dect
/
asterisk
Archived
13
0
Fork 0

Version 0.1.12 from FTP

git-svn-id: http://svn.digium.com/svn/asterisk/trunk@465 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
markster 2002-06-21 01:40:13 +00:00
parent 74d376fd37
commit 87909fa28e
14 changed files with 2703 additions and 273 deletions

View File

@ -11,7 +11,6 @@
# the GNU General Public License
#
.EXPORT_ALL_VARIABLES:
INSTALL_PREFIX=
@ -22,14 +21,20 @@ AGI_DIR=$(INSTALL_PREFIX)/var/lib/asterisk/agi-bin
# Pentium Pro Optimize
#PROC=i686
# Pentium Optimize
PROC=i586
#PROC=i586
#PROC=k6
#PROC=ppc
PROC=$(shell uname -m)
DEBUG=-g #-pg
INCLUDE=-Iinclude -I../include
CFLAGS=-pipe -Wall -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT
CFLAGS=-pipe -Wall -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT -D_GNU_SOURCE
#CFLAGS+=-Werror
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
ASTERISKVERSION=$(shell if [ -f .version ]; then cat .version; fi)
HTTPDIR=$(shell if [ -d /var/www ]; then echo "/var/www"; else echo "/home/httpd"; fi)
RPMVERSION=$(shell sed 's/[-\/:]/_/g' .version)
CFLAGS+=-DASTERISK_VERSION=\"$(ASTERISKVERSION)\"
# Optional debugging parameters
@ -38,11 +43,11 @@ CFLAGS+= -DDO_CRASH -DDEBUG_THREADS
#CLFAGS+= -DTRACE_FRAMES
CFLAGS+=# -fomit-frame-pointer
SUBDIRS=res channels pbx apps codecs formats agi cdr
LIBS=-ldl -lpthread -lreadline -lncurses -lm
LIBS=-ldl -lpthread -lreadline -lncurses -lm #-lnjamd
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \
translate.o file.o say.o pbx.o cli.o md5.o \
translate.o file.o say.o pbx.o cli.o md5.o term.o \
ulaw.o alaw.o callerid.o fskmodem.o image.o app.o \
cdr.o tdd.o asterisk.o
cdr.o tdd.o acl.o rtp.o asterisk.o
CC=gcc
INSTALL=install
@ -81,9 +86,10 @@ datafiles: all
for x in sounds/digits/*; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/sounds/digits ; \
done
for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-*; do \
for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-*; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/sounds ; \
done
mkdir -p $(INSTALL_PREFIX)/var/lib/asterisk/mohmp3
mkdir -p $(INSTALL_PREFIX)/var/lib/asterisk/images
for x in images/*.jpg; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/images ; \
@ -93,8 +99,10 @@ datafiles: all
install: all datafiles
mkdir -p $(MODULES_DIR)
mkdir -p $(INSTALL_PREFIX)/usr/sbin
mkdir -p $(INSTALL_PREFIX)/etc/asterisk
install -m 755 asterisk $(INSTALL_PREFIX)/usr/sbin/
install -m 755 astgenkey $(INSTALL_PREFIX)/usr/sbin/
install -m 755 safe_asterisk $(INSTALL_PREFIX)/usr/sbin/
for x in $(SUBDIRS); do $(MAKE) -C $$x install || exit 1 ; done
install -d $(INSTALL_PREFIX)/usr/include/asterisk
install include/asterisk/*.h $(INSTALL_PREFIX)/usr/include/asterisk
@ -128,7 +136,15 @@ install: all datafiles
@echo " + **Note** This requires that you have +"
@echo " + doxygen installed on your local system +"
@echo " +-------------------------------------------+"
samples: all datafiles
adsi: all
mkdir -p /etc/asterisk
for x in configs/*.adsi; do \
if ! [ -f $(INSTALL_PREFIX)/etc/asterisk/$$x ]; then \
install -m 644 $$x $(INSTALL_PREFIX)/etc/asterisk/`basename $$x` ; \
fi ; \
done
samples: all datafiles adsi
mkdir -p $(INSTALL_PREFIX)/etc/asterisk
for x in configs/*.sample; do \
if [ -f $(INSTALL_PREFIX)/etc/asterisk/`basename $$x .sample` ]; then \
@ -139,6 +155,9 @@ samples: all datafiles
for x in sounds/demo-*; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/sounds; \
done
for x in sounds/*.mp3; do \
install $$x $(INSTALL_PREFIX)/var/lib/asterisk/mohmp3 ; \
done
mkdir -p $(INSTALL_PREFIX)/var/spool/asterisk/vm/1234/INBOX
:> $(INSTALL_PREFIX)/var/lib/asterisk/sounds/vm/1234/unavail.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
@ -149,6 +168,24 @@ samples: all datafiles
cat $(INSTALL_PREFIX)/var/lib/asterisk/sounds/$$x.gsm >> $(INSTALL_PREFIX)/var/lib/asterisk/sounds/vm/1234/busy.gsm ; \
done
webvmail:
@[ -d $(HTTPDIR) ] || ( echo "No HTTP directory" && exit 1 )
@[ -d $(HTTPDIR)/html ] || ( echo "No http directory" && exit 1 )
@[ -d $(HTTPDIR)/cgi-bin ] || ( echo "No cgi-bin directory" && exit 1 )
install -m 4755 -o root -g root vmail.cgi $(HTTPDIR)/cgi-bin/vmail.cgi
mkdir -p $(HTTPDIR)/html/_asterisk
for x in images/*.gif; do \
install -m 644 $$x $(HTTPDIR)/html/_asterisk/; \
done
@echo " +--------- Asterisk Web Voicemail ----------+"
@echo " + +"
@echo " + Asterisk Web Voicemail is installed in +"
@echo " + your cgi-bin directory. IT USES A SETUID +"
@echo " + ROOT PERL SCRIPT, SO IF YOU DON'T LIKE +"
@echo " + THAT, UNINSTALL IT! +"
@echo " + +"
@echo " +-------------------------------------------+"
mailbox:
./addmailbox
@ -171,3 +208,13 @@ __rpm: _version
progdocs:
doxygen asterisk-ng-doxygen
config:
if [ -d /etc/rc.d/init.d ]; then \
install -m 755 init.asterisk /etc/rc.d/init.d/asterisk; \
/sbin/chkconfig --add asterisk; \
elif [ -d /etc/init.d ]; then \
install -m 755 init.asterisk /etc/init.d/asterisk; \
fi

1567
apps/app_adsiprog.c Executable file

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
@ -53,10 +54,10 @@ static int skel_exec(struct ast_channel *chan, void *data)
/* Do our thing here */
res = system((char *)data);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
res = -1;
} else if (res == 127) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
res = -1;
} else {
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))

449
channel.c
View File

@ -18,7 +18,9 @@
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <asterisk/lock.h>
#include <unistd.h>
#include <math.h> /* For PI */
#include <asterisk/frame.h>
#include <asterisk/sched.h>
#include <asterisk/options.h>
@ -28,6 +30,7 @@
#include <asterisk/file.h>
#include <asterisk/translate.h>
static int shutting_down = 0;
/* XXX Lock appropriately in more functions XXX */
@ -62,7 +65,7 @@ struct ast_channel *channels = NULL;
/* Protect the channel list (highly unlikely that two things would change
it at the same time, but still! */
static pthread_mutex_t chlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t chlock = AST_MUTEX_INITIALIZER;
int ast_check_hangup(struct ast_channel *chan)
{
@ -79,6 +82,45 @@ time_t myt;
return 1;
}
void ast_begin_shutdown(int hangup)
{
struct ast_channel *c;
shutting_down = 1;
if (hangup) {
PTHREAD_MUTEX_LOCK(&chlock);
c = channels;
while(c) {
c->softhangup = 1;
c = c->next;
}
PTHREAD_MUTEX_UNLOCK(&chlock);
}
}
int ast_active_channels(void)
{
struct ast_channel *c;
int cnt = 0;
PTHREAD_MUTEX_LOCK(&chlock);
c = channels;
while(c) {
cnt++;
c = c->next;
}
PTHREAD_MUTEX_UNLOCK(&chlock);
return cnt;
}
void ast_cancel_shutdown(void)
{
shutting_down = 0;
}
int ast_shutting_down(void)
{
return shutting_down;
}
void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
{
time_t myt;
@ -189,11 +231,15 @@ int ast_best_codec(int fmts)
return 0;
}
struct ast_channel *ast_channel_alloc(void)
struct ast_channel *ast_channel_alloc(int needqueue)
{
struct ast_channel *tmp;
struct ast_channel_pvt *pvt;
int x;
int flags;
/* If shutting down, don't allocate any new channels */
if (shutting_down)
return NULL;
PTHREAD_MUTEX_LOCK(&chlock);
tmp = malloc(sizeof(struct ast_channel));
memset(tmp, 0, sizeof(struct ast_channel));
@ -203,24 +249,43 @@ struct ast_channel *ast_channel_alloc(void)
memset(pvt, 0, sizeof(struct ast_channel_pvt));
tmp->sched = sched_context_create();
if (tmp->sched) {
for (x=0;x<AST_MAX_FDS;x++)
for (x=0;x<AST_MAX_FDS - 1;x++)
tmp->fds[x] = -1;
strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
tmp->pvt = pvt;
tmp->state = AST_STATE_DOWN;
tmp->stack = -1;
tmp->streamid = -1;
tmp->appl = NULL;
tmp->data = NULL;
pthread_mutex_init(&tmp->lock, NULL);
strncpy(tmp->context, "default", sizeof(tmp->context)-1);
strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
tmp->priority=1;
tmp->amaflags = ast_default_amaflags;
strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
tmp->next = channels;
channels= tmp;
if (needqueue &&
pipe(pvt->alertpipe)) {
ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
free(pvt);
free(tmp);
tmp = NULL;
pvt = NULL;
} else {
/* Make sure we've got it done right if they don't */
if (needqueue) {
flags = fcntl(pvt->alertpipe[0], F_GETFL);
fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
flags = fcntl(pvt->alertpipe[1], F_GETFL);
fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
} else
pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
/* Always watch the alertpipe */
tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
tmp->pvt = pvt;
tmp->state = AST_STATE_DOWN;
tmp->stack = -1;
tmp->streamid = -1;
tmp->appl = NULL;
tmp->data = NULL;
ast_pthread_mutex_init(&tmp->lock);
strncpy(tmp->context, "default", sizeof(tmp->context)-1);
strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
tmp->priority=1;
tmp->amaflags = ast_default_amaflags;
strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
tmp->next = channels;
channels= tmp;
}
} else {
ast_log(LOG_WARNING, "Unable to create schedule context\n");
free(tmp);
@ -237,6 +302,56 @@ struct ast_channel *ast_channel_alloc(void)
return tmp;
}
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int lock)
{
struct ast_frame *f;
struct ast_frame *prev, *cur;
int blah = 1;
int qlen = 0;
f = ast_frdup(fin);
if (!f) {
ast_log(LOG_WARNING, "Unable to duplicate frame\n");
return -1;
}
if (lock)
ast_pthread_mutex_lock(&chan->lock);
prev = NULL;
cur = chan->pvt->readq;
while(cur) {
prev = cur;
cur = cur->next;
qlen++;
}
if (prev)
prev->next = f;
else
chan->pvt->readq = f;
if (chan->pvt->alertpipe[1] > -1) {
if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
ast_log(LOG_WARNING, "Unable to write to alert pipe, frametype/subclass %d/%d (qlen = %d): %s!\n",
f->frametype, f->subclass, qlen, strerror(errno));
}
if (qlen > 128) {
ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
}
if (lock)
ast_pthread_mutex_unlock(&chan->lock);
return 0;
}
int ast_queue_hangup(struct ast_channel *chan, int lock)
{
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
return ast_queue_frame(chan, &f, lock);
}
int ast_queue_control(struct ast_channel *chan, int control, int lock)
{
struct ast_frame f = { AST_FRAME_CONTROL, };
f.subclass = control;
return ast_queue_frame(chan, &f, lock);
}
int ast_channel_defer_dtmf(struct ast_channel *chan)
{
int pre = 0;
@ -272,9 +387,28 @@ struct ast_channel *ast_channel_walk(struct ast_channel *prev)
}
int ast_safe_sleep(struct ast_channel *chan, int ms)
{
struct ast_frame *f;
while(ms > 0) {
ms = ast_waitfor(chan, ms);
if (ms <0)
return -1;
if (ms > 0) {
f = ast_read(chan);
if (!f)
return -1;
ast_frfree(f);
}
}
return 0;
}
void ast_channel_free(struct ast_channel *chan)
{
struct ast_channel *last=NULL, *cur;
int fd;
struct ast_frame *f, *fp;
PTHREAD_MUTEX_LOCK(&chlock);
cur = channels;
while(cur) {
@ -306,6 +440,17 @@ void ast_channel_free(struct ast_channel *chan)
if (chan->ani)
free(chan->ani);
pthread_mutex_destroy(&chan->lock);
/* Close pipes if appropriate */
if ((fd = chan->pvt->alertpipe[0]) > -1)
close(fd);
if ((fd = chan->pvt->alertpipe[1]) > -1)
close(fd);
f = chan->pvt->readq;
while(f) {
fp = f;
f = f->next;
ast_frfree(fp);
}
free(chan->pvt);
free(chan);
PTHREAD_MUTEX_UNLOCK(&chlock);
@ -359,6 +504,11 @@ int ast_hangup(struct ast_channel *chan)
ast_stopstream(chan);
if (chan->sched)
sched_context_destroy(chan->sched);
/* Clear any tone stuff remaining */
if (chan->generatordata)
chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
chan->generator = NULL;
if (chan->cdr) {
/* End the CDR if it hasn't already */
ast_cdr_end(chan->cdr);
@ -434,6 +584,29 @@ int ast_answer(struct ast_channel *chan)
return 0;
}
void ast_deactivate_generator(struct ast_channel *chan)
{
if (chan->generatordata) {
chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
chan->writeinterrupt = 0;
}
}
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
{
if (chan->generatordata) {
chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
}
if ((chan->generatordata = gen->alloc(chan, params))) {
chan->generator = gen;
} else {
return -1;
}
return 0;
}
int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
{
/* Wait for x amount of time on a file descriptor to have input. */
@ -511,9 +684,10 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
tv.tv_usec = (*ms % 1000) * 1000;
FD_ZERO(&rfds);
FD_ZERO(&efds);
for (x=0;x<n;x++) {
for (y=0;y<AST_MAX_FDS;y++) {
if (c[x]->fds[y] > 0) {
if (c[x]->fds[y] > -1) {
FD_SET(c[x]->fds[y], &rfds);
FD_SET(c[x]->fds[y], &efds);
if (c[x]->fds[y] > max)
@ -623,12 +797,13 @@ char ast_waitfordigit(struct ast_channel *c, int ms)
struct ast_frame *ast_read(struct ast_channel *chan)
{
struct ast_frame *f = NULL;
int blah;
static struct ast_frame null_frame =
{
AST_FRAME_NULL,
};
pthread_mutex_lock(&chan->lock);
ast_pthread_mutex_lock(&chan->lock);
if (chan->masq) {
if (ast_do_masquerade(chan)) {
ast_log(LOG_WARNING, "Failed to perform masquerade\n");
@ -644,7 +819,7 @@ struct ast_frame *ast_read(struct ast_channel *chan)
pthread_mutex_unlock(&chan->lock);
return NULL;
}
if (!chan->deferdtmf && strlen(chan->dtmfq)) {
/* We have DTMF that has been deferred. Return it now */
chan->dtmff.frametype = AST_FRAME_DTMF;
@ -655,19 +830,35 @@ struct ast_frame *ast_read(struct ast_channel *chan)
return &chan->dtmff;
}
chan->blocker = pthread_self();
if (chan->exception) {
if (chan->pvt->exception)
f = chan->pvt->exception(chan);
/* Read and ignore anything on the alertpipe, but read only
one sizeof(blah) per frame that we send from it */
if (chan->pvt->alertpipe[0] > -1) {
read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
}
/* Check for pending read queue */
if (chan->pvt->readq) {
f = chan->pvt->readq;
chan->pvt->readq = f->next;
/* Interpret hangup and return NULL */
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))
f = NULL;
} else {
chan->blocker = pthread_self();
if (chan->exception) {
if (chan->pvt->exception)
f = chan->pvt->exception(chan);
else
ast_log(LOG_WARNING, "Exception flag set, but no exception handler\n");
/* Clear the exception flag */
chan->exception = 0;
} else
if (chan->pvt->read)
f = chan->pvt->read(chan);
else
ast_log(LOG_WARNING, "Exception flag set, but no exception handler\n");
/* Clear the exception flag */
chan->exception = 0;
} else
if (chan->pvt->read)
f = chan->pvt->read(chan);
else
ast_log(LOG_WARNING, "No read routine on channel %s\n", chan);
ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
}
if (f && (f->frametype == AST_FRAME_VOICE)) {
if (chan->pvt->readtrans) {
f = ast_translate(chan->pvt->readtrans, f, 1);
@ -675,6 +866,7 @@ struct ast_frame *ast_read(struct ast_channel *chan)
f = &null_frame;
}
}
/* Make sure we always return NULL in the future */
if (!f) {
chan->softhangup = 1;
@ -689,10 +881,26 @@ struct ast_frame *ast_read(struct ast_channel *chan)
f = &null_frame;
} else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
/* Answer the CDR */
chan->state = AST_STATE_UP;
ast_cdr_answer(chan->cdr);
}
pthread_mutex_unlock(&chan->lock);
/* Run any generator sitting on the line */
if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
/* Mask generator data temporarily */
void *tmp;
int res;
tmp = chan->generatordata;
chan->generatordata = NULL;
res = chan->generator->generate(chan, tmp, f->datalen);
chan->generatordata = tmp;
if (res) {
ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
ast_deactivate_generator(chan);
}
}
return f;
}
@ -769,6 +977,12 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
}
if (chan->masqr)
return 0;
if (chan->generatordata) {
if (chan->writeinterrupt)
ast_deactivate_generator(chan);
else
return 0;
}
CHECK_BLOCKING(chan);
switch(fr->frametype) {
case AST_FRAME_CONTROL:
@ -796,6 +1010,9 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
}
}
chan->blocking = 0;
/* Consider a write failure to force a soft hangup */
if (res < 0)
chan->softhangup = 1;
return res;
}
@ -899,7 +1116,7 @@ int ast_call(struct ast_channel *chan, char *addr, int timeout)
return anyway. */
int res = -1;
/* Stop if we're a zombie or need a soft hangup */
pthread_mutex_lock(&chan->lock);
ast_pthread_mutex_lock(&chan->lock);
if (!chan->zombie && !ast_check_hangup(chan))
if (chan->pvt->call)
res = chan->pvt->call(chan, addr, timeout);
@ -975,19 +1192,19 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe
chanf = chan->nativeformats;
res = ast_translator_best_choice(&peerf, &chanf);
if (res < 0) {
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan, chan->nativeformats, peer, peer->nativeformats);
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
return -1;
}
/* Set read format on channel */
res = ast_set_read_format(chan, peerf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan, chanf);
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
return -1;
}
/* Set write format on peer channel */
res = ast_set_write_format(peer, peerf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer, peerf);
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
return -1;
}
/* Now we go the other way */
@ -995,19 +1212,19 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe
chanf = chan->nativeformats;
res = ast_translator_best_choice(&chanf, &peerf);
if (res < 0) {
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer, peer->nativeformats, chan, chan->nativeformats);
ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
return -1;
}
/* Set writeformat on channel */
res = ast_set_write_format(chan, chanf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan, chanf);
ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
return -1;
}
/* Set read format on peer channel */
res = ast_set_read_format(peer, chanf);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer, peerf);
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
return -1;
}
return 0;
@ -1057,7 +1274,7 @@ static int ast_do_masquerade(struct ast_channel *original)
free_translation(original);
/* We need the clone's lock, too */
pthread_mutex_lock(&clone->lock);
ast_pthread_mutex_lock(&clone->lock);
/* Unlink the masquerade */
original->masq = NULL;
@ -1224,7 +1441,8 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
}
if ((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) {
if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) &&
!(c0->generator || c1->generator)) {
if (ast_channel_make_compatible(c0, c1)) {
ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
return -1;
@ -1282,10 +1500,14 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
last = who;
#endif
tackygoto:
if (who == c0)
ast_write(c1, f);
else
ast_write(c0, f);
/* Don't copy packets if there is a generator on either one, since they're
not supposed to be listening anyway */
if (!c0->generator && !c1->generator) {
if (who == c0)
ast_write(c1, f);
else
ast_write(c0, f);
}
}
ast_frfree(f);
} else
@ -1320,3 +1542,136 @@ int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int
return 0;
}
struct tonepair_def {
int freq1;
int freq2;
int duration;
int vol;
};
struct tonepair_state {
float freq1;
float freq2;
float vol;
int duration;
int pos;
int origrfmt;
int origwfmt;
struct ast_frame f;
unsigned char offset[AST_FRIENDLY_OFFSET];
short data[4000];
};
static void tonepair_release(struct ast_channel *chan, void *params)
{
struct tonepair_state *ts = params;
if (chan) {
ast_set_write_format(chan, ts->origwfmt);
ast_set_read_format(chan, ts->origrfmt);
}
free(ts);
}
static void * tonepair_alloc(struct ast_channel *chan, void *params)
{
struct tonepair_state *ts;
struct tonepair_def *td = params;
ts = malloc(sizeof(struct tonepair_state));
if (!ts)
return NULL;
memset(ts, 0, sizeof(struct tonepair_state));
ts->origrfmt = chan->readformat;
ts->origwfmt = chan->writeformat;
if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
tonepair_release(NULL, ts);
ts = NULL;
} else if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (read)\n", chan->name);
ast_set_write_format(chan, ts->origwfmt);
tonepair_release(NULL, ts);
ts = NULL;
} else {
ts->freq1 = td->freq1;
ts->freq2 = td->freq2;
ts->duration = td->duration;
ts->vol = td->vol;
}
/* Let interrupts interrupt :) */
chan->writeinterrupt = 1;
return ts;
}
static int tonepair_generator(struct ast_channel *chan, void *data, int len)
{
struct tonepair_state *ts = data;
int x;
if (len > sizeof(ts->data) / 2 - 1) {
ast_log(LOG_WARNING, "Can't generate that much data!\n");
return -1;
}
memset(&ts->f, 0, sizeof(ts->f));
for (x=0;x<len/2;x++) {
ts->data[x] = ts->vol * (
sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
);
}
ts->f.frametype = AST_FRAME_VOICE;
ts->f.subclass = AST_FORMAT_SLINEAR;
ts->f.datalen = len;
ts->f.timelen = len/8;
ts->f.offset = AST_FRIENDLY_OFFSET;
ts->f.data = ts->data;
ast_write(chan, &ts->f);
ts->pos += x;
if (ts->duration > 0) {
if (ts->pos >= ts->duration * 8)
return -1;
}
return 0;
}
static struct ast_generator tonepair = {
alloc: tonepair_alloc,
release: tonepair_release,
generate: tonepair_generator,
};
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
{
struct tonepair_def d = { 0, };
d.freq1 = freq1;
d.freq2 = freq2;
d.duration = duration;
if (vol < 1)
d.vol = 8192;
else
d.vol = vol;
if (ast_activate_generator(chan, &tonepair, &d))
return -1;
return 0;
}
void ast_tonepair_stop(struct ast_channel *chan)
{
ast_deactivate_generator(chan);
}
int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
{
struct ast_frame *f;
int res;
if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
return res;
/* Give us some wiggle room */
while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
f = ast_read(chan);
if (f)
ast_frfree(f);
else
return -1;
}
return 0;
}

View File

@ -80,7 +80,7 @@ struct vofr_hdr {
u_int8_t cid; /* Channel ID */
u_int8_t mod:4; /* Modulation */
u_int8_t remid:4; /* Remote ID */
#elif __BYTE__ORDER == __BIG_ENDIAN
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t ctag:4; /* Connect tag */
u_int8_t dtype:4; /* Data type */
u_int8_t vflags:4; /* Voice Routing Flags */

View File

@ -14,6 +14,7 @@
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <asterisk/lock.h>
#include <asterisk/channel.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/config.h>
@ -55,14 +56,14 @@ static int silencesupression = 0;
static int prefformat = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
/* Protect the interface list (of phone_pvt's) */
static pthread_mutex_t iflock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t iflock = AST_MUTEX_INITIALIZER;
/* Protect the monitoring thread, so only one process can kill or start it, and not
when it's doing something critical. */
static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t monlock = AST_MUTEX_INITIALIZER;
/* This is the thread for the monitor which checks for input on the channels
which are not currently in use. */
@ -140,7 +141,31 @@ static int phone_digit(struct ast_channel *ast, char digit)
static int phone_call(struct ast_channel *ast, char *dest, int timeout)
{
struct phone_pvt *p;
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_RINGING };
// CID stuff for the phonejack...
PHONE_CID cid;
time_t UtcTime;
struct tm *t;
if (ast->callerid) {
time(&UtcTime);
t = localtime(&UtcTime);
if(t != NULL) {
sprintf(cid.month, "%02d",(t->tm_mon + 1));
sprintf(cid.day, "%02d", t->tm_mday);
sprintf(cid.hour, "%02d", t->tm_hour);
sprintf(cid.min, "%02d", t->tm_min);
}
strcpy(cid.name, "Unknown");
sprintf(cid.number,"%s",ast->callerid);
}
p = ast->pvt->pvt;
if ((ast->state != AST_STATE_DOWN) && (ast->state != AST_STATE_RESERVED)) {
ast_log(LOG_WARNING, "phone_call called on %s, neither down nor reserved\n", ast->name);
return -1;
@ -149,7 +174,9 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
ring the phone and wait for someone to answer */
if (option_debug)
ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fds[0]);
ioctl(p->fd, PHONE_RING_START);
ioctl(p->fd, PHONE_RING_START,&cid);
ast_queue_frame(ast, &f, 0);
ast->state = AST_STATE_RINGING;
return 0;
}
@ -336,7 +363,7 @@ static struct ast_frame *phone_exception(struct ast_channel *ast)
if (phonee.bits.pstn_ring)
ast_verbose("Unit is ringing\n");
if (phonee.bits.caller_id) {
ast_verbose("We have caller ID: %s\n");
ast_verbose("We have caller ID\n");
}
if (phonee.bits.pstn_wink)
ast_verbose("Detected Wink\n");
@ -351,6 +378,7 @@ static struct ast_frame *phone_read(struct ast_channel *ast)
{
int res;
struct phone_pvt *p = ast->pvt->pvt;
/* Some nice norms */
p->fr.datalen = 0;
@ -448,14 +476,13 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
char tmpbuf[4];
/* Write a frame of (presumably voice) data */
if (frame->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
ast_frfree(frame);
return -1;
if (frame->frametype != AST_FRAME_IMAGE)
ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
return 0;
}
if (!(frame->subclass &
(AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW))) {
ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
ast_frfree(frame);
return -1;
}
/* If we're not in up mode, go into up mode now */
@ -560,17 +587,20 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
res = phone_write_buf(p, pos, expected, maxfr);
}
if (res != expected) {
if (res < 0)
ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
/*
* Card is in non-blocking mode now and it works well now, but there are
* lot of messages like this. So, this message is temporarily disabled.
*/
if (errno != EAGAIN) {
if (res < 0)
ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
/*
* Card is in non-blocking mode now and it works well now, but there are
* lot of messages like this. So, this message is temporarily disabled.
*/
#if 0
else
ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
else
ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
#endif
return -1;
return -1;
} else /* Pretend it worked */
res = expected;
}
sofar += res;
pos += res;
@ -581,7 +611,7 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *context)
{
struct ast_channel *tmp;
tmp = ast_channel_alloc();
tmp = ast_channel_alloc(1);
if (tmp) {
snprintf(tmp->name, sizeof(tmp->name), "Phone/%s", i->dev + 5);
tmp->type = type;

View File

@ -25,6 +25,8 @@ CFLAGS+=
LIBG723=g723.1/libg723.a
LIBG723B=g723.1b/libg723b.a
LIBGSM=gsm/lib/libgsm.a
LIBGSM=$(shell if uname -m | grep -q 86; then echo gsm/lib/libgsm.a; else echo "-lgsm" ; fi)
LIBGSMT=$(shell if uname -m | grep -q 86; then echo gsm/lib/libgsm.a; fi)
LIBMP3=mp3/libmp3.a
LIBLPC10=lpc10/liblpc10.a
@ -44,7 +46,7 @@ clean:
$(LIBG723):
make -C g723.1 all
$(LIBGSM):
gsm/lib/libgsm.a:
make -C gsm lib/libgsm.a
$(LIBG723B):
@ -65,7 +67,7 @@ codec_g723_1b.o : codec_g723_1.c
codec_g723_1b.so : codec_g723_1b.o $(LIBG723B)
$(CC) -shared -Xlinker -x -o $@ $< $(LIBG723B) -lm
codec_gsm.so: codec_gsm.o $(LIBGSM)
codec_gsm.so: codec_gsm.o $(LIBGSMT)
$(CC) -shared -Xlinker -x -o $@ $< $(LIBGSM)
codec_lpc10.so: codec_lpc10.o $(LIBLPC10)

View File

@ -22,7 +22,8 @@ LIB_TARGET_DIR = .
#
WARNINGS = -Wall -Wno-comment -Wno-error
CFLAGS = -O6 -mpentium -I$(LIB_TARGET_DIR) $(WARNINGS)
CFLAGS = -O6 -I$(LIB_TARGET_DIR) $(WARNINGS)
CFLAGS+= $(shell if uname -m | grep -q 86; then echo "-mpentium" ; fi)
LIB = $(LIB_TARGET_DIR)/liblpc10.a

View File

@ -80,7 +80,7 @@ static int jpeg_write_image(int fd, struct ast_frame *fr)
if (fr->datalen) {
res = write(fd, fr->data, fr->datalen);
if (res != fr->datalen) {
ast_log(LOG_WARNING, "Only wrote %d of %d bytes: %s\n", res, fr->datalen);
ast_log(LOG_WARNING, "Only wrote %d of %d bytes: %s\n", res, fr->datalen, strerror(errno));
return -1;
}
}

View File

@ -11,6 +11,7 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/channel.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
@ -51,7 +52,7 @@ struct ast_filestream {
static struct ast_filestream *glist = NULL;
static pthread_mutex_t wav_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t wav_lock = AST_MUTEX_INITIALIZER;
static int glistcnt = 0;
static char *name = "wav";
@ -167,7 +168,7 @@ static int check_header(int fd)
return -1;
}
if (read(fd, &bisam, 2) != 2) {
ast_log(LOG_WARNING, "Read failed (Bits Per Sample): &d\n", ltohs(bisam));
ast_log(LOG_WARNING, "Read failed (Bits Per Sample): %d\n", ltohs(bisam));
return -1;
}
/* Begin data chunk */

View File

@ -37,7 +37,8 @@ extern "C" {
* ast_log(LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?", "flux capacitor", 10);
* where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending on which log you wish to output to.
*/
extern void ast_log(int level, char *file, int line, char *function, char *fmt, ...);
extern void ast_log(int level, char *file, int line, char *function, char *fmt, ...)
__attribute__ ((format (printf, 5, 6)));
//! Send a verbose message (based on verbose level)
/*!
@ -47,7 +48,8 @@ extern void ast_log(int level, char *file, int line, char *function, char *fmt,
* Note the abscence of a comma after the VERBOSE_PREFIX_3. This is important.
* VERBOSE_PREFIX_1 through VERBOSE_PREFIX_3 are defined.
*/
extern void ast_verbose(char *fmt, ...);
extern void ast_verbose(char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
extern int ast_register_verbose(void (*verboser)(char *string, int opos, int replacelast, int complete));
extern int ast_unregister_verbose(void (*verboser)(char *string, int opos, int replacelast, int complete));

View File

@ -15,10 +15,12 @@
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <asterisk/lock.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/config.h>
#include <asterisk/term.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
@ -30,8 +32,8 @@
#define MAX_MSG_QUEUE 200
static pthread_mutex_t msglist_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t loglock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t msglist_lock = AST_MUTEX_INITIALIZER;
static pthread_mutex_t loglock = AST_MUTEX_INITIALIZER;
static struct msglist {
char *msg;
@ -59,6 +61,14 @@ static char *levels[] = {
"ERROR"
};
static int colors[] = {
COLOR_BRGREEN,
COLOR_BRBLUE,
COLOR_YELLOW,
COLOR_BRRED,
COLOR_RED
};
static int make_components(char *s, int lineno)
{
char *w;
@ -207,14 +217,21 @@ int reload_logger(void)
extern void ast_log(int level, char *file, int line, char *function, char *fmt, ...)
{
char date[256];
char tmp[80];
char tmp2[80];
char tmp3[80];
char tmp4[80];
char linestr[80];
time_t t;
struct tm *tm;
struct logfile *f;
va_list ap;
va_start(ap, fmt);
if (!option_verbose && !option_debug && (!level))
if (!option_verbose && !option_debug && (!level)) {
va_end(ap);
return;
}
ast_pthread_mutex_lock(&loglock);
if (level == 1 /* Event */) {
time(&t);
@ -226,7 +243,9 @@ extern void ast_log(int level, char *file, int line, char *function, char *fmt,
vfprintf(eventlog, fmt, ap);
fflush(eventlog);
} else
ast_log(LOG_WARNING, "Unable to retrieve local time?\n");
/** Cannot use ast_log() from locked section of ast_log()!
ast_log(LOG_WARNING, "Unable to retrieve local time?\n"); **/
fprintf(stderr, "ast_log: Unable to retrieve local time for %d?\n", t);
} else {
if (logfiles) {
f = logfiles;
@ -238,16 +257,26 @@ extern void ast_log(int level, char *file, int line, char *function, char *fmt,
strftime(date, sizeof(date), "%b %e %T", tm);
fprintf(f->f, "%s %s[%ld]: File %s, Line %d (%s): ", date, levels[level], pthread_self(), file, line, function);
} else {
fprintf(f->f, "%s[%ld]: File %s, Line %d (%s): ", levels[level], pthread_self(), file, line, function);
sprintf(linestr, "%d", line);
fprintf(f->f, "%s[%ld]: File %s, Line %s (%s): ",
term_color(tmp, levels[level], colors[level], 0, sizeof(tmp)),
pthread_self(),
term_color(tmp2, file, COLOR_BRWHITE, 0, sizeof(tmp2)),
term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)),
term_color(tmp4, function, COLOR_BRWHITE, 0, sizeof(tmp4)));
}
vfprintf(f->f, fmt, ap);
va_start(ap, fmt);
fflush(f->f);
va_end(ap);
}
f = f->next;
}
} else {
fprintf(stdout, "%s[%ld]: File %s, Line %d (%s): ", levels[level], pthread_self(), file, line, function);
va_start(ap, fmt);
vfprintf(stdout, fmt, ap);
va_end(ap);
fflush(stdout);
}
}

417
pbx.c
View File

@ -11,7 +11,7 @@
* the GNU General Public License
*/
#include <pthread.h>
#include <asterisk/lock.h>
#include <asterisk/cli.h>
#include <asterisk/pbx.h>
#include <asterisk/channel.h>
@ -20,6 +20,7 @@
#include <asterisk/file.h>
#include <asterisk/callerid.h>
#include <asterisk/cdr.h>
#include <asterisk/term.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
@ -71,7 +72,13 @@ struct ast_exten {
struct ast_include {
char name[AST_MAX_EXTENSION];
char rname[AST_MAX_EXTENSION];
char *registrar;
int hastime;
unsigned int monthmask;
unsigned int daymask;
unsigned int dowmask;
unsigned int minmask[24];
struct ast_include *next;
};
@ -244,14 +251,14 @@ static struct pbx_builtin {
};
/* Lock for the application list */
static pthread_mutex_t applock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t applock = AST_MUTEX_INITIALIZER;
static struct ast_context *contexts = NULL;
/* Lock for the ast_context list */
static pthread_mutex_t conlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t conlock = AST_MUTEX_INITIALIZER;
static struct ast_app *apps = NULL;
/* Lock for switches */
static pthread_mutex_t switchlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t switchlock = AST_MUTEX_INITIALIZER;
struct ast_switch *switches = NULL;
int pbx_exec(struct ast_channel *c, /* Channel */
@ -342,6 +349,47 @@ static struct ast_switch *pbx_findswitch(char *sw)
return asw;
}
static inline int include_valid(struct ast_include *i)
{
struct tm *tm;
time_t t;
if (!i->hastime)
return 1;
time(&t);
tm = localtime(&t);
if (!tm) {
ast_log(LOG_WARNING, "Failed to get local time\n");
return 0;
}
/* If it's not the right month, return */
if (!(i->monthmask & (1 << tm->tm_mon))) {
return 0;
}
/* If it's not that time of the month.... */
if (!(i->daymask & (1 << tm->tm_mday)))
return 0;
/* If it's not the right day of the week */
if (!(i->dowmask & (1 << tm->tm_wday)))
return 0;
/* Sanity check the hour just to be safe */
if ((tm->tm_hour < 0) || (tm->tm_hour > 23)) {
ast_log(LOG_WARNING, "Insane time...\n");
return 0;
}
/* Now the tough part, we calculate if it fits
in the right time based on min/hour */
if (!(i->minmask[tm->tm_hour] & (1 << (tm->tm_min / 2))))
return 0;
/* If we got this far, then we're good */
return 1;
}
static void pbx_destroy(struct ast_pbx *p)
{
free(p);
@ -561,10 +609,12 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan, char *cont
/* Now try any includes we have in this context */
i = tmp->includes;
while(i) {
if ((e = pbx_find_extension(chan, i->name, exten, priority, callerid, action, incstack, stacklen, status, swo, data)))
return e;
if (*swo)
return NULL;
if (include_valid(i)) {
if ((e = pbx_find_extension(chan, i->rname, exten, priority, callerid, action, incstack, stacklen, status, swo, data)))
return e;
if (*swo)
return NULL;
}
i = i->next;
}
}
@ -584,6 +634,9 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
int status = 0;
char *incstack[AST_PBX_MAX_STACK];
int stacklen = 0;
char tmp[80];
char tmp2[80];
char tmp3[256];
if (ast_pthread_mutex_lock(&conlock)) {
ast_log(LOG_WARNING, "Unable to obtain lock\n");
if ((action == HELPER_EXISTS) || (action == HELPER_CANMATCH))
@ -614,7 +667,10 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
ast_log(LOG_DEBUG, "Launching '%s'\n", app->name);
else if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Executing %s(\"%s\", \"%s\") %s\n",
app->name, c->name, (e->data ? (char *)e->data : NULL), (newstack ? "in new stack" : "in same stack"));
term_color(tmp, app->name, COLOR_BRCYAN, 0, sizeof(tmp)),
term_color(tmp2, c->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
term_color(tmp3, (e->data ? (char *)e->data : NULL), COLOR_BRMAGENTA, 0, sizeof(tmp3)),
(newstack ? "in new stack" : "in same stack"));
res = pbx_exec(c, app, e->data, newstack);
return res;
} else {
@ -675,41 +731,6 @@ static int pbx_extension_helper(struct ast_channel *c, char *context, char *exte
}
#if 0
int ast_pbx_longest_extension(char *context)
{
/* XXX Not include-aware XXX */
struct ast_context *tmp;
struct ast_exten *e;
int len = 0;
if (ast_pthread_mutex_lock(&conlock)) {
ast_log(LOG_WARNING, "Unable to obtain lock\n");
return -1;
}
tmp = contexts;
while(tmp) {
if (!strcasecmp(tmp->name, context)) {
/* By locking tmp, not only can the state of its entries not
change, but it cannot be destroyed either. */
ast_pthread_mutex_lock(&tmp->lock);
/* But we can relieve the conlock, as tmp will not change */
ast_pthread_mutex_unlock(&conlock);
e = tmp->root;
while(e) {
if (strlen(e->exten) > len)
len = strlen(e->exten);
e = e->next;
}
ast_pthread_mutex_unlock(&tmp->lock);
return len;
}
tmp = tmp->next;
}
ast_log(LOG_WARNING, "No such context '%s'\n", context);
return -1;
}
#endif
int ast_exists_extension(struct ast_channel *c, char *context, char *exten, int priority, char *callerid)
{
return pbx_extension_helper(c, context, exten, priority, callerid, HELPER_EXISTS);
@ -736,7 +757,7 @@ int ast_pbx_run(struct ast_channel *c)
/* A little initial setup here */
if (c->pbx)
ast_log(LOG_WARNING, "%s already has PBX structure??\n");
ast_log(LOG_WARNING, "%s already has PBX structure??\n", c->name);
c->pbx = malloc(sizeof(struct ast_pbx));
if (!c->pbx) {
ast_log(LOG_WARNING, "Out of memory\n");
@ -744,7 +765,7 @@ int ast_pbx_run(struct ast_channel *c)
}
if (c->amaflags) {
if (c->cdr) {
ast_log(LOG_WARNING, "%s already has a call record??\n");
ast_log(LOG_WARNING, "%s already has a call record??\n", c->name);
} else {
c->cdr = ast_cdr_alloc();
if (!c->cdr) {
@ -890,6 +911,22 @@ int ast_pbx_run(struct ast_channel *c)
if (firstpass)
ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
out:
if (ast_exists_extension(c, c->context, "h", 1, c->callerid)) {
strcpy(c->exten, "h");
c->priority = 1;
while(ast_exists_extension(c, c->context, c->exten, c->priority, c->callerid)) {
if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->callerid))) {
/* Something bad happened, or a hangup has been requested. */
if (option_debug)
ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
else if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
break;
}
c->priority++;
}
}
pbx_destroy(c->pbx);
c->pbx = NULL;
if (res != AST_PBX_KEEPALIVE)
@ -973,7 +1010,7 @@ int ast_context_remove_include2(struct ast_context *con, char *include, char *re
{
struct ast_include *i, *pi = NULL;
if (pthread_mutex_lock(&con->lock)) return -1;
if (ast_pthread_mutex_lock(&con->lock)) return -1;
/* walk includes */
i = con->includes;
@ -1045,7 +1082,7 @@ int ast_context_remove_switch2(struct ast_context *con, char *sw, char *data, ch
{
struct ast_sw *i, *pi = NULL;
if (pthread_mutex_lock(&con->lock)) return -1;
if (ast_pthread_mutex_lock(&con->lock)) return -1;
/* walk switchs */
i = con->alts;
@ -1215,6 +1252,7 @@ int ast_context_remove_extension2(struct ast_context *con, char *extension, int
int ast_register_application(char *app, int (*execute)(struct ast_channel *, void *), char *synopsis, char *description)
{
struct ast_app *tmp;
char tmps[80];
if (ast_pthread_mutex_lock(&applock)) {
ast_log(LOG_ERROR, "Unable to lock application list\n");
return -1;
@ -1230,6 +1268,7 @@ int ast_register_application(char *app, int (*execute)(struct ast_channel *, voi
}
tmp = malloc(sizeof(struct ast_app));
if (tmp) {
memset(tmp, 0, sizeof(struct ast_app));
strncpy(tmp->name, app, sizeof(tmp->name)-1);
tmp->execute = execute;
tmp->synopsis = synopsis;
@ -1242,7 +1281,7 @@ int ast_register_application(char *app, int (*execute)(struct ast_channel *, voi
return -1;
}
if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", tmp->name);
ast_verbose( VERBOSE_PREFIX_2 "Registered application '%s'\n", term_color(tmps, tmp->name, COLOR_BRCYAN, 0, sizeof(tmps)));
ast_pthread_mutex_unlock(&applock);
return 0;
}
@ -1769,7 +1808,7 @@ struct ast_context *ast_context_create(char *name, char *registrar)
tmp = malloc(sizeof(struct ast_context));
if (tmp) {
memset(tmp, 0, sizeof(struct ast_context));
pthread_mutex_init(&tmp->lock, NULL);
ast_pthread_mutex_init(&tmp->lock);
strncpy(tmp->name, name, sizeof(tmp->name)-1);
tmp->root = NULL;
tmp->registrar = registrar;
@ -1821,6 +1860,255 @@ int ast_context_add_include(char *context, char *include, char *registrar)
return -1;
}
#define FIND_NEXT \
do { \
c = info; \
while(*c && (*c != '|')) c++; \
if (*c) *c = '\0'; else c = NULL; \
} while(0)
static void get_timerange(struct ast_include *i, char *times)
{
char *e;
int x;
int s1, s2;
int e1, e2;
/* Star is all times */
if (!strlen(times) || !strcmp(times, "*")) {
for (x=0;x<24;x++)
i->minmask[x] = (1 << 30) - 1;
return;
}
/* Otherwise expect a range */
e = strchr(times, '-');
if (!e) {
ast_log(LOG_WARNING, "Time range is not valid. Assuming no time.\n");
return;
}
*e = '\0';
e++;
while(*e && !isdigit(*e)) e++;
if (!*e) {
ast_log(LOG_WARNING, "Invalid time range. Assuming no time.\n");
return;
}
if (sscanf(times, "%d:%d", &s1, &s2) != 2) {
ast_log(LOG_WARNING, "%s isn't a time. Assuming no time.\n", times);
return;
}
if (sscanf(e, "%d:%d", &e1, &e2) != 2) {
ast_log(LOG_WARNING, "%s isn't a time. Assuming no time.\n", e);
return;
}
s1 = s1 * 30 + s2/2;
if ((s1 < 0) || (s1 >= 24*30)) {
ast_log(LOG_WARNING, "%s isn't a valid star time. Assuming no time.\n", times);
return;
}
e1 = e1 * 30 + e2/2;
if ((e1 < 0) || (e2 >= 24*30)) {
ast_log(LOG_WARNING, "%s isn't a valid start time. Assuming no time.\n", times);
return;
}
/* Go through the time and enable each appropriate bit */
for (x=s1;x != e1;x = (x + 1) % (24 * 30)) {
i->minmask[x/30] |= (1 << (x % 30));
}
/* Do the last one */
i->minmask[x/30] |= (1 << (x % 30));
/* All done */
}
static char *days[] =
{
"sun",
"mon",
"tue",
"wed",
"thu",
"fri",
"sat",
};
static unsigned int get_dow(char *dow)
{
char *c;
/* The following line is coincidence, really! */
int s, e, x;
unsigned mask;
/* Check for all days */
if (!strlen(dow) || !strcmp(dow, "*"))
return (1 << 7) - 1;
/* Get start and ending days */
c = strchr(dow, '-');
if (c) {
*c = '\0';
c++;
}
/* Find the start */
s = 0;
while((s < 7) && strcasecmp(dow, days[s])) s++;
if (s >= 7) {
ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", dow);
return 0;
}
if (c) {
e = 0;
while((e < 7) && strcasecmp(dow, days[e])) e++;
if (e >= 7) {
ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
return 0;
}
} else
e = s;
mask = 0;
for (x=s;x!=e;x = (x + 1) % 7) {
mask |= (1 << x);
}
/* One last one */
mask |= (1 << x);
return mask;
}
static unsigned int get_day(char *day)
{
char *c;
/* The following line is coincidence, really! */
int s, e, x;
unsigned int mask;
/* Check for all days */
if (!strlen(day) || !strcmp(day, "*")) {
mask = (1 << 30) + ((1 << 30) - 1);
}
/* Get start and ending days */
c = strchr(day, '-');
if (c) {
*c = '\0';
c++;
}
/* Find the start */
if (sscanf(day, "%d", &s) != 1) {
ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day);
return 0;
}
if ((s < 1) || (s > 31)) {
ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", day);
return 0;
}
s--;
if (c) {
if (sscanf(c, "%d", &e) != 1) {
ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
return 0;
}
if ((e < 1) || (e > 31)) {
ast_log(LOG_WARNING, "Invalid day '%s', assuming none\n", c);
return 0;
}
e--;
} else
e = s;
mask = 0;
for (x=s;x!=e;x = (x + 1) % 31) {
mask |= (1 << x);
}
mask |= (1 << x);
return mask;
}
static char *months[] =
{
"jan",
"feb",
"mar",
"apr",
"may",
"jun",
"jul",
"aug",
"sep",
"oct",
"nov",
"dec",
};
static unsigned int get_month(char *mon)
{
char *c;
/* The following line is coincidence, really! */
int s, e, x;
unsigned int mask;
/* Check for all days */
if (!strlen(mon) || !strcmp(mon, "*"))
return (1 << 12) - 1;
/* Get start and ending days */
c = strchr(mon, '-');
if (c) {
*c = '\0';
c++;
}
/* Find the start */
s = 0;
while((s < 12) && strcasecmp(mon, months[s])) s++;
if (s >= 12) {
ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", mon);
return 0;
}
if (c) {
e = 0;
while((e < 12) && strcasecmp(mon, months[e])) e++;
if (e >= 12) {
ast_log(LOG_WARNING, "Invalid month '%s', assuming none\n", c);
return 0;
}
} else
e = s;
mask = 0;
for (x=s;x!=e;x = (x + 1) % 12) {
mask |= (1 << x);
}
/* One last one */
mask |= (1 << x);
return mask;
}
static void build_timing(struct ast_include *i, char *info)
{
char *c;
/* Check for empty just in case */
if (!strlen(info))
return;
i->hastime = 1;
/* Assume everything except time */
i->monthmask = (1 << 12) - 1;
i->daymask = (1 << 30) - 1 + (1 << 30);
i->dowmask = (1 << 7) - 1;
/* Avoid using strtok */
FIND_NEXT;
/* Info has the time range, start with that */
get_timerange(i, info);
info = c;
if (!info)
return;
FIND_NEXT;
/* Now check for day of week */
i->dowmask = get_dow(info);
info = c;
if (!info)
return;
FIND_NEXT;
/* Now check for the day of the month */
i->daymask = get_day(info);
info = c;
if (!info)
return;
FIND_NEXT;
/* And finally go for the month */
i->monthmask = get_month(info);
}
/*
* errno values
* ENOMEM - out of memory
@ -1832,6 +2120,7 @@ int ast_context_add_include2(struct ast_context *con, char *value,
char *registrar)
{
struct ast_include *new_include;
char *c;
struct ast_include *i, *il = NULL; /* include, include_last */
/* allocate new include structure ... */
@ -1842,7 +2131,17 @@ int ast_context_add_include2(struct ast_context *con, char *value,
}
/* ... fill in this structure ... */
memset(new_include, 0, sizeof(struct ast_include));
strncpy(new_include->name, value, sizeof(new_include->name)-1);
strncpy(new_include->rname, value, sizeof(new_include->rname)-1);
c = new_include->rname;
/* Strip off timing info */
while(*c && (*c != '|')) c++;
/* Process if it's there */
if (*c) {
build_timing(new_include, c+1);
*c = '\0';
}
new_include->next = NULL;
new_include->registrar = registrar;
@ -1932,6 +2231,7 @@ int ast_context_add_switch2(struct ast_context *con, char *value,
}
/* ... fill in this structure ... */
memset(new_sw, 0, sizeof(struct ast_sw));
strncpy(new_sw->name, value, sizeof(new_sw->name)-1);
if (data)
strncpy(new_sw->data, data, sizeof(new_sw->data)-1);
@ -2068,10 +2368,11 @@ int ast_context_add_ignorepat2(struct ast_context *con, char *value, char *regis
errno = ENOMEM;
return -1;
}
memset(ignorepat, 0, sizeof(struct ast_ignorepat));
strncpy(ignorepat->pattern, value, sizeof(ignorepat->pattern)-1);
ignorepat->next = NULL;
ignorepat->registrar = registrar;
pthread_mutex_lock(&con->lock);
ast_pthread_mutex_lock(&con->lock);
ignorepatc = con->ignorepats;
while(ignorepatc) {
ignorepatl = ignorepatc;
@ -2194,6 +2495,7 @@ int ast_add_extension2(struct ast_context *con,
/* Be optimistic: Build the extension structure first */
tmp = malloc(sizeof(struct ast_exten));
if (tmp) {
memset(tmp, 0, sizeof(struct ast_exten));
ext_strncpy(tmp->exten, extension, sizeof(tmp->exten));
tmp->priority = priority;
if (callerid) {
@ -2474,21 +2776,10 @@ static int pbx_builtin_prefix(struct ast_channel *chan, void *data)
static int pbx_builtin_wait(struct ast_channel *chan, void *data)
{
int ms;
struct ast_frame *f;
/* Wait for "n" seconds */
if (data && atoi((char *)data)) {
ms = atoi((char *)data) * 1000;
while(ms > 0) {
ms = ast_waitfor(chan, ms);
if (ms <0)
return -1;
if (ms > 0) {
f = ast_read(chan);
if (!f)
return -1;
ast_frfree(f);
}
}
return ast_safe_sleep(chan, ms);
}
return 0;
}

View File

@ -99,27 +99,6 @@ static int adsi_generate(unsigned char *buf, int msgtype, char *msg, int msglen,
}
#if 0
static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int len, int *remainder)
{
int res;
fd_set fds;
while(len) {
FD_ZERO(&fds);
FD_SET(chan->fds[0], &fds);
select(chan->fds[0] + 1, NULL, &fds, NULL, NULL);
res = write(chan->fds[0], buf, len);
if (res < 1) {
ast_log(LOG_WARNING, "Failed to write: %s\n", strerror(errno));
return -1;
}
buf += res;
len -= res;
}
return 0;
}
#else
static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int len, int *remainder)
{
/* Sends carefully on a full duplex channel by using reading for
@ -190,7 +169,6 @@ static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int l
}
return 0;
}
#endif
static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype)
{
@ -305,7 +283,7 @@ static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **ms
break;
else {
retries++;
ast_log(LOG_DEBUG, "Retransmitting (%d), from %d\n", start + 1);
ast_log(LOG_DEBUG, "Retransmitting (%d), from %d\n", retries, start + 1);
}
} else {
retries++;
@ -502,14 +480,15 @@ int adsi_download_connect(unsigned char *buf, unsigned char *service, unsigned
/* Delimiter */
buf[bytes++] = 0xff;
for (x=0;x<4;x++)
for (x=0;x<4;x++) {
buf[bytes++] = fdn[x];
}
for (x=0;x<4;x++)
buf[bytes++] = sec[x];
if (ver > -1)
buf[bytes++] = ver & 0xff;
buf[bytes++] = ver & 0xff;
buf[1] = bytes - 2;
return bytes;
}
@ -529,6 +508,158 @@ int adsi_disconnect_session(unsigned char *buf)
}
int adsi_query_cpeid(unsigned char *buf)
{
int bytes = 0;
buf[bytes++] = ADSI_QUERY_CPEID;
/* Reserve space for length */
bytes++;
buf[1] = bytes - 2;
return bytes;
}
int adsi_query_cpeinfo(unsigned char *buf)
{
int bytes = 0;
buf[bytes++] = ADSI_QUERY_CONFIG;
/* Reserve space for length */
bytes++;
buf[1] = bytes - 2;
return bytes;
}
int adsi_read_encoded_dtmf(struct ast_channel *chan, unsigned char *buf, int maxlen)
{
int bytes = 0;
int res;
unsigned char current = 0;
int gotstar = 0;
int pos = 0;
memset(buf, 0, sizeof(buf));
while(bytes <= maxlen) {
/* Wait up to a second for a digit */
res = ast_waitfordigit(chan, 1000);
if (!res)
break;
if (res == '*') {
gotstar = 1;
continue;
}
/* Ignore anything other than a digit */
if ((res < '0') || (res > '9'))
continue;
res -= '0';
if (gotstar)
res += 9;
if (pos) {
pos = 0;
buf[bytes++] = (res << 4) | current;
} else {
pos = 1;
current = res;
}
gotstar = 0;
}
return bytes;
}
int adsi_get_cpeid(struct ast_channel *chan, unsigned char *cpeid, int voice)
{
char buf[256];
int bytes = 0;
int res;
bytes += adsi_data_mode(buf);
adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
bytes = 0;
bytes += adsi_query_cpeid(buf);
adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
/* Get response */
memset(buf, 0, sizeof(buf));
res = adsi_read_encoded_dtmf(chan, cpeid, 4);
if (res != 4) {
ast_log(LOG_WARNING, "Got %d bytes back of encoded DTMF, expecting 4\n", res);
res = 0;
} else {
res = 1;
}
if (voice) {
bytes = 0;
bytes += adsi_voice_mode(buf, 0);
adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
/* Ignore the resulting DTMF B announcing it's in voice mode */
ast_waitfordigit(chan, 1000);
}
return res;
}
int adsi_get_cpeinfo(struct ast_channel *chan, int *width, int *height, int *buttons, int voice)
{
char buf[256];
int bytes = 0;
int res;
bytes += adsi_data_mode(buf);
adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
bytes = 0;
bytes += adsi_query_cpeinfo(buf);
adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
/* Get width */
memset(buf, 0, sizeof(buf));
res = ast_readstring(chan, buf, 2, 1000, 500, "");
if (res < 0)
return res;
if (strlen(buf) != 2) {
ast_log(LOG_WARNING, "Got %d bytes of width, expecting 2\n", res);
res = 0;
} else {
res = 1;
}
if (width)
*width = atoi(buf);
/* Get height */
memset(buf, 0, sizeof(buf));
if (res) {
res = ast_readstring(chan, buf, 2, 1000, 500, "");
if (res < 0)
return res;
if (strlen(buf) != 2) {
ast_log(LOG_WARNING, "Got %d bytes of height, expecting 2\n", res);
res = 0;
} else {
res = 1;
}
if (height)
*height= atoi(buf);
}
/* Get buttons */
memset(buf, 0, sizeof(buf));
if (res) {
res = ast_readstring(chan, buf, 1, 1000, 500, "");
if (res < 0)
return res;
if (strlen(buf) != 1) {
ast_log(LOG_WARNING, "Got %d bytes of buttons, expecting 1\n", res);
res = 0;
} else {
res = 1;
}
if (buttons)
*buttons = atoi(buf);
}
if (voice) {
bytes = 0;
bytes += adsi_voice_mode(buf, 0);
adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
/* Ignore the resulting DTMF B announcing it's in voice mode */
ast_waitfordigit(chan, 1000);
}
return res;
}
int adsi_data_mode(unsigned char *buf)
{
int bytes=0;
@ -544,6 +675,36 @@ int adsi_data_mode(unsigned char *buf)
}
int adsi_clear_soft_keys(unsigned char *buf)
{
int bytes=0;
/* Message type */
buf[bytes++] = ADSI_CLEAR_SOFTKEY;
/* Reserve space for length */
bytes++;
buf[1] = bytes - 2;
return bytes;
}
int adsi_clear_screen(unsigned char *buf)
{
int bytes=0;
/* Message type */
buf[bytes++] = ADSI_CLEAR_SCREEN;
/* Reserve space for length */
bytes++;
buf[1] = bytes - 2;
return bytes;
}
int adsi_voice_mode(unsigned char *buf, int when)
{
int bytes=0;
@ -719,86 +880,6 @@ int adsi_set_line(unsigned char *buf, int page, int line)
static int total = 0;
static int speeds = 0;
#if 0
int adsi_channel_init(struct ast_channel *chan)
{
char dsp[256];
char keys[256];
int bytes;
int x;
unsigned char *msgs[3];
unsigned char keyd[6];
int lens[3];
int types[3];
memset(dsp, 0, sizeof(dsp));
memset(keys, 0, sizeof(keys));
memset(msgs, 0, sizeof(msgs));
/* Start with initial display setup */
bytes = 0;
bytes += adsi_connect_session(dsp, NULL, -1);
for (x=0;x<total;x++) {
bytes += adsi_display(dsp + bytes, ADSI_INFO_PAGE, x + 1, aligns[x], 0,
strlen(intro[x]) ? intro[x] : " ", "");
}
bytes += adsi_set_line(dsp + bytes, ADSI_INFO_PAGE, 1);
msgs[0] = dsp;
lens[0] = bytes;
types[0] = ADSI_MSG_DISPLAY;
/* Prepare key setup messages */
if (speeds) {
bytes = 0;
memset(keyd, 0, sizeof(keyd));
for (x=0;x<speeds;x++) {
bytes += adsi_load_soft_key(keys + bytes, ADSI_SPEED_DIAL + x,
speeddial[x][1], speeddial[x][2], speeddial[x][0]);
keyd[x] = ADSI_SPEED_DIAL + x;
}
bytes += adsi_set_keys(keys + bytes, keyd);
msgs[1] = keys;
lens[1] = bytes;
types[1] = ADSI_MSG_DISPLAY;
}
adsi_transmit_messages(chan, msgs, lens, types);
return 0;
}
#else
int adsi_channel_init(struct ast_channel *chan)
{
char dsp[256];
int bytes;
int x;
unsigned char keyd[6];
memset(dsp, 0, sizeof(dsp));
/* Start with initial display setup */
bytes = 0;
bytes += adsi_connect_session(dsp, NULL, -1);
for (x=0;x<total;x++) {
bytes += adsi_display(dsp + bytes, ADSI_INFO_PAGE, x + 1, aligns[x], 0,
strlen(intro[x]) ? intro[x] : " ", "");
}
bytes += adsi_set_line(dsp + bytes, ADSI_INFO_PAGE, 1);
/* Prepare key setup messages */
if (speeds) {
memset(keyd, 0, sizeof(keyd));
for (x=0;x<speeds;x++) {
bytes += adsi_load_soft_key(dsp + bytes, ADSI_SPEED_DIAL + x,
speeddial[x][1], speeddial[x][2], speeddial[x][0], 0);
keyd[x] = ADSI_SPEED_DIAL + x;
}
bytes += adsi_set_keys(dsp + bytes, keyd);
}
adsi_transmit_message(chan, dsp, bytes, ADSI_MSG_DISPLAY);
return 0;
}
#endif
int adsi_channel_restore(struct ast_channel *chan)
{
char dsp[256];
@ -826,6 +907,26 @@ int adsi_channel_restore(struct ast_channel *chan)
}
int adsi_print(struct ast_channel *chan, char **lines, int *aligns, int voice)
{
char buf[4096];
int bytes=0;
int res;
int x;
for(x=0;lines[x];x++)
bytes += adsi_display(buf + bytes, ADSI_INFO_PAGE, x+1, aligns[x],0, lines[x], "");
bytes += adsi_set_line(buf + bytes, ADSI_INFO_PAGE, 1);
if (voice) {
bytes += adsi_voice_mode(buf + bytes, 0);
}
res = adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
if (voice) {
/* Ignore the resulting DTMF B announcing it's in voice mode */
ast_waitfordigit(chan, 1000);
}
return res;
}
int adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int data)
{
char dsp[256];
@ -845,21 +946,24 @@ int adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int
/* Prepare key setup messages */
if (adsi_transmit_message(chan, dsp, bytes, ADSI_MSG_DISPLAY))
return -1;
res = ast_readstring(chan, resp, 1, 1200, 1200, "");
if (res < 0)
return -1;
if (res) {
ast_log(LOG_DEBUG, "No response from CPE about version. Assuming not there.\n");
return 0;
}
if (!strcmp(resp, "B")) {
ast_log(LOG_DEBUG, "CPE has script '%s' version %d already loaded\n", app, ver);
if (app) {
res = ast_readstring(chan, resp, 1, 1200, 1200, "");
if (res < 0)
return -1;
if (res) {
ast_log(LOG_DEBUG, "No response from CPE about version. Assuming not there.\n");
return 0;
}
if (!strcmp(resp, "B")) {
ast_log(LOG_DEBUG, "CPE has script '%s' version %d already loaded\n", app, ver);
return 1;
} else if (!strcmp(resp, "A")) {
ast_log(LOG_DEBUG, "CPE hasn't script '%s' version %d already loaded\n", app, ver);
} else {
ast_log(LOG_WARNING, "Unexpected CPE response to script query: %s\n", resp);
}
} else
return 1;
} else if (!strcmp(resp, "A")) {
ast_log(LOG_DEBUG, "CPE hasn't script '%s' version %d already loaded\n", app, ver);
} else {
ast_log(LOG_WARNING, "Unexpected CPE response to script query: %s\n", resp);
}
return 0;
}