dect
/
asterisk
Archived
13
0
Fork 0

Tue Mar 18 07:00:01 CET 2003

git-svn-id: http://svn.digium.com/svn/asterisk/trunk@652 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
matteo 2003-03-18 06:00:18 +00:00
parent 5ed6a971da
commit 15d2f7aa97
17 changed files with 395 additions and 286 deletions

View File

@ -13,6 +13,34 @@
.EXPORT_ALL_VARIABLES:
# Pentium Pro Optimize
#PROC=i686
# Pentium Optimize
#PROC=i586
#PROC=k6
#PROC=ppc
PROC=$(shell uname -m)
######### More GSM codec optimization
######### Uncomment to enable MMXTM optimizations for x86 architecture CPU's
######### which support MMX instructions. This should be newer pentiums,
######### ppro's, etc, as well as the AMD K6 and K7.
K6OPT = #-DK6OPT
#Tell gcc to optimize the asterisk's code
OPTIMIZE=-O6
#Include debug symbols in the executables (-g) and profiling info (-pg)
DEBUG=-g #-pg
# Optional debugging parameters
DEBUG_THREADS = #-DDO_CRASH -DDEBUG_THREADS
# Uncomment next one to enable ast_frame tracing (for debugging)
TRACE_FRAMES = #-DTRACE_FRAMES
# Where to install asterisk after compiling
# Default -> leave empty
INSTALL_PREFIX=
ASTLIBDIR=$(INSTALL_PREFIX)/usr/lib/asterisk
@ -30,18 +58,9 @@ ASTVARRUNDIR=$(INSTALL_PREFIX)/var/run
MODULES_DIR=$(ASTLIBDIR)/modules
AGI_DIR=$(ASTVARLIBDIR)/agi-bin
# Pentium Pro Optimize
#PROC=i686
# Pentium Optimize
#PROC=i586
#PROC=k6
#PROC=ppc
PROC=$(shell uname -m)
DEBUG=-g #-pg
INCLUDE=-Iinclude -I../include
CFLAGS=-pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations $(DEBUG) $(INCLUDE) -D_REENTRANT -D_GNU_SOURCE #-DMAKE_VALGRIND_HAPPY
#CFLAGS+=-O6
CFLAGS+=$(OPTIMIZE)
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)
@ -62,10 +81,8 @@ CFLAGS+=-DASTCONFPATH=\"$(ASTCONFPATH)\"
CFLAGS+=-DASTMODDIR=\"$(MODULES_DIR)\"
CFLAGS+=-DASTAGIDIR=\"$(AGI_DIR)\"
# Optional debugging parameters
CFLAGS+= -DDO_CRASH -DDEBUG_THREADS
# Uncomment next one to enable ast_frame tracing (for debugging)
#CFLAGS+= -DTRACE_FRAMES
CFLAGS+= $(DEBUG_THREADS)
CFLAGS+= $(TRACE_FRAMES)
CFLAGS+=# -fomit-frame-pointer
SUBDIRS=res channels pbx apps codecs formats agi cdr astman
LIBS=-ldl -lpthread -lncurses -lm #-lnjamd
@ -311,3 +328,7 @@ config:
fi
dont-optimize:
make OPTIMIZE= K6OPT= install
valgrind: dont-optimize

View File

@ -56,6 +56,7 @@ static int substring_exec(struct ast_channel *chan, void *data)
char *count1, *count2;
char *first, *second, *stringp;
stringp=alloca(strlen(data)+1);
ast_log(LOG_WARNING, "The use of Substring application is deprecated. Please use ${variable:a:b} instead\n");
strncpy(stringp,data,strlen(data)+1);
if (strchr(stringp,'|')&&strchr(stringp,'=')) {
int icount1,icount2;

View File

@ -347,7 +347,8 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int lock)
cur = cur->next;
qlen++;
}
if (qlen > 128) {
/* Allow up to 96 voice frames outstanding, and up to 128 total frames */
if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) {
if (fin->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
CRASH;

View File

@ -3409,7 +3409,6 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
char rel0[256];
char rel1[255];
char empty[32]=""; /* Safety measure */
fr.ts=0; /* make Valgrind happy */
res = recvfrom(netsocket, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len);
if (res < 0) {
if (errno != ECONNREFUSED)
@ -3473,6 +3472,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", ntohs(fh->seqno), f.frametype, f.subclass);
/* Check if it's out of order (and not an ACK or INVAL) */
fr.seqno = ntohs(fh->seqno);
fr.ts = ntohl(fh->ts);
if ((iaxs[fr.callno]->iseqno != fr.seqno) &&
(iaxs[fr.callno]->iseqno ||
((f.subclass != AST_IAX_COMMAND_TXCNT) &&
@ -3525,7 +3525,6 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
f.data = buf + sizeof(struct ast_iax_full_hdr);
else
f.data = empty;
fr.ts = ntohl(fh->ts);
/* Unless this is an ACK or INVAL frame, ack it */
if ((f.frametype != AST_FRAME_IAX) ||
((f.subclass != AST_IAX_COMMAND_ACK) &&

View File

@ -1786,6 +1786,7 @@ static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
struct ast_frame *f;
struct chan_iax2_pvt *p0 = c0->pvt->pvt;
struct chan_iax2_pvt *p1 = c1->pvt->pvt;
struct timeval waittimer = {0, 0}, tv;
/* Put them in native bridge mode */
p0->bridgecallno = p1->callno;
@ -1814,13 +1815,18 @@ static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
if ((p0->transferring == TRANSFER_RELEASED) && (p1->transferring == TRANSFER_RELEASED)) {
/* Call has been transferred. We're no longer involved */
sleep(1);
c0->_softhangup |= AST_SOFTHANGUP_DEV;
c1->_softhangup |= AST_SOFTHANGUP_DEV;
*fo = NULL;
*rc = c0;
res = 0;
break;
gettimeofday(&tv, NULL);
if (!waittimer.tv_sec && !waittimer.tv_usec) {
waittimer.tv_sec = tv.tv_sec;
waittimer.tv_usec = tv.tv_usec;
} else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
c0->_softhangup |= AST_SOFTHANGUP_DEV;
c1->_softhangup |= AST_SOFTHANGUP_DEV;
*fo = NULL;
*rc = c0;
res = 0;
break;
}
}
to = 1000;
who = ast_waitfor_n(cs, 2, &to);
@ -2164,7 +2170,10 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
fh->ts = htonl(fr->ts);
fh->oseqno = fr->oseqno;
fh->iseqno = fr->iseqno;
if (transfer) {
fh->iseqno = 0;
} else
fh->iseqno = fr->iseqno;
/* Keep track of the last thing we've acknowledged */
pvt->aseqno = fr->iseqno;
fh->type = fr->af.frametype & 0xFF;
@ -2206,6 +2215,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
ast_log(LOG_WARNING, "Out of trunk data space on call number %d, dropping\n", pvt->callno);
pvt->trunkerror = 1;
}
res = 0;
} else {
/* Mini-frames have no sequence number */
fr->oseqno = -1;
@ -3355,146 +3365,6 @@ static int iax2_poke_peer_s(void *data)
return 0;
}
static int parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
{
/* Parse data into information elements */
int len;
int ie;
memset(ies, 0, sizeof(struct iax_ies));
ies->msgcount = -1;
while(datalen >= 2) {
ie = data[0];
len = data[1];
if (len > datalen - 2) {
ast_log(LOG_WARNING, "Information element length exceeds message size\n");
return -1;
}
switch(ie) {
case IAX_IE_CALLED_NUMBER:
ies->called_number = data + 2;
break;
case IAX_IE_CALLING_NUMBER:
ies->calling_number = data + 2;
break;
case IAX_IE_CALLING_ANI:
ies->calling_ani = data + 2;
break;
case IAX_IE_CALLING_NAME:
ies->calling_name = data + 2;
break;
case IAX_IE_CALLED_CONTEXT:
ies->called_context = data + 2;
break;
case IAX_IE_USERNAME:
ies->username = data + 2;
break;
case IAX_IE_PASSWORD:
ies->password = data + 2;
break;
case IAX_IE_CAPABILITY:
if (len != sizeof(unsigned int))
ast_log(LOG_WARNING, "Expecting capability to be %d bytes long but was %d\n", sizeof(unsigned int), len);
else
ies->capability = ntohl(*((unsigned int *)(data + 2)));
break;
case IAX_IE_FORMAT:
if (len != sizeof(unsigned int))
ast_log(LOG_WARNING, "Expecting format to be %d bytes long but was %d\n", sizeof(unsigned int), len);
else
ies->format = ntohl(*((unsigned int *)(data + 2)));
break;
case IAX_IE_LANGUAGE:
ies->language = data + 2;
break;
case IAX_IE_VERSION:
if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting version to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else
ies->version = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_ADSICPE:
if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting adsicpe to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else
ies->adsicpe = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_DNID:
ies->dnid = data + 2;
break;
case IAX_IE_AUTHMETHODS:
if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting authmethods to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else
ies->authmethods = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_CHALLENGE:
ies->challenge = data + 2;
break;
case IAX_IE_MD5_RESULT:
ies->md5_result = data + 2;
break;
case IAX_IE_RSA_RESULT:
ies->rsa_result = data + 2;
break;
case IAX_IE_APPARENT_ADDR:
ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
break;
case IAX_IE_REFRESH:
if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting refresh to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else
ies->refresh = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_DPSTATUS:
if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting dpstatus to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else
ies->dpstatus = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_CALLNO:
if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting callno to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else
ies->callno = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_CAUSE:
ies->cause = data + 2;
break;
case IAX_IE_IAX_UNKNOWN:
if (len == 1)
ies->iax_unknown = data[2];
else
ast_log(LOG_WARNING, "Expected single byte Unknown command, but was %d long\n", len);
break;
case IAX_IE_MSGCOUNT:
if (len != sizeof(unsigned short))
ast_log(LOG_WARNING, "Expecting msgcount to be %d bytes long but was %d\n", sizeof(unsigned short), len);
else
ies->msgcount = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_AUTOANSWER:
ies->autoanswer = 1;
break;
case IAX_IE_MUSICONHOLD:
ies->musiconhold = 1;
break;
default:
ast_log(LOG_NOTICE, "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
}
/* Overwrite information element with 0, to null terminate previous portion */
data[0] = 0;
datalen -= (len + 2);
data += (len + 2);
}
/* Null-terminate last field */
*data = '\0';
if (datalen) {
ast_log(LOG_WARNING, "Invalid information element contents, strange boundary\n");
return -1;
}
return 0;
}
static int send_trunk(struct iax2_peer *peer)
{
int x;
@ -3777,9 +3647,8 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
ast_pthread_mutex_unlock(&iaxsl[fr.callno]);
return 1;
}
if (((f.subclass != IAX_COMMAND_TXCNT) &&
(f.subclass != IAX_COMMAND_TXACC)) || (f.frametype != AST_FRAME_IAX))
iaxs[fr.callno]->peercallno = (short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
if (!memcmp(&sin, &iaxs[fr.callno]->addr, sizeof(sin)))
iaxs[fr.callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
if (ntohs(mh->callno) & IAX_FLAG_FULL) {
if (option_debug)
ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
@ -3840,9 +3709,11 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
}
f.datalen = res - sizeof(struct ast_iax2_full_hdr);
/* Handle implicit ACKing unless this is an INVAL */
if (((f.subclass != IAX_COMMAND_INVAL)) ||
(f.frametype != AST_FRAME_IAX)) {
/* Handle implicit ACKing unless this is an INVAL, and only if this is
from the real peer, not the transfer peer */
if (!memcmp(&sin, &iaxs[fr.callno]->addr, sizeof(sin)) &&
(((f.subclass != IAX_COMMAND_INVAL)) ||
(f.frametype != AST_FRAME_IAX))) {
unsigned char x;
/* XXX This code is not very efficient. Surely there is a better way which still
properly handles boundary conditions? XXX */
@ -3883,10 +3754,18 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
} else
ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr.iseqno, iaxs[fr.callno]->rseqno, iaxs[fr.callno]->oseqno);
}
if (memcmp(&sin, &iaxs[fr.callno]->addr, sizeof(sin)) &&
((f.frametype != AST_FRAME_IAX) ||
((f.subclass != IAX_COMMAND_TXACC) &&
(f.subclass != IAX_COMMAND_TXCNT)))) {
/* Only messages we accept from a transfer host are TXACC and TXCNT */
ast_pthread_mutex_unlock(&iaxsl[fr.callno]);
return 1;
}
if (f.datalen) {
if (f.frametype == AST_FRAME_IAX) {
if (parse_ies(&ies, buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
if (iax_parse_ies(&ies, buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
ast_log(LOG_WARNING, "undecodable frame received\n");
ast_pthread_mutex_unlock(&iaxsl[fr.callno]);
return 1;
@ -4385,6 +4264,8 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
send_command_transfer(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
break;
case IAX_COMMAND_TXREL:
/* Send ack immediately, rather than waiting until we've changed addresses */
send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno);
complete_transfer(fr.callno, &ies);
break;
case IAX_COMMAND_DPREP:

View File

@ -473,7 +473,7 @@ static void sip_prefs_free(void)
static void sip_pref_remove(int format)
{
struct sip_codec_pref *cur, *prev;
struct sip_codec_pref *cur, *prev=NULL;
cur = prefs;
while(cur) {
if (cur->codec == format) {
@ -744,10 +744,9 @@ static int sip_hangup(struct ast_channel *ast)
static int sip_answer(struct ast_channel *ast)
{
int res = 0,fmt,capability;
int res = 0,fmt;
char *codec;
struct sip_pvt *p = ast->pvt->pvt;
struct sip_codec_pref *oldpref=NULL;
if (ast->_state != AST_STATE_UP) {
@ -759,10 +758,6 @@ static int sip_answer(struct ast_channel *ast)
ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC) variable\n",codec);
fmt=ast_getformatbyname(codec);
if (fmt) {
oldpref=prefs;
prefs=NULL;
sip_pref_append(fmt);
capability=p->capability;
p->capability=fmt;
} else ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized codec: %s\n",codec);
}
@ -771,11 +766,6 @@ static int sip_answer(struct ast_channel *ast)
if (option_debug)
ast_log(LOG_DEBUG, "sip_answer(%s)\n", ast->name);
res = transmit_response_with_sdp(p, "200 OK", &p->initreq);
sip_prefs_free();
if (oldpref) {
prefs=oldpref;
p->capability=capability;
}
}
return res;
}

View File

@ -2732,6 +2732,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
p->owner = p->subs[SUB_REAL].owner;
if (p->subs[SUB_REAL].owner && p->subs[SUB_REAL].owner->bridge)
ast_moh_stop(p->subs[SUB_REAL].owner->bridge);
zt_enable_ec(p);
}
}

View File

@ -342,3 +342,157 @@ void iax_set_error(void (*func)(const char *))
{
errorf = func;
}
int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
{
/* Parse data into information elements */
int len;
int ie;
char tmp[256];
memset(ies, 0, sizeof(struct iax_ies));
ies->msgcount = -1;
while(datalen >= 2) {
ie = data[0];
len = data[1];
if (len > datalen - 2) {
errorf("Information element length exceeds message size\n");
return -1;
}
switch(ie) {
case IAX_IE_CALLED_NUMBER:
ies->called_number = data + 2;
break;
case IAX_IE_CALLING_NUMBER:
ies->calling_number = data + 2;
break;
case IAX_IE_CALLING_ANI:
ies->calling_ani = data + 2;
break;
case IAX_IE_CALLING_NAME:
ies->calling_name = data + 2;
break;
case IAX_IE_CALLED_CONTEXT:
ies->called_context = data + 2;
break;
case IAX_IE_USERNAME:
ies->username = data + 2;
break;
case IAX_IE_PASSWORD:
ies->password = data + 2;
break;
case IAX_IE_CAPABILITY:
if (len != sizeof(unsigned int)) {
snprintf(tmp, sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", sizeof(unsigned int), len);
errorf(tmp);
} else
ies->capability = ntohl(*((unsigned int *)(data + 2)));
break;
case IAX_IE_FORMAT:
if (len != sizeof(unsigned int)) {
snprintf(tmp, sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", sizeof(unsigned int), len);
errorf(tmp);
} else
ies->format = ntohl(*((unsigned int *)(data + 2)));
break;
case IAX_IE_LANGUAGE:
ies->language = data + 2;
break;
case IAX_IE_VERSION:
if (len != sizeof(unsigned short)) {
snprintf(tmp, sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", sizeof(unsigned short), len);
errorf(tmp);
} else
ies->version = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_ADSICPE:
if (len != sizeof(unsigned short)) {
snprintf(tmp, sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", sizeof(unsigned short), len);
errorf(tmp);
} else
ies->adsicpe = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_DNID:
ies->dnid = data + 2;
break;
case IAX_IE_AUTHMETHODS:
if (len != sizeof(unsigned short)) {
snprintf(tmp, sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", sizeof(unsigned short), len);
errorf(tmp);
} else
ies->authmethods = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_CHALLENGE:
ies->challenge = data + 2;
break;
case IAX_IE_MD5_RESULT:
ies->md5_result = data + 2;
break;
case IAX_IE_RSA_RESULT:
ies->rsa_result = data + 2;
break;
case IAX_IE_APPARENT_ADDR:
ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
break;
case IAX_IE_REFRESH:
if (len != sizeof(unsigned short)) {
snprintf(tmp, sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", sizeof(unsigned short), len);
errorf(tmp);
} else
ies->refresh = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_DPSTATUS:
if (len != sizeof(unsigned short)) {
snprintf(tmp, sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", sizeof(unsigned short), len);
errorf(tmp);
} else
ies->dpstatus = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_CALLNO:
if (len != sizeof(unsigned short)) {
snprintf(tmp, sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", sizeof(unsigned short), len);
errorf(tmp);
} else
ies->callno = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_CAUSE:
ies->cause = data + 2;
break;
case IAX_IE_IAX_UNKNOWN:
if (len == 1)
ies->iax_unknown = data[2];
else {
snprintf(tmp, sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
errorf(tmp);
}
break;
case IAX_IE_MSGCOUNT:
if (len != sizeof(unsigned short)) {
snprintf(tmp, sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", sizeof(unsigned short), len);
errorf(tmp);
} else
ies->msgcount = ntohs(*((unsigned short *)(data + 2)));
break;
case IAX_IE_AUTOANSWER:
ies->autoanswer = 1;
break;
case IAX_IE_MUSICONHOLD:
ies->musiconhold = 1;
break;
default:
snprintf(tmp, sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
errorf(tmp);
}
/* Overwrite information element with 0, to null terminate previous portion */
data[0] = 0;
datalen -= (len + 2);
data += (len + 2);
}
/* Null-terminate last field */
*data = '\0';
if (datalen) {
errorf("Invalid information element contents, strange boundary\n");
return -1;
}
return 0;
}

View File

@ -106,5 +106,6 @@ extern int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsign
extern int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, unsigned char *str);
extern int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat);
extern int iax_ie_append(struct iax_ie_data *ied, unsigned char ie);
extern int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen);
#endif

View File

@ -66,6 +66,8 @@
#define IAX_DEFAULT_REG_EXPIRE 60 /* By default require re-registration once per minute */
#define IAX_LINGER_TIMEOUT 10 /* How long to wait before closing bridged call */
#define IAX_DEFAULT_PORTNO 4569
/* IAX Information elements */

View File

@ -31,7 +31,7 @@ WAV49 = -DWAV49
######### manual page on gsm_option(3).
#K6OPT = -DK6OPT
K6OPT =
#K6OPT =
######### Define to enable MMXTM optimizations for x86 architecture CPU's
######### which support MMX instructions. This should be newer pentiums,
######### ppro's, etc, as well as the AMD K6 and K7. The compile will
@ -54,7 +54,7 @@ PG =
# CC = /usr/lang/acc
# CCFLAGS = -c -O
CC = gcc -ansi -pedantic -O6 -mpentium -fschedule-insns2 -fomit-frame-pointer
CC = gcc -ansi -pedantic $(OPTIMIZE) -march=$(PROC) -fschedule-insns2 -fomit-frame-pointer
CCFLAGS += -c -DNeedFunctionPrototypes=1 -finline-functions -funroll-loops
LD = $(CC)

View File

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

View File

@ -31,7 +31,7 @@ CONSOLE=Console/dsp ; Console interface for demo
IAXINFO=guest ; IAXtel username/password
;IAXINFO=myuser:mypass
TRUNK=Zap/g2 ; Trunk interface
;TRUNK=IAX/user:pass@provider
;TRUNK=IAX2/user:pass@provider
;
; Any category other than "General" and "Globals" represent
@ -84,10 +84,10 @@ TRUNK=Zap/g2 ; Trunk interface
; up, please go to www.gnophone.com or www.iaxtel.com
;
[iaxtel700]
exten => _91700NXXXXXX,1,Dial(IAX/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel)
exten => _91700NXXXXXX,1,Dial(IAX2/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel)
[iaxprovider]
;switch => IAX/user:[key]@myserver/mycontext
;switch => IAX2/user:[key]@myserver/mycontext
[trunkint]
;
@ -155,7 +155,7 @@ include => provider
; extensions that are not known here, for example with remote
; IAX switching you transparently get access to the remote
;
; switch => IAX/user:password@bigserver/local
; switch => IAX2/user:password@bigserver/local
[macro-stdexten];
;
@ -218,7 +218,7 @@ exten => i,1,Playback(invalid) ; "That's not valid, try again"
; Asterisk demo.
;
exten => 500,1,Playback(demo-abouttotry); Let them know what's going on
exten => 500,2,Dial(IAX/guest@misery.digium.com/s@default) ; Call the Asterisk demo
exten => 500,2,Dial(IAX2/guest@misery.digium.com/s@default) ; Call the Asterisk demo
exten => 500,3,Playback(demo-nogo) ; Couldn't connect to the demo site
exten => 500,4,Goto(s,6) ; Return to the start over message.

40
frame.c
View File

@ -238,15 +238,37 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr)
struct ast_frame *ast_frdup(struct ast_frame *f)
{
struct ast_frame *ret;
int p;
p = f->mallocd;
f->mallocd = 0;
/* Make frisolate think this is a 100% static frame, and make a duplicate */
ret = ast_frisolate(f);
/* Restore its true malloc status */
f->mallocd = p;
return ret;
struct ast_frame *out;
int len;
void *buf;
/* Start with standard stuff */
len = sizeof(struct ast_frame) + AST_FRIENDLY_OFFSET + f->datalen;
/* If we have a source, add space for it */
if (f->src && strlen(f->src))
len += strlen(f->src) + 1;
buf = malloc(len);
if (!buf)
return NULL;
out = buf;
/* Set us as having malloc'd header only, so it will eventually
get freed. */
out->frametype = f->frametype;
out->subclass = f->subclass;
out->datalen = f->datalen;
out->samples = f->samples;
out->mallocd = AST_MALLOCD_HDR;
out->offset = AST_FRIENDLY_OFFSET;
out->data = buf + sizeof(struct ast_frame) + AST_FRIENDLY_OFFSET;
if (f->src && strlen(f->src)) {
out->src = out->data + f->datalen;
/* Must have space since we allocated for it */
strcpy(out->src, f->src);
} else
out->src = NULL;
out->prev = NULL;
out->next = NULL;
memcpy(out->data, f->data, out->datalen);
return out;
}
struct ast_frame *ast_fr_fdread(int fd)

180
pbx.c
View File

@ -678,97 +678,125 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan, char *cont
static void pbx_substitute_variables_temp(struct ast_channel *c,char *cp3,char **cp4)
{
int offset;
char *first,*second;
int offset,offset2;
struct ast_var_t *variables;
char *name, *num; /* for callerid name + num variables */
struct varshead *headp;
char pri[80];
headp=&c->varshead;
*cp4=NULL;
/* Now we have the variable name on cp3 */
if (!strcmp(cp3, "CALLERIDNUM")) {
char cid[256] = "";
if (c->callerid)
strncpy(cid, c->callerid, sizeof(cid) - 1);
ast_callerid_parse(cid, &name, &num);
if (num) {
ast_shrink_phone_number(num);
*cp4 = num;
} else
*cp4 = "";
} else if (!strcmp(cp3, "CALLERIDNAME")) {
char cid[256] = "";
if (c->callerid)
strncpy(cid, c->callerid, sizeof(cid) - 1);
ast_callerid_parse(cid, &name, &num);
if (name)
*cp4 = name;
else
*cp4 = "";
} else if (!strcmp(cp3, "CALLERID")) {
*cp4 = c->callerid;
if (!(*cp4))
*cp4 = "";
} else if (!strcmp(cp3, "EXTEN")) {
*cp4 = c->exten;
} else if (!strncmp(cp3, "EXTEN-", strlen("EXTEN-")) &&
/* XXX Remove me eventually */
(sscanf(cp3 + strlen("EXTEN-"), "%d", &offset) == 1)) {
if (offset < 0)
offset=0;
if (offset > strlen(c->exten))
offset = strlen(c->exten);
*cp4 = c->exten + offset;
ast_log(LOG_WARNING, "The use of 'EXTEN-foo' has been derprecated in favor of 'EXTEN:foo'\n");
} else if (!strncmp(cp3, "EXTEN:", strlen("EXTEN:")) &&
(sscanf(cp3 + strlen("EXTEN:"), "%d", &offset) == 1)) {
if (offset < 0)
offset=0;
if (offset > strlen(c->exten))
offset = strlen(c->exten);
*cp4 = c->exten + offset;
} else if (!strcmp(cp3, "RDNIS")) {
*cp4 = c->rdnis;
if (!(*cp4))
*cp4 = "";
} else if (!strcmp(cp3, "CONTEXT")) {
*cp4 = c->context;
} else if (!strcmp(cp3, "PRIORITY")) {
snprintf(pri, sizeof(pri), "%d", c->priority);
*cp4 = pri;
} else {
AST_LIST_TRAVERSE(headp,variables,entries) {
/* Now we have the variable name on cp3 */
if ((first=strchr(cp3,':'))) {
*first='\0';
offset=atoi(first+1);
if ((second=strchr(first+1,':'))) {
*second='\0';
offset2=atoi(second+1);
} else {
offset2=offset;
offset=0;
}
pbx_substitute_variables_temp(c,cp3,cp4);
if (!(*cp4)) return;
if (abs(offset)>strlen(*cp4)) {
if (offset>=0) offset=strlen(*cp4);
else offset=-strlen(*cp4);
}
if ((offset<0 && offset2>-offset) || (offset>=0 && offset+offset2>strlen(*cp4))) {
if (offset>=0) offset2=strlen(*cp4)-offset;
else offset2=strlen(*cp4)+offset;
}
if (offset>=0)
*cp4+=offset;
else
*cp4+=strlen(*cp4)+offset;
(*cp4)[offset2] = '\0';
} else if (!strcmp(cp3, "CALLERIDNUM")) {
char cid[256] = "";
if (c->callerid)
strncpy(cid, c->callerid, sizeof(cid) - 1);
ast_callerid_parse(cid, &name, &num);
if (num) {
ast_shrink_phone_number(num);
*cp4 = num;
} else
*cp4 = "";
} else if (!strcmp(cp3, "CALLERIDNAME")) {
char cid[256] = "";
if (c->callerid)
strncpy(cid, c->callerid, sizeof(cid) - 1);
ast_callerid_parse(cid, &name, &num);
if (name)
*cp4 = name;
else
*cp4 = "";
} else if (!strcmp(cp3, "CALLERID")) {
*cp4 = c->callerid;
if (!(*cp4))
*cp4 = "";
} else if (!strcmp(cp3, "EXTEN")) {
*cp4 = c->exten;
} else if (!strncmp(cp3, "EXTEN-", strlen("EXTEN-")) &&
/* XXX Remove me eventually */
(sscanf(cp3 + strlen("EXTEN-"), "%d", &offset) == 1)) {
if (offset < 0)
offset=0;
if (offset > strlen(c->exten))
offset = strlen(c->exten);
*cp4 = c->exten + offset;
ast_log(LOG_WARNING, "The use of 'EXTEN-foo' has been derprecated in favor of 'EXTEN:foo'\n");
#if 0
ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",cp3,ast_var_name(variables));
} else if (!strncmp(cp3, "EXTEN:", strlen("EXTEN:")) &&
(sscanf(cp3 + strlen("EXTEN:"), "%d", &offset) == 1)) {
if (offset < 0)
offset=0;
if (offset > strlen(c->exten))
offset = strlen(c->exten);
*cp4 = c->exten + offset;
#endif
if (strcasecmp(ast_var_name(variables),cp3)==0)
*cp4=ast_var_value(variables);
}
if (!(*cp4)) {
/* Try globals */
AST_LIST_TRAVERSE(&globals,variables,entries) {
} else if (!strcmp(cp3, "RDNIS")) {
*cp4 = c->rdnis;
if (!(*cp4))
*cp4 = "";
} else if (!strcmp(cp3, "CONTEXT")) {
*cp4 = c->context;
} else if (!strcmp(cp3, "PRIORITY")) {
snprintf(pri, sizeof(pri), "%d", c->priority);
*cp4 = pri;
} else {
AST_LIST_TRAVERSE(headp,variables,entries) {
#if 0
ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",cp3,ast_var_name(variables));
ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",cp3,ast_var_name(variables));
#endif
if (strcasecmp(ast_var_name(variables),cp3)==0)
*cp4=ast_var_value(variables);
}
}
if (!(*cp4)) {
int len=strlen(cp3);
int len_env=strlen("ENV(");
if (len > (len_env+1) && !strncasecmp(cp3,"ENV(",len_env) && !strcmp(cp3+len-1,")")) {
cp3[len-1]='\0';
*cp4=getenv(cp3+len_env);
}
}
}
if (strcasecmp(ast_var_name(variables),cp3)==0)
*cp4=ast_var_value(variables);
}
if (!(*cp4)) {
/* Try globals */
AST_LIST_TRAVERSE(&globals,variables,entries) {
#if 0
ast_log(LOG_WARNING,"Comparing variable '%s' with '%s'\n",cp3,ast_var_name(variables));
#endif
if (strcasecmp(ast_var_name(variables),cp3)==0)
*cp4=ast_var_value(variables);
}
}
if (!(*cp4)) {
int len=strlen(cp3);
int len_env=strlen("ENV(");
if (len > (len_env+1) && !strncasecmp(cp3,"ENV(",len_env) && !strcmp(cp3+len-1,")")) {
cp3[len-1]='\0';
*cp4=getenv(cp3+len_env);
}
}
}
}
static void pbx_substitute_variables_helper(struct ast_channel *c,char *cp1,char **ecp2,int count)
{
char *cp4,*cp2;
char *tmp,*wherearewe,*finish,*ltmp,*lval,*nextvar;
char *tmp,*wherearewe,*finish=NULL,*ltmp,*lval,*nextvar;
int length,variables=0;
wherearewe=tmp=cp1;

View File

@ -1512,8 +1512,12 @@ static int pbx_load_module(void)
appl = stringp;
if (!appl)
appl="";
if (!(start = strchr(appl, '(')))
appl = strsep(&stringp, ",");
if (!(start = strchr(appl, '('))) {
if (stringp)
appl = strsep(&stringp, ",");
else
appl = "";
}
if (start && (end = strrchr(appl, ')'))) {
*start = *end = '\0';
data = start + 1;
@ -1525,7 +1529,10 @@ static int pbx_load_module(void)
data = strsep(&stringp, "\"");
stringp++;
} else {
data = strsep(&stringp, ",");
if (stringp)
data = strsep(&stringp, ",");
else
data = "";
}
cidmatch = strchr(ext, '/');
if (cidmatch) {

View File

@ -221,8 +221,8 @@ static void *monmp3thread(void *data)
res = read(class->pseudofd, buf, sizeof(buf));
} else {
/* otherwise just sleep (unreliable) */
usleep(250000);
res = 2000;
usleep(100000); /* Sleep 100 ms */
res = 800; /* 800 samples */
}
if (!class->members)
continue;
@ -328,7 +328,7 @@ static struct mohdata *mohalloc(struct mohclass *cl)
static void moh_release(struct ast_channel *chan, void *data)
{
struct mohdata *moh = data, *prev, *cur;
int oldrfmt, oldwfmt;
int oldwfmt;
ast_pthread_mutex_lock(&moh_lock);
/* Unlink */
prev = NULL;
@ -350,8 +350,8 @@ static void moh_release(struct ast_channel *chan, void *data)
oldwfmt = moh->origwfmt;
free(moh);
if (chan) {
if (ast_set_write_format(chan, oldwfmt))
ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %d/%d\n", chan->name, oldwfmt, oldrfmt);
if (oldwfmt && ast_set_write_format(chan, oldwfmt))
ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %d\n", chan->name, oldwfmt);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name);
}