#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_format |
struct | ast_filestream |
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. | |
ast_frame * | ast_readframe (struct ast_filestream *s) |
Read a frame from a filestream. | |
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_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. | |
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 310 of file file.c. Referenced by ast_filecopy(). |
|
Definition at line 307 of file file.c. Referenced by ast_filedelete(). |
|
Definition at line 306 of file file.c. Referenced by ast_fileexists(). |
|
Definition at line 309 of file file.c. Referenced by ast_openstream(), and ast_openvstream(). |
|
Definition at line 308 of file file.c. Referenced by ast_filerename(). |
|
Applys a open stream to a channel.
Definition at line 594 of file file.c. References s. Referenced by ast_streamfile().
00595 { 00596 s->owner = chan; 00597 return 0; 00598 } |
|
Closes a stream.
Definition at line 639 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().
00640 { 00641 /* Stop a running stream if there is one */ 00642 if (f->owner) { 00643 if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { 00644 f->owner->stream = NULL; 00645 if (f->owner->streamid > -1) 00646 ast_sched_del(f->owner->sched, f->owner->streamid); 00647 f->owner->streamid = -1; 00648 #ifdef ZAPTEL_OPTIMIZATIONS 00649 ast_settimeout(f->owner, 0, NULL, NULL); 00650 #endif 00651 } else { 00652 f->owner->vstream = NULL; 00653 if (f->owner->vstreamid > -1) 00654 ast_sched_del(f->owner->sched, f->owner->vstreamid); 00655 f->owner->vstreamid = -1; 00656 } 00657 } 00658 /* destroy the translator on exit */ 00659 if (f->trans) { 00660 ast_translator_free_path(f->trans); 00661 f->trans = NULL; 00662 } 00663 if (f->filename) 00664 free(f->filename); 00665 f->filename = NULL; 00666 f->fmt->close(f); 00667 return 0; 00668 } |
|
Copies a file.
Definition at line 721 of file file.c. References ACTION_COPY.
00722 {
00723 return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00724 }
|
|
Deletes a file.
Definition at line 711 of file file.c. References ACTION_DELETE.
00712 {
00713 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00714 }
|
|
Checks for the existence of a given file.
Definition at line 671 of file file.c. References ACTION_EXISTS, and MAX_LANGUAGE. Referenced by ast_openstream(), and ast_openvstream().
00672 { 00673 char filename2[256]; 00674 char tmp[256]; 00675 char *postfix; 00676 char *prefix; 00677 char *c; 00678 char lang2[MAX_LANGUAGE]; 00679 int res = -1; 00680 if (preflang && strlen(preflang)) { 00681 /* Insert the language between the last two parts of the path */ 00682 strncpy(tmp, filename, sizeof(tmp) - 1); 00683 c = strrchr(tmp, '/'); 00684 if (c) { 00685 *c = '\0'; 00686 postfix = c+1; 00687 prefix = tmp; 00688 } else { 00689 postfix = tmp; 00690 prefix=""; 00691 } 00692 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix); 00693 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00694 if (res < 1) { 00695 char *stringp=NULL; 00696 strncpy(lang2, preflang, sizeof(lang2)-1); 00697 stringp=lang2; 00698 strsep(&stringp, "_"); 00699 if (strcmp(lang2, preflang)) { 00700 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix); 00701 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00702 } 00703 } 00704 } 00705 if (res < 1) { 00706 res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS); 00707 } 00708 return res; 00709 } |
|
Renames a file.
Definition at line 716 of file file.c. References ACTION_RENAME.
00717 {
00718 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00719 }
|
|
Definition at line 85 of file file.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), LOG_WARNING, malloc, ast_frame::next, 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 422 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().
00423 { 00424 /* This is a fairly complex routine. Essentially we should do 00425 the following: 00426 00427 1) Find which file handlers produce our type of format. 00428 2) Look for a filename which it can handle. 00429 3) If we find one, then great. 00430 4) If not, see what files are there 00431 5) See what we can actually support 00432 6) Choose the one with the least costly translator path and 00433 set it up. 00434 00435 */ 00436 int fd = -1; 00437 int fmts = -1; 00438 char filename2[256]=""; 00439 char filename3[256]=""; 00440 char *endpart; 00441 int res; 00442 ast_stopstream(chan); 00443 /* do this first, otherwise we detect the wrong writeformat */ 00444 if (chan->generator) 00445 ast_deactivate_generator(chan); 00446 if (preflang && strlen(preflang)) { 00447 strncpy(filename3, filename, sizeof(filename3) - 1); 00448 endpart = strrchr(filename3, '/'); 00449 if (endpart) { 00450 *endpart = '\0'; 00451 endpart++; 00452 snprintf(filename2, sizeof(filename2), "%s/%s/%s", filename3, preflang, endpart); 00453 } else 00454 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename); 00455 fmts = ast_fileexists(filename2, NULL, NULL); 00456 } 00457 if (fmts < 1) { 00458 strncpy(filename2, filename, sizeof(filename2)-1); 00459 fmts = ast_fileexists(filename2, NULL, NULL); 00460 } 00461 if (fmts < 1) { 00462 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00463 return NULL; 00464 } 00465 chan->oldwriteformat = chan->writeformat; 00466 /* Set the channel to a format we can work with */ 00467 res = ast_set_write_format(chan, fmts); 00468 00469 fd = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN); 00470 if(fd >= 0) 00471 return chan->stream; 00472 return NULL; 00473 } |
|
Opens stream for use in seeking, playing.
Definition at line 475 of file file.c. References ACTION_OPEN, ast_fileexists(), ast_log(), LOG_WARNING, and MAX_LANGUAGE. Referenced by ast_streamfile().
00476 { 00477 /* This is a fairly complex routine. Essentially we should do 00478 the following: 00479 00480 1) Find which file handlers produce our type of format. 00481 2) Look for a filename which it can handle. 00482 3) If we find one, then great. 00483 4) If not, see what files are there 00484 5) See what we can actually support 00485 6) Choose the one with the least costly translator path and 00486 set it up. 00487 00488 */ 00489 int fd = -1; 00490 int fmts = -1; 00491 char filename2[256]; 00492 char lang2[MAX_LANGUAGE]; 00493 /* XXX H.263 only XXX */ 00494 char *fmt = "h263"; 00495 if (preflang && strlen(preflang)) { 00496 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename); 00497 fmts = ast_fileexists(filename2, fmt, NULL); 00498 if (fmts < 1) { 00499 strncpy(lang2, preflang, sizeof(lang2)-1); 00500 snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename); 00501 fmts = ast_fileexists(filename2, fmt, NULL); 00502 } 00503 } 00504 if (fmts < 1) { 00505 strncpy(filename2, filename, sizeof(filename2)-1); 00506 fmts = ast_fileexists(filename2, fmt, NULL); 00507 } 00508 if (fmts < 1) { 00509 return NULL; 00510 } 00511 fd = ast_filehelper(filename2, (char *)chan, fmt, ACTION_OPEN); 00512 if(fd >= 0) 00513 return chan->vstream; 00514 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00515 return NULL; 00516 } |
|
play a open stream on a channel.
Definition at line 600 of file file.c. References AST_FORMAT_MAX_AUDIO, and s. Referenced by ast_streamfile().
00601 { 00602 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00603 ast_readaudio_callback(s); 00604 else 00605 ast_readvideo_callback(s); 00606 return 0; 00607 } |
|
Starts reading from a file.
Definition at line 754 of file file.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, free, LOG_WARNING, and strdup.
00755 { 00756 int fd,myflags = 0; 00757 struct ast_format *f; 00758 struct ast_filestream *fs=NULL; 00759 char *fn; 00760 char *ext; 00761 if (ast_mutex_lock(&formatlock)) { 00762 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00763 return NULL; 00764 } 00765 f = formats; 00766 while(f) { 00767 if (exts_compare(f->exts, type)) { 00768 char *stringp=NULL; 00769 /* XXX Implement check XXX */ 00770 ext = strdup(f->exts); 00771 stringp=ext; 00772 ext = strsep(&stringp, "|"); 00773 fn = build_filename(filename, ext); 00774 fd = open(fn, flags | myflags); 00775 if (fd >= 0) { 00776 errno = 0; 00777 if ((fs = f->open(fd))) { 00778 fs->trans = NULL; 00779 fs->fmt = f; 00780 fs->flags = flags; 00781 fs->mode = mode; 00782 fs->filename = strdup(filename); 00783 fs->vfs = NULL; 00784 } else { 00785 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 00786 close(fd); 00787 unlink(fn); 00788 } 00789 } else if (errno != EEXIST) 00790 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 00791 free(fn); 00792 free(ext); 00793 break; 00794 } 00795 f = f->next; 00796 } 00797 ast_mutex_unlock(&formatlock); 00798 if (!f) 00799 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00800 return fs; 00801 } |
|
Read a frame from a filestream.
Definition at line 518 of file file.c. References s.
|
|
Seeks into stream.
Definition at line 609 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 624 of file file.c. References ast_seekstream(). Referenced by ast_waitstream_fr().
00625 { 00626 /* I think this is right, 8000 samples per second, 1000 ms a second so 8 00627 * samples per ms */ 00628 long samples = ms * 8; 00629 return ast_seekstream(fs, samples, SEEK_CUR); 00630 } |
|
Rewind stream ms.
Definition at line 632 of file file.c. References ast_seekstream(). Referenced by ast_waitstream_fr().
00633 { 00634 long samples = ms * 8; 00635 samples = samples * -1; 00636 return ast_seekstream(fs, samples, SEEK_CUR); 00637 } |
|
Streams a file.
Definition at line 726 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().
00727 { 00728 struct ast_filestream *fs; 00729 struct ast_filestream *vfs; 00730 00731 fs = ast_openstream(chan, filename, preflang); 00732 vfs = ast_openvstream(chan, filename, preflang); 00733 if (vfs) 00734 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00735 if(fs){ 00736 if(ast_applystream(chan, fs)) 00737 return -1; 00738 if(vfs && ast_applystream(chan, vfs)) 00739 return -1; 00740 if(ast_playstream(fs)) 00741 return -1; 00742 if(vfs && ast_playstream(vfs)) 00743 return -1; 00744 #if 1 00745 if (option_verbose > 2) 00746 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (language '%s')\n", filename, preflang ? preflang : "default"); 00747 #endif 00748 return 0; 00749 } 00750 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno)); 00751 return -1; 00752 } |
|
Tell where we are in a stream.
Definition at line 619 of file file.c. References ast_filestream::fmt, and ast_format::tell.
|
|
Trunc stream at current location.
Definition at line 614 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 858 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().
00859 { 00860 /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */ 00861 int res; 00862 struct ast_frame *fr; 00863 while(c->stream) { 00864 res = ast_sched_wait(c->sched); 00865 if ((res < 0) && !c->timingfunc) { 00866 ast_stopstream(c); 00867 break; 00868 } 00869 if (res < 0) 00870 res = 1000; 00871 res = ast_waitfor(c, res); 00872 if (res < 0) { 00873 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 00874 return res; 00875 } else if (res > 0) { 00876 fr = ast_read(c); 00877 if (!fr) { 00878 #if 0 00879 ast_log(LOG_DEBUG, "Got hung up\n"); 00880 #endif 00881 return -1; 00882 } 00883 00884 switch(fr->frametype) { 00885 case AST_FRAME_DTMF: 00886 res = fr->subclass; 00887 if (strchr(breakon, res)) { 00888 ast_frfree(fr); 00889 return res; 00890 } 00891 break; 00892 case AST_FRAME_CONTROL: 00893 switch(fr->subclass) { 00894 case AST_CONTROL_HANGUP: 00895 ast_frfree(fr); 00896 return -1; 00897 case AST_CONTROL_RINGING: 00898 case AST_CONTROL_ANSWER: 00899 /* Unimportant */ 00900 break; 00901 default: 00902 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 00903 } 00904 } 00905 /* Ignore */ 00906 ast_frfree(fr); 00907 } 00908 ast_sched_runq(c->sched); 00909 } 00910 return (c->_softhangup ? -1 : 0); 00911 } |
|
Same as waitstream but allows stream to be forwarded or rewound.
Definition at line 913 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.
00914 { 00915 int res; 00916 struct ast_frame *fr; 00917 while(c->stream) { 00918 res = ast_sched_wait(c->sched); 00919 if ((res < 0) && !c->timingfunc) { 00920 ast_stopstream(c); 00921 break; 00922 } 00923 if (res < 0) 00924 res = 1000; 00925 res = ast_waitfor(c, res); 00926 if (res < 0) { 00927 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 00928 return res; 00929 } else 00930 if (res > 0) { 00931 fr = ast_read(c); 00932 if (!fr) { 00933 #if 0 00934 ast_log(LOG_DEBUG, "Got hung up\n"); 00935 #endif 00936 return -1; 00937 } 00938 00939 switch(fr->frametype) { 00940 case AST_FRAME_DTMF: 00941 res = fr->subclass; 00942 if (strchr(forward,res)) { 00943 ast_stream_fastforward(c->stream, ms); 00944 } else if (strchr(rewind,res)) { 00945 ast_stream_rewind(c->stream, ms); 00946 } else if (strchr(breakon, res)) { 00947 ast_frfree(fr); 00948 return res; 00949 } 00950 break; 00951 case AST_FRAME_CONTROL: 00952 switch(fr->subclass) { 00953 case AST_CONTROL_HANGUP: 00954 ast_frfree(fr); 00955 return -1; 00956 case AST_CONTROL_RINGING: 00957 case AST_CONTROL_ANSWER: 00958 /* Unimportant */ 00959 break; 00960 default: 00961 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 00962 } 00963 } 00964 /* Ignore */ 00965 ast_frfree(fr); 00966 } else 00967 ast_sched_runq(c->sched); 00968 00969 00970 } 00971 return (c->_softhangup ? -1 : 0); 00972 } |
|
Definition at line 974 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().
00975 { 00976 int res; 00977 int ms; 00978 int outfd; 00979 struct ast_frame *fr; 00980 struct ast_channel *rchan; 00981 00982 while(c->stream) { 00983 ms = ast_sched_wait(c->sched); 00984 if ((ms < 0) && !c->timingfunc) { 00985 ast_stopstream(c); 00986 break; 00987 } 00988 if (ms < 0) 00989 ms = 1000; 00990 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 00991 if (!rchan && (outfd < 0) && (ms)) { 00992 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 00993 return -1; 00994 } else if (outfd > -1) { 00995 /* The FD we were watching has something waiting */ 00996 return 1; 00997 } else if (rchan) { 00998 fr = ast_read(c); 00999 if (!fr) { 01000 #if 0 01001 ast_log(LOG_DEBUG, "Got hung up\n"); 01002 #endif 01003 return -1; 01004 } 01005 01006 switch(fr->frametype) { 01007 case AST_FRAME_DTMF: 01008 res = fr->subclass; 01009 if (strchr(breakon, res)) { 01010 ast_frfree(fr); 01011 return res; 01012 } 01013 break; 01014 case AST_FRAME_CONTROL: 01015 switch(fr->subclass) { 01016 case AST_CONTROL_HANGUP: 01017 ast_frfree(fr); 01018 return -1; 01019 case AST_CONTROL_RINGING: 01020 case AST_CONTROL_ANSWER: 01021 /* Unimportant */ 01022 break; 01023 default: 01024 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01025 } 01026 case AST_FRAME_VOICE: 01027 /* Write audio if appropriate */ 01028 if (audiofd > -1) 01029 write(audiofd, fr->data, fr->datalen); 01030 } 01031 /* Ignore */ 01032 ast_frfree(fr); 01033 } 01034 ast_sched_runq(c->sched); 01035 01036 01037 } 01038 return (c->_softhangup ? -1 : 0); 01039 } |
|
Starts writing a file.
Definition at line 803 of file file.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, free, LOG_WARNING, and strdup. Referenced by ast_app_getvoice(), and ast_writestream().
00804 { 00805 int fd,myflags = 0; 00806 struct ast_format *f; 00807 struct ast_filestream *fs=NULL; 00808 char *fn; 00809 char *ext; 00810 if (ast_mutex_lock(&formatlock)) { 00811 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00812 return NULL; 00813 } 00814 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 00815 if (!(flags & O_APPEND)) 00816 myflags = O_TRUNC; 00817 00818 myflags |= O_WRONLY | O_CREAT; 00819 00820 f = formats; 00821 while(f) { 00822 if (exts_compare(f->exts, type)) { 00823 char *stringp=NULL; 00824 /* XXX Implement check XXX */ 00825 ext = strdup(f->exts); 00826 stringp=ext; 00827 ext = strsep(&stringp, "|"); 00828 fn = build_filename(filename, ext); 00829 fd = open(fn, flags | myflags, mode); 00830 if (fd >= 0) { 00831 errno = 0; 00832 if ((fs = f->rewrite(fd, comment))) { 00833 fs->trans = NULL; 00834 fs->fmt = f; 00835 fs->flags = flags; 00836 fs->mode = mode; 00837 fs->filename = strdup(filename); 00838 fs->vfs = NULL; 00839 } else { 00840 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 00841 close(fd); 00842 unlink(fn); 00843 } 00844 } else if (errno != EEXIST) 00845 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 00846 free(fn); 00847 free(ext); 00848 break; 00849 } 00850 f = f->next; 00851 } 00852 ast_mutex_unlock(&formatlock); 00853 if (!f) 00854 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00855 return fs; 00856 } |
|
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, 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 } |