#include <sys/types.h>
#include <asterisk/frame.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/sched.h>
#include <asterisk/options.h>
#include <asterisk/translate.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include "asterisk.h"
#include "astconf.h"
Go to the source code of this file.
Data Structures | |
struct | ast_filestream |
struct | ast_format |
Defines | |
#define | ACTION_EXISTS 1 |
#define | ACTION_DELETE 2 |
#define | ACTION_RENAME 3 |
#define | ACTION_OPEN 4 |
#define | ACTION_COPY 5 |
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 sample_offset, int whence), int(*trunc)(struct ast_filestream *), long(*tell)(struct ast_filestream *), struct ast_frame *(*read)(struct ast_filestream *, int *whennext), void(*close)(struct ast_filestream *), char *(*getcomment)(struct ast_filestream *)) |
int | ast_format_unregister (char *name) |
Unregisters a file format. | |
int | ast_stopstream (struct ast_channel *tmp) |
Stops a stream. | |
int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f) |
Writes a frame to 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. | |
long | ast_tellstream (struct ast_filestream *fs) |
Tell where we are in a stream. | |
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. | |
int | ast_closestream (struct ast_filestream *f) |
Closes a stream. | |
int | ast_fileexists (char *filename, char *fmt, char *preflang) |
Checks for the existence of a given file. | |
int | ast_filedelete (char *filename, char *fmt) |
Deletes a file. | |
int | ast_filerename (char *filename, char *filename2, char *fmt) |
Renames a file. | |
int | ast_filecopy (char *filename, char *filename2, char *fmt) |
Copies a file. | |
int | ast_streamfile (struct ast_channel *chan, char *filename, char *preflang) |
Streams a file. | |
ast_filestream * | ast_writefile (char *filename, char *type, char *comment, int flags, int check, mode_t mode) |
Starts writing 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 cmdfd) |
|
Definition at line 294 of file file.c. Referenced by ast_filecopy(). |
|
Definition at line 291 of file file.c. Referenced by ast_filedelete(). |
|
Definition at line 290 of file file.c. Referenced by ast_fileexists(). |
|
Definition at line 293 of file file.c. Referenced by ast_openstream(), and ast_openvstream(). |
|
Definition at line 292 of file file.c. Referenced by ast_filerename(). |
|
Applys a open stream to a channel.
Definition at line 566 of file file.c. References ast_filestream::owner. Referenced by ast_streamfile().
00567 { 00568 s->owner = chan; 00569 return 0; 00570 } |
|
Closes a stream.
Definition at line 611 of file file.c. References AST_FORMAT_MAX_AUDIO, 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_channel::sched, ast_channel::stream, ast_channel::streamid, ast_filestream::trans, ast_channel::vstream, and ast_channel::vstreamid. Referenced by ast_app_getvoice(), and ast_stopstream().
00612 { 00613 /* Stop a running stream if there is one */ 00614 if (f->owner) { 00615 if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { 00616 f->owner->stream = NULL; 00617 if (f->owner->streamid > -1) 00618 ast_sched_del(f->owner->sched, f->owner->streamid); 00619 f->owner->streamid = -1; 00620 #ifdef ZAPTEL_OPTIMIZATIONS 00621 ast_settimeout(f->owner, 0, NULL, NULL); 00622 #endif 00623 } else { 00624 f->owner->vstream = NULL; 00625 if (f->owner->vstreamid > -1) 00626 ast_sched_del(f->owner->sched, f->owner->vstreamid); 00627 f->owner->vstreamid = -1; 00628 } 00629 } 00630 /* destroy the translator on exit */ 00631 if (f->trans) { 00632 ast_translator_free_path(f->trans); 00633 f->trans = NULL; 00634 } 00635 if (f->filename) 00636 free(f->filename); 00637 f->filename = NULL; 00638 f->fmt->close(f); 00639 return 0; 00640 } |
|
Copies a file.
Definition at line 693 of file file.c. References ACTION_COPY.
00694 {
00695 return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00696 }
|
|
Deletes a file.
Definition at line 683 of file file.c. References ACTION_DELETE.
00684 {
00685 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00686 }
|
|
Checks for the existence of a given file.
Definition at line 643 of file file.c. References ACTION_EXISTS, and MAX_LANGUAGE. Referenced by ast_openstream(), and ast_openvstream().
00644 { 00645 char filename2[256]; 00646 char tmp[256]; 00647 char *postfix; 00648 char *prefix; 00649 char *c; 00650 char lang2[MAX_LANGUAGE]; 00651 int res = -1; 00652 if (preflang && strlen(preflang)) { 00653 /* Insert the language between the last two parts of the path */ 00654 strncpy(tmp, filename, sizeof(tmp) - 1); 00655 c = strrchr(tmp, '/'); 00656 if (c) { 00657 *c = '\0'; 00658 postfix = c+1; 00659 prefix = tmp; 00660 } else { 00661 postfix = tmp; 00662 prefix=""; 00663 } 00664 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix); 00665 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00666 if (res < 1) { 00667 char *stringp=NULL; 00668 strncpy(lang2, preflang, sizeof(lang2)-1); 00669 stringp=lang2; 00670 strsep(&stringp, "_"); 00671 if (strcmp(lang2, preflang)) { 00672 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix); 00673 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00674 } 00675 } 00676 } 00677 if (res < 1) { 00678 res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS); 00679 } 00680 return res; 00681 } |
|
Renames a file.
Definition at line 688 of file file.c. References ACTION_RENAME.
00689 {
00690 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00691 }
|
|
Definition at line 85 of file file.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), LOG_WARNING, malloc, option_verbose, and VERBOSE_PREFIX_2.
00095 { 00096 struct ast_format *tmp; 00097 if (ast_mutex_lock(&formatlock)) { 00098 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00099 return -1; 00100 } 00101 tmp = formats; 00102 while(tmp) { 00103 if (!strcasecmp(name, tmp->name)) { 00104 ast_mutex_unlock(&formatlock); 00105 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", name); 00106 return -1; 00107 } 00108 tmp = tmp->next; 00109 } 00110 tmp = malloc(sizeof(struct ast_format)); 00111 if (!tmp) { 00112 ast_log(LOG_WARNING, "Out of memory\n"); 00113 ast_mutex_unlock(&formatlock); 00114 return -1; 00115 } 00116 strncpy(tmp->name, name, sizeof(tmp->name)-1); 00117 strncpy(tmp->exts, exts, sizeof(tmp->exts)-1); 00118 tmp->open = open; 00119 tmp->rewrite = rewrite; 00120 tmp->read = read; 00121 tmp->write = write; 00122 tmp->seek = seek; 00123 tmp->trunc = trunc; 00124 tmp->tell = tell; 00125 tmp->close = close; 00126 tmp->format = format; 00127 tmp->getcomment = getcomment; 00128 tmp->next = formats; 00129 formats = tmp; 00130 ast_mutex_unlock(&formatlock); 00131 if (option_verbose > 1) 00132 ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", name, exts); 00133 return 0; 00134 } |
|
Unregisters a file format.
Definition at line 136 of file file.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), free, LOG_WARNING, ast_format::next, option_verbose, and VERBOSE_PREFIX_2.
00137 { 00138 struct ast_format *tmp, *tmpl = NULL; 00139 if (ast_mutex_lock(&formatlock)) { 00140 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00141 return -1; 00142 } 00143 tmp = formats; 00144 while(tmp) { 00145 if (!strcasecmp(name, tmp->name)) { 00146 if (tmpl) 00147 tmpl->next = tmp->next; 00148 else 00149 formats = tmp->next; 00150 free(tmp); 00151 ast_mutex_unlock(&formatlock); 00152 if (option_verbose > 1) 00153 ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name); 00154 return 0; 00155 } 00156 tmp = tmp->next; 00157 } 00158 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00159 return -1; 00160 } |
|
Opens stream for use in seeking, playing.
Definition at line 406 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, MAX_LANGUAGE, ast_channel::oldwriteformat, and ast_channel::writeformat. Referenced by ast_streamfile().
00407 { 00408 /* This is a fairly complex routine. Essentially we should do 00409 the following: 00410 00411 1) Find which file handlers produce our type of format. 00412 2) Look for a filename which it can handle. 00413 3) If we find one, then great. 00414 4) If not, see what files are there 00415 5) See what we can actually support 00416 6) Choose the one with the least costly translator path and 00417 set it up. 00418 00419 */ 00420 int fd = -1; 00421 int fmts = -1; 00422 char filename2[256]; 00423 char lang2[MAX_LANGUAGE]; 00424 int res; 00425 ast_stopstream(chan); 00426 /* do this first, otherwise we detect the wrong writeformat */ 00427 if (chan->generator) 00428 ast_deactivate_generator(chan); 00429 if (preflang && strlen(preflang)) { 00430 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename); 00431 fmts = ast_fileexists(filename2, NULL, NULL); 00432 if (fmts < 1) { 00433 strncpy(lang2, preflang, sizeof(lang2)-1); 00434 snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename); 00435 fmts = ast_fileexists(filename2, NULL, NULL); 00436 } 00437 } 00438 if (fmts < 1) { 00439 strncpy(filename2, filename, sizeof(filename2)-1); 00440 fmts = ast_fileexists(filename2, NULL, NULL); 00441 } 00442 if (fmts < 1) { 00443 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00444 return NULL; 00445 } 00446 chan->oldwriteformat = chan->writeformat; 00447 /* Set the channel to a format we can work with */ 00448 res = ast_set_write_format(chan, fmts); 00449 00450 fd = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN); 00451 if(fd >= 0) 00452 return chan->stream; 00453 return NULL; 00454 } |
|
Opens stream for use in seeking, playing.
Definition at line 456 of file file.c. References ACTION_OPEN, ast_fileexists(), ast_log(), LOG_WARNING, and MAX_LANGUAGE. Referenced by ast_streamfile().
00457 { 00458 /* This is a fairly complex routine. Essentially we should do 00459 the following: 00460 00461 1) Find which file handlers produce our type of format. 00462 2) Look for a filename which it can handle. 00463 3) If we find one, then great. 00464 4) If not, see what files are there 00465 5) See what we can actually support 00466 6) Choose the one with the least costly translator path and 00467 set it up. 00468 00469 */ 00470 int fd = -1; 00471 int fmts = -1; 00472 char filename2[256]; 00473 char lang2[MAX_LANGUAGE]; 00474 /* XXX H.263 only XXX */ 00475 char *fmt = "h263"; 00476 if (preflang && strlen(preflang)) { 00477 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename); 00478 fmts = ast_fileexists(filename2, fmt, NULL); 00479 if (fmts < 1) { 00480 strncpy(lang2, preflang, sizeof(lang2)-1); 00481 snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename); 00482 fmts = ast_fileexists(filename2, fmt, NULL); 00483 } 00484 } 00485 if (fmts < 1) { 00486 strncpy(filename2, filename, sizeof(filename2)-1); 00487 fmts = ast_fileexists(filename2, fmt, NULL); 00488 } 00489 if (fmts < 1) { 00490 return NULL; 00491 } 00492 fd = ast_filehelper(filename2, (char *)chan, fmt, ACTION_OPEN); 00493 if(fd >= 0) 00494 return chan->vstream; 00495 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00496 return NULL; 00497 } |
|
play a open stream on a channel.
Definition at line 572 of file file.c. References AST_FORMAT_MAX_AUDIO, ast_filestream::fmt, and ast_format::format. Referenced by ast_streamfile().
00573 { 00574 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00575 ast_readaudio_callback(s); 00576 else 00577 ast_readvideo_callback(s); 00578 return 0; 00579 } |
|
Seeks into stream.
Definition at line 581 of file file.c. References ast_filestream::fmt, and ast_format::seek. Referenced by ast_read(), ast_stream_fastforward(), ast_stream_rewind(), and ast_write().
|
|
Stops a stream.
Definition at line 162 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_hangup(), ast_openstream(), ast_readstring(), ast_readstring_full(), ast_say_digit_str(), ast_say_digit_str_full(), ast_say_number(), ast_say_number_full(), ast_waitstream(), ast_waitstream_fr(), and ast_waitstream_full().
00163 { 00164 /* Stop a running stream if there is one */ 00165 if (tmp->vstream) 00166 ast_closestream(tmp->vstream); 00167 if (tmp->stream) { 00168 ast_closestream(tmp->stream); 00169 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00170 ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat); 00171 } 00172 return 0; 00173 } |
|
Fast forward stream ms.
Definition at line 596 of file file.c. References ast_seekstream(). Referenced by ast_waitstream_fr().
00597 { 00598 /* I think this is right, 8000 samples per second, 1000 ms a second so 8 00599 * samples per ms */ 00600 long samples = ms * 8; 00601 return ast_seekstream(fs, samples, SEEK_CUR); 00602 } |
|
Rewind stream ms.
Definition at line 604 of file file.c. References ast_seekstream(). Referenced by ast_waitstream_fr().
00605 { 00606 long samples = ms * 8; 00607 samples = samples * -1; 00608 return ast_seekstream(fs, samples, SEEK_CUR); 00609 } |
|
Streams a file.
Definition at line 698 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, and VERBOSE_PREFIX_3. Referenced by ast_app_getdata(), ast_app_getdata_full(), ast_app_getvoice(), ast_say_date(), ast_say_datetime(), ast_say_datetime_from_now(), ast_say_digit_str(), ast_say_digit_str_full(), ast_say_number(), ast_say_number_full(), and ast_say_time().
00699 { 00700 struct ast_filestream *fs; 00701 struct ast_filestream *vfs; 00702 00703 fs = ast_openstream(chan, filename, preflang); 00704 vfs = ast_openvstream(chan, filename, preflang); 00705 if (vfs) 00706 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00707 if(fs){ 00708 if(ast_applystream(chan, fs)) 00709 return -1; 00710 if(vfs && ast_applystream(chan, vfs)) 00711 return -1; 00712 if(ast_playstream(fs)) 00713 return -1; 00714 if(vfs && ast_playstream(vfs)) 00715 return -1; 00716 #if 1 00717 if (option_verbose > 2) 00718 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s'\n", filename); 00719 #endif 00720 return 0; 00721 } 00722 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno)); 00723 return -1; 00724 } |
|
Tell where we are in a stream.
Definition at line 591 of file file.c. References ast_filestream::fmt, and ast_format::tell.
|
|
Trunc stream at current location.
Definition at line 586 of file file.c. References ast_filestream::fmt, and ast_format::trunc.
|
|
Waits for a stream to stop or digit to be pressed.
Definition at line 779 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(), LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, and ast_channel::timingfunc. Referenced by ast_app_getvoice(), ast_readstring(), ast_say_date(), ast_say_datetime(), ast_say_datetime_from_now(), ast_say_digit_str(), ast_say_number(), and ast_say_time().
00780 { 00781 /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */ 00782 int res; 00783 struct ast_frame *fr; 00784 while(c->stream) { 00785 res = ast_sched_wait(c->sched); 00786 if ((res < 0) && !c->timingfunc) { 00787 ast_stopstream(c); 00788 break; 00789 } 00790 if (res < 0) 00791 res = 1000; 00792 res = ast_waitfor(c, res); 00793 if (res < 0) { 00794 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 00795 return res; 00796 } else if (res > 0) { 00797 fr = ast_read(c); 00798 if (!fr) { 00799 #if 0 00800 ast_log(LOG_DEBUG, "Got hung up\n"); 00801 #endif 00802 return -1; 00803 } 00804 00805 switch(fr->frametype) { 00806 case AST_FRAME_DTMF: 00807 res = fr->subclass; 00808 if (strchr(breakon, res)) { 00809 ast_frfree(fr); 00810 return res; 00811 } 00812 break; 00813 case AST_FRAME_CONTROL: 00814 switch(fr->subclass) { 00815 case AST_CONTROL_HANGUP: 00816 ast_frfree(fr); 00817 return -1; 00818 case AST_CONTROL_RINGING: 00819 case AST_CONTROL_ANSWER: 00820 /* Unimportant */ 00821 break; 00822 default: 00823 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 00824 } 00825 } 00826 /* Ignore */ 00827 ast_frfree(fr); 00828 } 00829 ast_sched_runq(c->sched); 00830 } 00831 return (c->_softhangup ? -1 : 0); 00832 } |
|
Same as waitstream but allows stream to be forwarded or rewound.
Definition at line 834 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(), LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, and ast_channel::timingfunc.
00835 { 00836 int res; 00837 struct ast_frame *fr; 00838 while(c->stream) { 00839 res = ast_sched_wait(c->sched); 00840 if ((res < 0) && !c->timingfunc) { 00841 ast_stopstream(c); 00842 break; 00843 } 00844 if (res < 0) 00845 res = 1000; 00846 res = ast_waitfor(c, res); 00847 if (res < 0) { 00848 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 00849 return res; 00850 } else 00851 if (res > 0) { 00852 fr = ast_read(c); 00853 if (!fr) { 00854 #if 0 00855 ast_log(LOG_DEBUG, "Got hung up\n"); 00856 #endif 00857 return -1; 00858 } 00859 00860 switch(fr->frametype) { 00861 case AST_FRAME_DTMF: 00862 res = fr->subclass; 00863 if (strchr(forward,res)) { 00864 ast_stream_fastforward(c->stream, ms); 00865 } else if (strchr(rewind,res)) { 00866 ast_stream_rewind(c->stream, ms); 00867 } else if (strchr(breakon, res)) { 00868 ast_frfree(fr); 00869 return res; 00870 } 00871 break; 00872 case AST_FRAME_CONTROL: 00873 switch(fr->subclass) { 00874 case AST_CONTROL_HANGUP: 00875 ast_frfree(fr); 00876 return -1; 00877 case AST_CONTROL_RINGING: 00878 case AST_CONTROL_ANSWER: 00879 /* Unimportant */ 00880 break; 00881 default: 00882 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 00883 } 00884 } 00885 /* Ignore */ 00886 ast_frfree(fr); 00887 } else 00888 ast_sched_runq(c->sched); 00889 00890 00891 } 00892 return (c->_softhangup ? -1 : 0); 00893 } |
|
Definition at line 895 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(), LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, and ast_channel::timingfunc. Referenced by ast_readstring_full(), ast_say_digit_str_full(), and ast_say_number_full().
00896 { 00897 int res; 00898 int ms; 00899 int outfd; 00900 struct ast_frame *fr; 00901 struct ast_channel *rchan; 00902 00903 while(c->stream) { 00904 ms = ast_sched_wait(c->sched); 00905 if ((ms < 0) && !c->timingfunc) { 00906 ast_stopstream(c); 00907 break; 00908 } 00909 if (ms < 0) 00910 ms = 1000; 00911 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 00912 if (!rchan && (outfd < 0) && (ms)) { 00913 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 00914 return -1; 00915 } else if (outfd > -1) { 00916 /* The FD we were watching has something waiting */ 00917 return 1; 00918 } else if (rchan) { 00919 fr = ast_read(c); 00920 if (!fr) { 00921 #if 0 00922 ast_log(LOG_DEBUG, "Got hung up\n"); 00923 #endif 00924 return -1; 00925 } 00926 00927 switch(fr->frametype) { 00928 case AST_FRAME_DTMF: 00929 res = fr->subclass; 00930 if (strchr(breakon, res)) { 00931 ast_frfree(fr); 00932 return res; 00933 } 00934 break; 00935 case AST_FRAME_CONTROL: 00936 switch(fr->subclass) { 00937 case AST_CONTROL_HANGUP: 00938 ast_frfree(fr); 00939 return -1; 00940 case AST_CONTROL_RINGING: 00941 case AST_CONTROL_ANSWER: 00942 /* Unimportant */ 00943 break; 00944 default: 00945 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 00946 } 00947 case AST_FRAME_VOICE: 00948 /* Write audio if appropriate */ 00949 if (audiofd > -1) 00950 write(audiofd, fr->data, fr->datalen); 00951 } 00952 /* Ignore */ 00953 ast_frfree(fr); 00954 } 00955 ast_sched_runq(c->sched); 00956 00957 00958 } 00959 return (c->_softhangup ? -1 : 0); 00960 } |
|
Starts writing a file.
Definition at line 727 of file file.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, free, LOG_WARNING, strdup, and type. Referenced by ast_app_getvoice(), and ast_writestream().
00728 { 00729 int fd,myflags; 00730 struct ast_format *f; 00731 struct ast_filestream *fs=NULL; 00732 char *fn; 00733 char *ext; 00734 if (ast_mutex_lock(&formatlock)) { 00735 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00736 return NULL; 00737 } 00738 myflags = 0; 00739 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 00740 if (!(flags & O_APPEND)) myflags = O_TRUNC; 00741 f = formats; 00742 while(f) { 00743 if (!strcasecmp(f->name, type)) { 00744 char *stringp=NULL; 00745 /* XXX Implement check XXX */ 00746 ext = strdup(f->exts); 00747 stringp=ext; 00748 ext = strsep(&stringp, "|"); 00749 fn = build_filename(filename, ext); 00750 fd = open(fn, flags | myflags | O_WRONLY | O_CREAT, mode); 00751 if (fd >= 0) { 00752 errno = 0; 00753 if ((fs = f->rewrite(fd, comment))) { 00754 fs->trans = NULL; 00755 fs->fmt = f; 00756 fs->flags = flags; 00757 fs->mode = mode; 00758 fs->filename = strdup(filename); 00759 fs->vfs = NULL; 00760 } else { 00761 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 00762 close(fd); 00763 unlink(fn); 00764 } 00765 } else if (errno != EEXIST) 00766 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 00767 free(fn); 00768 free(ext); 00769 break; 00770 } 00771 f = f->next; 00772 } 00773 ast_mutex_unlock(&formatlock); 00774 if (!f) 00775 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00776 return fs; 00777 } |
|
Writes a frame to a stream.
Definition at line 175 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_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_read(), and ast_write().
00176 { 00177 struct ast_frame *trf; 00178 int res = -1; 00179 int alt=0; 00180 if (f->frametype == AST_FRAME_VIDEO) { 00181 if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) { 00182 /* This is the audio portion. Call the video one... */ 00183 if (!fs->vfs && fs->filename) { 00184 /* XXX Support other video formats XXX */ 00185 char *type = "h263"; 00186 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00187 ast_log(LOG_DEBUG, "Opened video output file\n"); 00188 } 00189 if (fs->vfs) 00190 return ast_writestream(fs->vfs, f); 00191 /* Ignore */ 00192 return 0; 00193 } else { 00194 /* Might / might not have mark set */ 00195 alt = 1; 00196 } 00197 } else if (f->frametype != AST_FRAME_VOICE) { 00198 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00199 return -1; 00200 } 00201 if (((fs->fmt->format | alt) & f->subclass) == f->subclass) { 00202 res = fs->fmt->write(fs, f); 00203 if (res < 0) 00204 ast_log(LOG_WARNING, "Natural write failed\n"); 00205 if (res > 0) 00206 ast_log(LOG_WARNING, "Huh??\n"); 00207 return res; 00208 } else { 00209 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00210 the one we've setup a translator for, we do the "wrong thing" XXX */ 00211 if (fs->trans && (f->subclass != fs->lastwriteformat)) { 00212 ast_translator_free_path(fs->trans); 00213 fs->trans = NULL; 00214 } 00215 if (!fs->trans) 00216 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass); 00217 if (!fs->trans) 00218 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", fs->fmt->name, ast_getformatname(f->subclass)); 00219 else { 00220 fs->lastwriteformat = f->subclass; 00221 res = 0; 00222 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00223 trf = ast_translate(fs->trans, f, 0); 00224 if (trf) { 00225 res = fs->fmt->write(fs, trf); 00226 if (res) 00227 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00228 } else 00229 res = 0; 00230 } 00231 return res; 00232 } 00233 } |