diff --git a/Makefile b/Makefile index 4ff600fb96d216d24eee4d9ef64ecafb01dee3b2..0d225a07de62c1137d3039b7d099aec877fd0906 100755 --- a/Makefile +++ b/Makefile @@ -79,6 +79,8 @@ ifeq (${OSARCH},OpenBSD) CFLAGS+=-pthread endif +CFLAGS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi) + LIBEDIT=editline/libedit.a ASTERISKVERSION=$(shell if [ -f .version ]; then cat .version; fi) diff --git a/apps/app_voicemail2.c b/apps/app_voicemail2.c index 3d5fb6d6eb8f6c31d2aa6caa2c02de2d74ba0f36..f2bb8549e58a35aae0882fc3b882705b31d233ab 100755 --- a/apps/app_voicemail2.c +++ b/apps/app_voicemail2.c @@ -678,6 +678,8 @@ static int play_and_record(struct ast_channel *chan, char *playfile, char *recor for (x=0;x<fmtcnt;x++) { if (!others[x]) break; + ast_stream_rewind(others[x], 1000); + ast_truncstream(others[x]); ast_closestream(others[x]); } if (outmsg) { @@ -705,7 +707,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int FILE *txt; int res = 0; int msgnum; - int maxmessage=0; char date[256]; char dir[256]; char fn[256]; @@ -846,7 +847,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int fclose(txt); } else ast_log(LOG_WARNING, "Error opening text file for output\n"); - res = play_and_record(chan, NULL, fn, maxmessage, fmt); + res = play_and_record(chan, NULL, fn, vmmaxmessage, fmt); if (res > 0) res = 0; txt = fopen(txtfile, "a"); diff --git a/channel.c b/channel.c index 3640dd11cb93ba467f816131fcc0ce8114520b2a..0a9363a8fb899006f95b6779666db598759eabcc 100755 --- a/channel.c +++ b/channel.c @@ -34,6 +34,10 @@ #include <asterisk/linkedlists.h> #include <asterisk/indications.h> #include <asterisk/monitor.h> +#ifdef ZAPTEL_OPTIMIZATIONS +#include <sys/ioctl.h> +#include <linux/zaptel.h> +#endif static int shutting_down = 0; @@ -296,8 +300,15 @@ struct ast_channel *ast_channel_alloc(int needqueue) fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK); } else pvt->alertpipe[0] = pvt->alertpipe[1] = -1; +#ifdef ZAPTEL_OPTIMIZATIONS + tmp->timingfd = open("/dev/zap/timer", O_RDWR); +#else + tmp->timingfd = -1; +#endif /* Always watch the alertpipe */ tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0]; + /* And timing pipe */ + tmp->fds[AST_MAX_FDS-2] = tmp->timingfd; strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1); tmp->pvt = pvt; /* Initial state */ @@ -921,6 +932,17 @@ char ast_waitfordigit(struct ast_channel *c, int ms) return result; } +int ast_settimeout(struct ast_channel *c, int ms) +{ + int res = -1; +#ifdef ZAPTEL_OPTIMIZATIONS + if (c->timingfd > -1) { + ms *= 8; + res = ioctl(c->timingfd, ZT_TIMERCONFIG, &ms); + } +#endif + return res; +} char ast_waitfordigit_full(struct ast_channel *c, int ms, int audio, int ctrl) { struct ast_frame *f; @@ -994,7 +1016,18 @@ struct ast_frame *ast_read(struct ast_channel *chan) if (chan->pvt->alertpipe[0] > -1) { read(chan->pvt->alertpipe[0], &blah, sizeof(blah)); } - +#ifdef ZAPTEL_OPTIMIZATIONS + if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) { + chan->exception = 0; + blah = -1; + ioctl(chan->timingfd, ZT_TIMERACK, &blah); + blah = 0; + ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); + f = &null_frame; + pthread_mutex_unlock(&chan->lock); + return f; + } +#endif /* Check for pending read queue */ if (chan->pvt->readq) { f = chan->pvt->readq; diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index f77da478c09bf89f9857e5e30b8171c50084d4dc..c9d2dc3212202b92a6ac34d2d1e51efa981cc049 100755 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -3452,13 +3452,13 @@ static int timing_read(int *id, int fd, short events, void *cbdata) struct iax2_peer *peer; int processed = 0; int totalcalls = 0; - int x = -1; + int x = 1; if (iaxtrunkdebug) ast_verbose("Beginning trunk processing\n"); if (events & AST_IO_PRI) { #ifdef ZT_TIMERACK /* Great, this is a timing interface, just call the ioctl */ - if (ioctl(fd, ZT_TIMERACK, x)) + if (ioctl(fd, ZT_TIMERACK, &x)) ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); res = 0; #endif diff --git a/file.c b/file.c index 466b8aa5aaa26a883512d970ef26490c1975b82c..4ad7fa974a7d62a620dbe1c177a8b76dbeecbeef 100755 --- a/file.c +++ b/file.c @@ -615,12 +615,13 @@ char ast_waitstream(struct ast_channel *c, char *breakon) ast_closestream(c->stream); break; } + /* Setup timeout if supported */ + ast_settimeout(c, res); res = ast_waitfor(c, res); if (res < 0) { ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); return res; - } else - if (res > 0) { + } else if (res > 0) { fr = ast_read(c); if (!fr) { #if 0 @@ -652,8 +653,8 @@ char ast_waitstream(struct ast_channel *c, char *breakon) } /* Ignore */ ast_frfree(fr); - } else - ast_sched_runq(c->sched); + } + ast_sched_runq(c->sched); } @@ -670,6 +671,7 @@ char ast_waitstream_fr(struct ast_channel *c, char *breakon, char *forward, char ast_closestream(c->stream); break; } + ast_settimeout(c, res); res = ast_waitfor(c, res); if (res < 0) { ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); @@ -733,6 +735,7 @@ char ast_waitstream_full(struct ast_channel *c, char *breakon, int audiofd, int ast_closestream(c->stream); break; } + ast_settimeout(c, ms); rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); if (!rchan && (outfd < 0) && (ms)) { ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); @@ -776,8 +779,8 @@ char ast_waitstream_full(struct ast_channel *c, char *breakon, int audiofd, int } /* Ignore */ ast_frfree(fr); - } else - ast_sched_runq(c->sched); + } + ast_sched_runq(c->sched); } diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index c67dd58c4c1fc5db8e66a630535419f37a0bfbe1..97f8af91f00f312b94e4f49bf4fe5be960bca2f2 100755 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -112,6 +112,9 @@ struct ast_channel { struct ast_filestream *stream; /*! Original writer format */ int oldwriteformat; + + /*! Timing fd */ + int timingfd; /*! State of line -- Don't write directly, use ast_setstate */ @@ -669,6 +672,10 @@ int ast_autoservice_start(struct ast_channel *chan); /*! Stop servicing a channel for us... Returns -1 on error or if channel has been hungup */ int ast_autoservice_stop(struct ast_channel *chan); +/* If built with zaptel optimizations, force a scheduled expiration on the + timer fd */ +int ast_settimeout(struct ast_channel *c, int ms); + /* Misc. functions below */ //! Waits for activity on a group of channels