aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author(no author) <(no author)@f38db490-d61c-443f-a65b-d21fe96a405b>2004-04-13 04:46:23 +0000
committer(no author) <(no author)@f38db490-d61c-443f-a65b-d21fe96a405b>2004-04-13 04:46:23 +0000
commitd46468f42c6762ce7646e773c7d0919ed1f626d4 (patch)
tree5d62a34385385b3485137835b2629174ca0464cf
parentf38bc8131c9eda8d0b0eabaafbaa53f4247989c4 (diff)
This commit was manufactured by cvs2svn to create tag 'v0_9_0'.
git-svn-id: http://svn.digium.com/svn/asterisk/tags/v0_9_0@2684 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xBUGS34
-rwxr-xr-xCHANGES7
-rwxr-xr-xMakefile2
-rwxr-xr-xREADME4
-rwxr-xr-xacl.c22
-rwxr-xr-xaesopt.h1
-rwxr-xr-xapps/app_adsiprog.c15
-rwxr-xr-xapps/app_agi.c15
-rwxr-xr-xapps/app_chanisavail.c14
-rwxr-xr-xapps/app_cut.c2
-rwxr-xr-xapps/app_dial.c31
-rwxr-xr-xapps/app_directory.c16
-rwxr-xr-xapps/app_festival.c3
-rwxr-xr-xapps/app_macro.c2
-rwxr-xr-xapps/app_parkandannounce.c15
-rwxr-xr-xapps/app_queue.c67
-rwxr-xr-xapps/app_random.c4
-rwxr-xr-xapps/app_record.c6
-rwxr-xr-xapps/app_sql_postgres.c2
-rwxr-xr-xapps/app_system.c5
-rwxr-xr-xapps/app_voicemail.c108
-rwxr-xr-xapps/app_waitforring.c2
-rwxr-xr-xapps/app_zapras.c2
-rwxr-xr-xapps/app_zapscan.c20
-rwxr-xr-xasterisk.c49
-rwxr-xr-xastman/astman.c1
-rwxr-xr-xautoservice.c8
-rwxr-xr-xchannel.c102
-rwxr-xr-xchannels/Makefile16
-rwxr-xr-xchannels/chan_agent.c17
-rwxr-xr-xchannels/chan_alsa.c43
-rwxr-xr-xchannels/chan_h323.c10
-rwxr-xr-xchannels/chan_iax.c10
-rwxr-xr-xchannels/chan_iax2.c277
-rwxr-xr-xchannels/chan_mgcp.c10
-rwxr-xr-xchannels/chan_modem.c10
-rwxr-xr-xchannels/chan_nbs.c4
-rwxr-xr-xchannels/chan_phone.c10
-rwxr-xr-xchannels/chan_sip.c151
-rwxr-xr-xchannels/chan_skinny.c10
-rwxr-xr-xchannels/chan_vofr.c8
-rwxr-xr-xchannels/chan_zap.c78
-rwxr-xr-xchannels/iax2-parser.c6
-rwxr-xr-xcli.c8
-rwxr-xr-xcodecs/codec_adpcm.c44
-rwxr-xr-xcodecs/gsm/Makefile6
-rwxr-xr-xcodecs/lpc10/Makefile4
-rwxr-xr-xconfig.c14
-rwxr-xr-xconfigs/extensions.conf.sample21
-rwxr-xr-xconfigs/iax.conf.sample6
-rwxr-xr-xconfigs/mgcp.conf.sample1
-rwxr-xr-xconfigs/sip.conf.sample82
-rwxr-xr-xconfigs/voicemail.conf.sample4
-rwxr-xr-xconfigs/zapata.conf.sample13
-rwxr-xr-xcontrib/scripts/sip-friends.sql1
-rwxr-xr-xcontrib/scripts/vmdb.sql11
-rwxr-xr-xdns.c12
-rwxr-xr-xdoc/README.cdr4
-rwxr-xr-xdoc/README.iax10
-rwxr-xr-xdoc/README.variables4
-rwxr-xr-xdoc/extensions.txt4
-rwxr-xr-xdoc/localchannel.txt2
-rwxr-xr-xdoc/manager.txt2
-rwxr-xr-xdoc/model.txt4
-rwxr-xr-xdoc/modules.txt6
-rwxr-xr-xdsp.c36
-rwxr-xr-xenum.c4
-rwxr-xr-xfile.c26
-rwxr-xr-xformats/format_g723.c2
-rwxr-xr-xformats/format_vox.c162
-rwxr-xr-xformats/format_wav_gsm.c4
-rwxr-xr-xframe.c4
-rwxr-xr-xinclude/asterisk/adsi.h4
-rwxr-xr-xinclude/asterisk/channel.h2
-rwxr-xr-xinclude/asterisk/config.h8
-rwxr-xr-xinclude/asterisk/file.h14
-rwxr-xr-xinclude/asterisk/frame.h12
-rwxr-xr-xinclude/asterisk/lock.h15
-rwxr-xr-xinclude/asterisk/manager.h4
-rwxr-xr-xinclude/asterisk/options.h1
-rwxr-xr-xinclude/asterisk/parking.h2
-rwxr-xr-xindications.c4
-rwxr-xr-xloader.c1
-rwxr-xr-xlogger.c21
-rwxr-xr-xmanager.c92
-rwxr-xr-xmd5.c8
-rwxr-xr-xpbx.c62
-rwxr-xr-xpbx/pbx_config.c2
-rwxr-xr-xpbx/pbx_spool.c63
-rwxr-xr-xres/res_indications.c4
-rwxr-xr-xres/res_monitor.c2
-rwxr-xr-xres/res_parking.c35
-rwxr-xr-xrtp.c31
-rwxr-xr-xsample.call5
-rwxr-xr-xsay.c7
-rwxr-xr-xsrv.c4
-rwxr-xr-xtranslate.c33
-rwxr-xr-xutils/astman.c1
98 files changed, 1362 insertions, 795 deletions
diff --git a/BUGS b/BUGS
index d896e7c22..15f29a452 100755
--- a/BUGS
+++ b/BUGS
@@ -1,3 +1,37 @@
+Known Issues in Asterisk 1.0
+============================
+In order to provide a path for a stable Asterisk 1.0, the Asterisk CVS tree
+was forked into a a 1.0-stable branch. Many new features and enhancements
+have been added to the development tree in the mean time since the branch,
+but in the interest of stability, only bug fixes were accepted into the
+stable branch, meaning that over time, there has been a substantial
+diversion of the feature set between stable (1.0) and developmental
+Asterisk. This section is a list of important differences between the
+stable (1.0) and development versions of Asterisk.
+
+* The number of SIP channels that can be simultaneously run through Asterisk
+ may be more limited than in development releases.
+
+* When Asterisk carries media from one RTP or IAX connection to another,
+ jitter on one side can sometimes be reflected in the timestamps going
+ to the other, causing the audio to be broken up on poor quality network
+ connections. This behavior has been changed in development releases.
+
+* The MGCP channel driver has been greatly extended in development releases.
+
+* The VPB (Voicetronix) driver in 1.0 only works with properly with FXO
+ interfaces. Extensive work has been done on the driver in the development
+ channel.
+
+* The SIP channel driver's ability to negotiate codecs has been improved
+ in developmental Asterisk.
+
+* The return result of app_system is unrealiable in 1.0 and has gone through
+ extensive rework in developmental Asterisk.
+
+* The queue system has been extensively reworked with a variety of new
+ features in developmental Asterisk.
+
Asterisk Bug Tracking Information
=================================
diff --git a/CHANGES b/CHANGES
index 68433196c..e0b86a11b 100755
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+Asterisk 0.9.0
+ -- Fixes from the bug tracker
+ -- ADPCM Standardization
+ -- Branch to Stable CVS
+Asterisk 0.7.2
+ -- Countless small bug fixes from bug tracker
+ -- DSP Fixes
-- Fix unloading of Zaptel
-- Pass Caller*ID/ANI properly on call forwarding
-- Add indication for Italy
diff --git a/Makefile b/Makefile
index b678b15fb..3cc44afff 100755
--- a/Makefile
+++ b/Makefile
@@ -397,7 +397,7 @@ samples: all datafiles adsi
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
cat $(DESTDIR)$(ASTVARLIBDIR)/sounds/$$x.gsm >> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/unavail.gsm ; \
done
- :> $(DESTDIR)$(ASTVARLIBDIR)/sounds/voicemail/default/1234/busy.gsm
+ :> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/busy.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isonphone; do \
cat $(DESTDIR)$(ASTVARLIBDIR)/sounds/$$x.gsm >> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/busy.gsm ; \
done
diff --git a/README b/README
index ccb8c66b4..64bf06a20 100755
--- a/README
+++ b/README
@@ -24,7 +24,7 @@ community on this Wiki:
must apply to all loadable modules as well, except as defined below.
Digium, Inc. (formerly Linux Support Services) retains copyright to all
-of the core Asterisk system, and therefore can grant, at its sole discression,
+of the core Asterisk system, and therefore can grant, at its sole discretion,
the ability for companies, individuals, or organizations to create proprietary
or Open Source (but non-GPL'd) modules which may be dynamically linked at
runtime with the portions of Asterisk which fall under our copyright
@@ -34,7 +34,7 @@ umbrella, or are distributed under more flexible licenses than GPL.
If you wish to use our code in other GPL programs, don't worry -- there
is no requirement that you provide the same exemption in your GPL'd
products (although if you've written a module for Asterisk we would
-strongly encourage you to make the same excemption that we do).
+strongly encourage you to make the same exemption that we do).
Specific permission is also granted to OpenSSL and OpenH323 to link to
Asterisk.
diff --git a/acl.c b/acl.c
index 9e1edb414..1ec629f2b 100755
--- a/acl.c
+++ b/acl.c
@@ -279,7 +279,7 @@ int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
fgets(line,sizeof(line),PROC);
while (!feof(PROC)) {
- char iface[8];
+ char iface[256];
unsigned int dest, gateway, mask;
int i,fieldnum;
char *fields[40];
@@ -303,18 +303,20 @@ int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
i = offset - line;
}
}
+ if (fieldnum >= 8) {
- sscanf(fields[0],"%s",iface);
- sscanf(fields[1],"%x",&dest);
- sscanf(fields[2],"%x",&gateway);
- sscanf(fields[7],"%x",&mask);
+ sscanf(fields[0],"%s",iface);
+ sscanf(fields[1],"%x",&dest);
+ sscanf(fields[2],"%x",&gateway);
+ sscanf(fields[7],"%x",&mask);
#if 0
- printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask);
+ printf("Addr: %s %08x Dest: %08x Mask: %08x\n", inet_ntoa(*them), remote_ip, dest, mask);
#endif
- /* Looks simple, but here is the magic */
- if (((remote_ip & mask) ^ dest) == 0) {
- res = ast_lookup_iface(iface,us);
- break;
+ /* Looks simple, but here is the magic */
+ if (((remote_ip & mask) ^ dest) == 0) {
+ res = ast_lookup_iface(iface,us);
+ break;
+ }
}
}
fclose(PROC);
diff --git a/aesopt.h b/aesopt.h
index 60675e418..799c8a694 100755
--- a/aesopt.h
+++ b/aesopt.h
@@ -149,6 +149,7 @@
/* PLATFORM SPECIFIC INCLUDES */
#if defined( __FreeBSD__ ) || defined( __OpenBSD__ )
+# include <sys/types.h>
# include <sys/endian.h>
#elif defined( BSD ) && ( BSD >= 199103 )
# include <machine/endian.h>
diff --git a/apps/app_adsiprog.c b/apps/app_adsiprog.c
index 696b1cd77..12742609d 100755
--- a/apps/app_adsiprog.c
+++ b/apps/app_adsiprog.c
@@ -666,7 +666,7 @@ static int showdisplay(char *buf, char *name, int id, char *args, struct adsi_sc
}
buf[0] = id;
- buf[1] = (cmd << 6) | (disp->id & 0x2f);
+ buf[1] = (cmd << 6) | (disp->id & 0x3f);
buf[2] = ((line & 0x1f) << 3) | (flag & 0x7);
return 3;
}
@@ -695,6 +695,18 @@ static int digitdirect(char *buf, char *name, int id, char *args, struct adsi_sc
return 2;
}
+static int clearcbone(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
+{
+ char *tok;
+ tok = get_token(&args, script, lineno);
+ if (tok)
+ ast_log(LOG_WARNING, "CLEARCB1 requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
+
+ buf[0] = id;
+ buf[1] = 0;
+ return 2;
+}
+
static int digitcollect(char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
{
char *tok;
@@ -831,6 +843,7 @@ static struct adsi_key_cmd kcmds[] = {
{ "VOICEMODE", 0x93 },
/* Display call buffer 'n' */
/* Clear call buffer 'n' */
+ { "CLEARCB1", 0x95, clearcbone },
{ "DIGITCOLLECT", 0x96, digitcollect },
{ "DIGITDIRECT", 0x96, digitdirect },
{ "CLEAR", 0x97 },
diff --git a/apps/app_agi.c b/apps/app_agi.c
index 2be4987bb..cb635451f 100755
--- a/apps/app_agi.c
+++ b/apps/app_agi.c
@@ -529,6 +529,8 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
if (!fs) {
res = -1;
fdprintf(agi->fd, "200 result=%d (writefile)\n", res);
+ if (sildet)
+ ast_dsp_free(sildet);
return RESULT_FAILURE;
}
@@ -545,12 +547,16 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
if (res < 0) {
ast_closestream(fs);
fdprintf(agi->fd, "200 result=%d (waitfor) endpos=%ld\n", res,sample_offset);
+ if (sildet)
+ ast_dsp_free(sildet);
return RESULT_FAILURE;
}
f = ast_read(chan);
if (!f) {
fdprintf(agi->fd, "200 result=%d (hangup) endpos=%ld\n", 0, sample_offset);
ast_closestream(fs);
+ if (sildet)
+ ast_dsp_free(sildet);
return RESULT_FAILURE;
}
switch(f->frametype) {
@@ -561,6 +567,8 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
fdprintf(agi->fd, "200 result=%d (dtmf) endpos=%ld\n", f->subclass, sample_offset);
ast_closestream(fs);
ast_frfree(f);
+ if (sildet)
+ ast_dsp_free(sildet);
return RESULT_SUCCESS;
}
break;
@@ -596,6 +604,7 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, char
if (gotsilence) {
ast_stream_rewind(fs, silence-1000);
ast_truncstream(fs);
+ sample_offset = ast_tellstream(fs);
}
fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
ast_closestream(fs);
@@ -1218,6 +1227,10 @@ static int agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf)
fdprintf(agi->fd, c->usage);
fdprintf(agi->fd, "520 End of proper usage.\n");
break;
+ case AST_PBX_KEEPALIVE:
+ /* We've been asked to keep alive, so do so */
+ return AST_PBX_KEEPALIVE;
+ break;
case RESULT_FAILURE:
/* They've already given the failure. We've been hung up on so handle this
appropriately */
@@ -1285,7 +1298,7 @@ static int run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid)
returnstatus |= agi_handle_command(chan, agi, buf);
/* If the handle_command returns -1, we need to stop */
- if (returnstatus < 0) {
+ if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) {
break;
}
} else {
diff --git a/apps/app_chanisavail.c b/apps/app_chanisavail.c
index 57f6e6ff0..18e61b419 100755
--- a/apps/app_chanisavail.c
+++ b/apps/app_chanisavail.c
@@ -38,9 +38,9 @@ static char *synopsis = "Check if channel is available";
static char *descrip =
" ChanIsAvail(Technology/resource[&Technology2/resource2...]): \n"
"Checks is any of the requested channels are available. If none\n"
-"of the requested channels are available the new priority will\n"
-"be n+101 (unless such a priority does not exist, in which case\n"
-"ChanIsAvail will return -1. If any of the requested channels\n"
+"of the requested channels are available the new priority will be\n"
+"n+101 (unless such a priority does not exist or on error, in which\n"
+"case ChanIsAvail will return -1). If any of the requested channels\n"
"are available, the next priority will be n+1, the channel variable\n"
"${AVAILCHAN} will be set to the name of the available channel and\n"
"the ChanIsAvail app will return 0.\n";
@@ -53,7 +53,7 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
- char info[256], *peers, *tech, *number, *rest, *cur;
+ char info[512], *peers, *tech, *number, *rest, *cur;
struct ast_channel *tempchan;
if (!data) {
@@ -62,7 +62,7 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
}
LOCAL_USER_ADD(u);
- strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
+ strncpy(info, (char *)data, sizeof(info)-1);
peers = info;
if (peers) {
cur = peers;
@@ -76,8 +76,8 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
tech = cur;
number = strchr(tech, '/');
if (!number) {
- ast_log(LOG_WARNING, "ChanIsAvail argument takes format (Zap/[device])\n");
- continue;
+ ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
+ return -1;
}
*number = '\0';
number++;
diff --git a/apps/app_cut.c b/apps/app_cut.c
index 1d3cf5b89..18de2d10a 100755
--- a/apps/app_cut.c
+++ b/apps/app_cut.c
@@ -85,6 +85,8 @@ static int cut_exec(struct ast_channel *chan, void *data)
char *tmp2 = alloca(MAXRESULT);
char retstring[MAXRESULT];
+ if (tmp2)
+ memset(tmp2, 0, MAXRESULT);
memset(retstring, 0, MAXRESULT);
if (tmp && tmp2) {
diff --git a/apps/app_dial.c b/apps/app_dial.c
index bfc93f69f..15bbaaedb 100755
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -49,10 +49,10 @@ static char *descrip =
"which first answered. All other calls placed by the Dial app will be hung up\n"
"If a timeout is not specified, the Dial application will wait indefinitely\n"
"until either one of the called channels answers, the user hangs up, or all\n"
-"channels return busy or error. In general, the dialler will return 0 if it\n"
+"channels return busy or error. In general, the dialer will return 0 if it\n"
"was unable to place the call, or the timeout expired. However, if all\n"
"channels were busy, and there exists an extension with priority n+101 (where\n"
-"n is the priority of the dialler instance), then it will be the next\n"
+"n is the priority of the dialer instance), then it will be the next\n"
"executed extension (this allows you to setup different behavior on busy from\n"
"no-answer).\n"
" This application returns -1 if the originating channel hangs up, or if the\n"
@@ -69,7 +69,7 @@ static char *descrip =
" 'A(x)' -- play an announcement to the called party, using x as file\n"
" In addition to transferring the call, a call may be parked and then picked\n"
"up by another user.\n"
-" The optionnal URL will be sent to the called party if the channel supports\n"
+" The optional URL will be sent to the called party if the channel supports\n"
"it.\n";
/* We define a customer "local user" structure because we
@@ -139,6 +139,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
} else if (outgoing->ringbackonly) {
ast_indicate(in, AST_CONTROL_RINGING);
}
+ sentringing++;
}
while(*to && !peer) {
@@ -171,7 +172,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
/* if no one available we'd better stop MOH/ringing to */
if (moh) {
ast_moh_stop(in);
- } else if (ringind) {
+ } else if (sentringing) {
ast_indicate(in, -1);
}
return NULL;
@@ -207,13 +208,19 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (o->chan->callerid)
free(o->chan->callerid);
o->chan->callerid = malloc(strlen(in->callerid) + 1);
- strncpy(o->chan->callerid, in->callerid, strlen(in->callerid) + 1);
+ if (o->chan->callerid)
+ strncpy(o->chan->callerid, in->callerid, strlen(in->callerid) + 1);
+ else
+ ast_log(LOG_WARNING, "Out of memory\n");
}
if (in->ani) {
if (o->chan->ani)
free(o->chan->ani);
o->chan->ani = malloc(strlen(in->ani) + 1);
- strncpy(o->chan->ani, in->ani, strlen(in->ani) + 1);
+ if (o->chan->ani)
+ strncpy(o->chan->ani, in->ani, strlen(in->ani) + 1);
+ else
+ ast_log(LOG_WARNING, "Out of memory\n");
}
if (ast_call(o->chan, tmpchan, 0)) {
ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
@@ -268,7 +275,6 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (!sentringing && !moh) {
ast_indicate(in, AST_CONTROL_RINGING);
sentringing++;
- ringind++;
}
break;
case AST_CONTROL_PROGRESS:
@@ -280,9 +286,12 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
/* Ignore going off hook */
break;
case -1:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
- ast_indicate(in, -1);
+ if (!ringind && !moh) {
+ if (option_verbose > 2)
+ ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
+ ast_indicate(in, -1);
+ sentringing = 0;
+ }
break;
default:
ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
@@ -337,7 +346,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
}
if (moh) {
ast_moh_stop(in);
- } else if (ringind) {
+ } else if (sentringing) {
ast_indicate(in, -1);
}
diff --git a/apps/app_directory.c b/apps/app_directory.c
index 8e8f62455..199888b23 100755
--- a/apps/app_directory.c
+++ b/apps/app_directory.c
@@ -37,7 +37,8 @@ static char *descrip =
"discovered from voicemail.conf. The context argument is required, and\n"
"specifies the context in which to interpret the extensions. Returns 0\n"
"unless the user hangs up. It also sets up the channel on exit to enter the\n"
-"extension the user selected.\n";
+"extension the user selected. Please note that the context must be the same\n"
+"as the section in voicemail.conf that the mailbox is processed from as well.\n";
/* For simplicity, I'm keeping the format compatible with the voicemail config,
but i'm open to suggestions for isolating it */
@@ -199,10 +200,15 @@ ahem:
ast_stopstream(chan);
if (res > -1) {
if (res == '1') {
- strncpy(chan->exten, v->name, sizeof(chan->exten)-1);
- chan->priority = 0;
- strncpy(chan->context, context, sizeof(chan->context)-1);
- res = 0;
+ if (ast_exists_extension(chan, context, v->name, 1, chan->callerid)) {
+ strncpy(chan->exten, v->name, sizeof(chan->exten)-1);
+ chan->priority = 0;
+ strncpy(chan->context, context, sizeof(chan->context)-1);
+ res = 0;
+ } else {
+ ast_log(LOG_WARNING, "Can't find extension '%s' in context '%s'. Did you pass the wrong context to Directory?\n", v->name, context);
+ res = -1;
+ }
break;
} else if (res == '*') {
res = 0;
diff --git a/apps/app_festival.c b/apps/app_festival.c
index 82a819395..309af973b 100755
--- a/apps/app_festival.c
+++ b/apps/app_festival.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2002, Christos Ricudis
*
- * Christos Ricudis <ricudis@paiko.gr>
+ * Christos Ricudis <ricudis@itc.auth.gr>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
@@ -376,6 +376,7 @@ static int festival_exec(struct ast_channel *chan, void *vdata)
if (strlen((char *)data)==strln) {
ast_log(LOG_DEBUG,"Size OK\n");
read(fdesc,&bigstring,strln);
+ bigstring[strln] = 0;
if (strcmp(bigstring,data)==0) {
readcache=1;
} else {
diff --git a/apps/app_macro.c b/apps/app_macro.c
index 6cb07bd6f..3189d077b 100755
--- a/apps/app_macro.c
+++ b/apps/app_macro.c
@@ -202,7 +202,7 @@ out:
/* If we're leaving the macro normally, restore original information */
chan->priority = oldpriority;
strncpy(chan->context, oldcontext, sizeof(chan->context) - 1);
- if (!chan->_softhangup) {
+ if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) {
/* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
strncpy(chan->exten, oldexten, sizeof(chan->exten) - 1);
if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) {
diff --git a/apps/app_parkandannounce.c b/apps/app_parkandannounce.c
index 072d55189..2b6404bef 100755
--- a/apps/app_parkandannounce.c
+++ b/apps/app_parkandannounce.c
@@ -68,13 +68,17 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data)
int outstate;
struct localuser *u;
- if (!data) {
- ast_log(LOG_WARNING, "Park requires an argument (parkinglot)\n");
+ if (!data || (data && !strlen(data))) {
+ ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
return -1;
}
l=strlen(data)+2;
orig_s=malloc(l);
+ if (!orig_s) {
+ ast_log(LOG_WARNING, "Out of memory\n");
+ return -1;
+ }
s=orig_s;
strncpy(s,data,l);
@@ -85,9 +89,10 @@ static int parkandannounce_exec(struct ast_channel *chan, void *data)
return -1;
}
- timeout = atoi(strsep(&s, "|"));
- timeout *= 1000;
-
+ if (s) {
+ timeout = atoi(strsep(&s, "|"));
+ timeout *= 1000;
+ }
dial=strsep(&s, "|");
if (! dial) {
ast_log(LOG_WARNING, "PARK: A dial resouce must be specified i.e: Console/dsp or Zap/g1/5551212\n");
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 446b26422..4bb5aef6a 100755
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -78,7 +78,7 @@ static char *descrip =
" 'n' -- no retries on the timeout; will exit this application and go to the next step.\n"
" In addition to transferring the call, a call may be parked and then picked\n"
"up by another user.\n"
-" The optionnal URL will be sent to the called party if the channel supports\n"
+" The optional URL will be sent to the called party if the channel supports\n"
"it.\n";
// [PHM 06/26/03]
@@ -482,7 +482,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
if (numlines == numbusies) {
ast_log(LOG_DEBUG, "Everyone is busy at this time\n");
} else {
- ast_log(LOG_NOTICE, "No one is answered queue %s\n", queue);
+ ast_log(LOG_NOTICE, "No one is answering queue '%s'\n", queue);
}
*to = 0;
return NULL;
@@ -1344,7 +1344,7 @@ static void reload_queues(void)
ast_mutex_unlock(&qlock);
}
-static int queues_show(int fd, int argc, char **argv)
+static int __queues_show(int fd, int argc, char **argv, int queue_show)
{
struct ast_call_queue *q;
struct queue_ent *qe;
@@ -1353,19 +1353,32 @@ static int queues_show(int fd, int argc, char **argv)
time_t now;
char max[80];
char calls[80];
-
time(&now);
- if (argc != 2)
+ if ((!queue_show && argc != 2) || (queue_show && argc != 3))
return RESULT_SHOWUSAGE;
ast_mutex_lock(&qlock);
q = queues;
if (!q) {
ast_mutex_unlock(&qlock);
- ast_cli(fd, "No queues.\n");
+ if (queue_show)
+ ast_cli(fd, "No such queue: %s.\n",argv[2]);
+ else
+ ast_cli(fd, "No queues.\n");
return RESULT_SUCCESS;
}
while(q) {
ast_mutex_lock(&q->lock);
+ if (queue_show) {
+ if (strcasecmp(q->name, argv[2]) != 0) {
+ ast_mutex_unlock(&q->lock);
+ q = q->next;
+ if (!q) {
+ ast_cli(fd, "No such queue: %s.\n",argv[2]);
+ break;
+ }
+ continue;
+ }
+ }
if (q->maxlen)
snprintf(max, sizeof(max), "%d", q->maxlen);
else
@@ -1400,11 +1413,41 @@ static int queues_show(int fd, int argc, char **argv)
ast_cli(fd, "\n");
ast_mutex_unlock(&q->lock);
q = q->next;
+ if (queue_show)
+ break;
}
ast_mutex_unlock(&qlock);
return RESULT_SUCCESS;
}
+static int queues_show(int fd, int argc, char **argv)
+{
+ return __queues_show(fd, argc, argv, 0);
+}
+
+static int queue_show(int fd, int argc, char **argv)
+{
+ return __queues_show(fd, argc, argv, 1);
+}
+
+static char *complete_queue(char *line, char *word, int pos, int state)
+{
+ struct ast_call_queue *q;
+ int which=0;
+
+ ast_mutex_lock(&qlock);
+ q = queues;
+ while(q) {
+ if (!strncasecmp(word, q->name, strlen(word))) {
+ if (++which > state)
+ break;
+ }
+ q = q->next;
+ }
+ ast_mutex_unlock(&qlock);
+ return q ? strdup(q->name) : NULL;
+}
+
/* JDG: callback to display queues status in manager */
static int manager_queues_show( struct mansession *s, struct message *m )
{
@@ -1469,12 +1512,23 @@ static struct ast_cli_entry cli_show_queues = {
{ "show", "queues", NULL }, queues_show,
"Show status of queues", show_queues_usage, NULL };
+static char show_queue_usage[] =
+"Usage: show queue\n"
+" Provides summary information on a specified queue.\n";
+
+static struct ast_cli_entry cli_show_queue = {
+ { "show", "queue", NULL }, queue_show,
+ "Show status of a specified queue", show_queue_usage, complete_queue };
+
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
+ ast_cli_unregister(&cli_show_queue);
ast_cli_unregister(&cli_show_queues);
ast_manager_unregister( "Queues" );
ast_manager_unregister( "QueueStatus" );
+ ast_unregister_application(app_aqm);
+ ast_unregister_application(app_rqm);
return ast_unregister_application(app);
}
@@ -1483,6 +1537,7 @@ int load_module(void)
int res;
res = ast_register_application(app, queue_exec, synopsis, descrip);
if (!res) {
+ ast_cli_register(&cli_show_queue);
ast_cli_register(&cli_show_queues);
ast_manager_register( "Queues", 0, manager_queues_show, "Queues" );
ast_manager_register( "QueueStatus", 0, manager_queues_status, "Queue Status" );
diff --git a/apps/app_random.c b/apps/app_random.c
index d46c1c0f6..c9f8f4788 100755
--- a/apps/app_random.c
+++ b/apps/app_random.c
@@ -42,7 +42,7 @@ static int random_exec(struct ast_channel *chan, void *data)
int res=0;
struct localuser *u;
- char *s, *ts;
+ char *s;
char *exten, *pri, *context;
char *prob;
int probint, priorityint;
@@ -54,7 +54,7 @@ static int random_exec(struct ast_channel *chan, void *data)
LOCAL_USER_ADD(u);
s = ast_strdupa((void *) data);
- prob = strsep(&ts,":");
+ prob = strsep(&s,":");
if ((!prob) || (sscanf(prob, "%d", &probint) != 1))
probint = 0;
diff --git a/apps/app_record.c b/apps/app_record.c
index 732922ebf..29d98f760 100755
--- a/apps/app_record.c
+++ b/apps/app_record.c
@@ -30,13 +30,13 @@ static char *app = "Record";
static char *synopsis = "Record to a file";
static char *descrip =
-" Record(filename:extension|silence): Records from the channel into a given\n"
+" Record(filename:format|silence): Records from the channel into a given\n"
"filename. If the file exists it will be overwritten. \n"
-"- 'extension' is the extension of the file type to be recorded (wav, gsm, etc).\n"
+"- 'format' is the format of the file type to be recorded (wav, gsm, etc).\n"
"- 'silence' is the number of seconds of silence to allow before returning.\n\n"
"If filename contains '%d', these characters will be replaced with a number\n"
"incremented by one each time the file is recorded. \n\n"
-"Extensions: g723, g729, gsm, h263, ulaw, alaw, vox, wav, WAV\n\n"
+"Formats: g723, g729, gsm, h263, ulaw, alaw, vox, wav, WAV\n\n"
"Returns -1 when the user hangs up.\n";
STANDARD_LOCAL_USER;
diff --git a/apps/app_sql_postgres.c b/apps/app_sql_postgres.c
index 3e7e1f462..302d2563a 100755
--- a/apps/app_sql_postgres.c
+++ b/apps/app_sql_postgres.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2002, Christos Ricudis
*
- * Christos Ricudis <ricudis@paiko.gr>
+ * Christos Ricudis <ricudis@itc.auth.gr>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
diff --git a/apps/app_system.c b/apps/app_system.c
index 3378602fe..b13bcedc8 100755
--- a/apps/app_system.c
+++ b/apps/app_system.c
@@ -21,6 +21,7 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
#include <pthread.h>
@@ -53,13 +54,15 @@ static int system_exec(struct ast_channel *chan, void *data)
LOCAL_USER_ADD(u);
/* Do our thing here */
res = system((char *)data);
- if (res < 0) {
+ if ((res < 0) && (errno != ECHILD)) {
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", (char *)data);
res = -1;
} else {
+ if (res < 0)
+ res = 0;
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority+=100;
res = 0;
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 536a2e0a8..0dbf0531b 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -148,12 +148,14 @@ static char *synopsis_vm =
static char *descrip_vm =
" VoiceMail([s|u|b]extension[@context]): Leaves voicemail for a given\n"
-"extension (must be configured in voicemail.conf). If the extension is\n"
-"preceded by an 's' then instructions for leaving the message will be\n"
-"skipped. If the extension is preceeded by 'u' then the \"unavailable\"\n"
-"message will be played (/var/lib/asterisk/sounds/vm/<exten>/unavail) if it\n"
-"exists. If the extension is preceeded by a 'b' then the the busy message\n"
-"will be played (that is, busy instead of unavail).\n"
+"extension (must be configured in voicemail.conf). \n"
+" If the extension is preceded by \n"
+"* 's' instructions for leaving the message will be skipped.\n"
+"* 'u' the \"unavailable\" message will be played \n"
+" (/var/lib/asterisk/sounds/vm/<exten>/unavail) if it exists.\n"
+"* 'b' the busy message will be played (that is, busy instead of unavail).\n"
+"If the caller presses '0' (zero) during the prompt, the call jumps to\n"
+"priority 'o' in the current context.\n"
"If the requested mailbox does not exist, and there exists a priority\n"
"n + 101, then that priority will be taken next.\n"
"Returns -1 on error or mailbox not found, or if the user hangs up.\n"
@@ -167,7 +169,7 @@ static char *descrip_vmain =
"for the checking of voicemail. The mailbox can be passed as the option,\n"
"which will stop the voicemail system from prompting the user for the mailbox.\n"
"If the mailbox is preceded by 's' then the password check will be skipped. If\n"
-"a context is specified, logins are considered in that context only.\n"
+"a context is specified, logins are considered in that voicemail context only.\n"
"Returns -1 if the user hangs up or 0 otherwise.\n";
/* Leave a message */
@@ -450,11 +452,14 @@ static void vm_change_password(struct ast_vm_user *vmu, char *newpassword)
FILE *configin;
FILE *configout;
+ int linenum=0;
char inbuf[256];
char orig[256];
+ char currcontext[256] ="";
char tmpin[AST_CONFIG_MAX_PATH];
char tmpout[AST_CONFIG_MAX_PATH];
- char *user, *pass, *rest, *trim;
+ char *user, *pass, *rest, *trim, *tempcontext;
+ tempcontext = NULL;
snprintf((char *)tmpin, sizeof(tmpin)-1, "%s/voicemail.conf",(char *)ast_config_AST_CONFIG_DIR);
snprintf((char *)tmpout, sizeof(tmpout)-1, "%s/voicemail.conf.new",(char *)ast_config_AST_CONFIG_DIR);
configin = fopen((char *)tmpin,"r");
@@ -477,6 +482,7 @@ static void vm_change_password(struct ast_vm_user *vmu, char *newpassword)
while (!feof(configin)) {
/* Read in the line */
fgets(inbuf, sizeof(inbuf), configin);
+ linenum++;
if (!feof(configin)) {
/* Make a backup of it */
memcpy(orig, inbuf, sizeof(orig));
@@ -488,6 +494,18 @@ static void vm_change_password(struct ast_vm_user *vmu, char *newpassword)
user=inbuf;
while(*user < 33)
user++;
+ /* check for '[' (opening of context name ) */
+ tempcontext = strchr(user, '[');
+ if (tempcontext) {
+ strncpy(currcontext, tempcontext +1,
+ sizeof(currcontext) - 1);
+ /* now check for ']' */
+ tempcontext = strchr(currcontext, ']');
+ if (tempcontext)
+ *tempcontext = '\0';
+ else
+ currcontext[0] = '\0';
+ }
pass = strchr(user, '=');
if (pass > user) {
trim = pass - 1;
@@ -512,7 +530,11 @@ static void vm_change_password(struct ast_vm_user *vmu, char *newpassword)
}
} else
rest = NULL;
- if (user && pass && *user && *pass && !strcmp(user, vmu->mailbox) && !strcmp(pass, vmu->password)) {
+
+ /* Compare user, pass AND context */
+ if (user && *user && !strcmp(user, vmu->mailbox) &&
+ pass && *pass && !strcmp(pass, vmu->password) &&
+ currcontext && *currcontext && !strcmp(currcontext, vmu->context)) {
/* This is the line */
if (rest) {
fprintf(configout, "%s => %s,%s\n", vmu->mailbox,newpassword,rest);
@@ -741,7 +763,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m
fprintf(p, "--%s\n", bound);
}
- fprintf(p, "Content-Type: text/plain; charset=ISO-8859-1\nContent-Transfer-Encoding: 8bit\n");
+ fprintf(p, "Content-Type: text/plain; charset=ISO-8859-1\nContent-Transfer-Encoding: 8bit\n\n");
strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
if (emailbody) {
struct ast_channel *ast = ast_channel_alloc(0);
@@ -1318,6 +1340,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
FILE *txt;
int res = 0;
int msgnum;
+ int fd;
char date[256];
char dir[256];
char fn[256];
@@ -1453,11 +1476,15 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int
res = play_and_record(chan, NULL, fn, vmmaxmessage, fmt);
if (res > 0)
res = 0;
- txt = fopen(txtfile, "a");
- if (txt) {
- time(&end);
- fprintf(txt, "duration=%ld\n", (long)(end-start));
- fclose(txt);
+ fd = open(txtfile, O_APPEND | O_WRONLY);
+ if (fd > -1) {
+ txt = fdopen(fd, "a");
+ if (txt) {
+ time(&end);
+ fprintf(txt, "duration=%ld\n", (long)(end-start));
+ fclose(txt);
+ } else
+ close(fd);
}
stringp = fmt;
strsep(&stringp, "|");
@@ -2244,7 +2271,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i
system(sys);
todircount = count_messages(todir);
- strncpy(tmp, fmt, sizeof(tmp));
+ strncpy(tmp, fmt, sizeof(tmp) - 1);
stringp = tmp;
while((s = strsep(&stringp, "|"))) {
/* XXX This is a hack -- we should use build_filename or similar XXX */
@@ -2556,9 +2583,7 @@ static int vm_instructions(struct ast_channel *chan, struct vm_state *vms)
if (!res) {
vms->repeats++;
if (vms->repeats > 2) {
- res = play_and_wait(chan, "vm-goodbye");
- if (!res)
- res = 't';
+ res = 't';
}
}
}
@@ -2994,22 +3019,22 @@ static int append_mailbox(char *context, char *mbox, char *data)
char *stringp;
char *s;
struct ast_vm_user *vmu;
- strncpy(tmp, data, sizeof(tmp));
+ strncpy(tmp, data, sizeof(tmp) - 1);
vmu = malloc(sizeof(struct ast_vm_user));
if (vmu) {
memset(vmu, 0, sizeof(struct ast_vm_user));
- strncpy(vmu->context, context, sizeof(vmu->context));
- strncpy(vmu->mailbox, mbox, sizeof(vmu->mailbox));
+ strncpy(vmu->context, context, sizeof(vmu->context) - 1);
+ strncpy(vmu->mailbox, mbox, sizeof(vmu->mailbox) - 1);
vmu->attach = -1;
stringp = tmp;
if ((s = strsep(&stringp, ",")))
- strncpy(vmu->password, s, sizeof(vmu->password));
+ strncpy(vmu->password, s, sizeof(vmu->password) - 1);
if (stringp && (s = strsep(&stringp, ",")))
- strncpy(vmu->fullname, s, sizeof(vmu->fullname));
+ strncpy(vmu->fullname, s, sizeof(vmu->fullname) - 1);
if (stringp && (s = strsep(&stringp, ",")))
- strncpy(vmu->email, s, sizeof(vmu->email));
+ strncpy(vmu->email, s, sizeof(vmu->email) - 1);
if (stringp && (s = strsep(&stringp, ",")))
- strncpy(vmu->pager, s, sizeof(vmu->pager));
+ strncpy(vmu->pager, s, sizeof(vmu->pager) - 1);
if (stringp && (s = strsep(&stringp, ",")))
apply_options(vmu, s);
vmu->next = NULL;
@@ -3022,6 +3047,7 @@ static int append_mailbox(char *context, char *mbox, char *data)
return 0;
}
+#ifndef USEMYSQLVM
/* XXX TL Bug 690 */
static char show_voicemail_users_help[] =
"Usage: show voicemail users [for <context>]\n"
@@ -3143,7 +3169,7 @@ static struct ast_cli_entry show_voicemail_zones_cli =
{ { "show", "voicemail", "zones", NULL },
handle_show_voicemail_zones, "List zone message formats",
show_voicemail_zones_help, NULL };
-
+#endif
static int load_config(void)
{
@@ -3167,6 +3193,7 @@ static int load_config(void)
while(cur) {
l = cur;
cur = cur->next;
+ l->alloced = 1;
free_user(l);
}
zcur = zones;
@@ -3301,16 +3328,21 @@ static int load_config(void)
msg_format = ast_strdupa(var->value);
if (msg_format != NULL) {
timezone = strsep(&msg_format, "|");
- strncpy(z->name, var->name, sizeof(z->name) - 1);
- strncpy(z->timezone, timezone, sizeof(z->timezone) - 1);
- strncpy(z->msg_format, msg_format, sizeof(z->msg_format) - 1);
- z->next = NULL;
- if (zones) {
- zonesl->next = z;
- zonesl = z;
+ if (msg_format) {
+ strncpy(z->name, var->name, sizeof(z->name) - 1);
+ strncpy(z->timezone, timezone, sizeof(z->timezone) - 1);
+ strncpy(z->msg_format, msg_format, sizeof(z->msg_format) - 1);
+ z->next = NULL;
+ if (zones) {
+ zonesl->next = z;
+ zonesl = z;
+ } else {
+ zones = z;
+ zonesl = z;
+ }
} else {
- zones = z;
- zonesl = z;
+ ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
+ free(z);
}
} else {
ast_log(LOG_WARNING, "Out of memory while reading voicemail config\n");
@@ -3386,8 +3418,10 @@ int unload_module(void)
res |= ast_unregister_application(app2);
res |= ast_unregister_application(capp2);
sql_close();
+#ifndef USEMYSQLVM
ast_cli_unregister(&show_voicemail_users_cli);
ast_cli_unregister(&show_voicemail_zones_cli);
+#endif
return res;
}
@@ -3409,8 +3443,10 @@ int load_module(void)
ast_log(LOG_WARNING, "SQL init\n");
return res;
}
+#ifndef USEMYSQLVM
ast_cli_register(&show_voicemail_users_cli);
ast_cli_register(&show_voicemail_zones_cli);
+#endif
return res;
}
diff --git a/apps/app_waitforring.c b/apps/app_waitforring.c
index 3fcfa9a03..bb8622920 100755
--- a/apps/app_waitforring.c
+++ b/apps/app_waitforring.c
@@ -48,7 +48,7 @@ static int waitforring_exec(struct ast_channel *chan, void *data)
int res = 0;
int ms;
if (!data || (sscanf(data, "%d", &ms) != 1)) {
- ast_log(LOG_WARNING, "SoftHangup requires an argument (minimum seconds)\n");
+ ast_log(LOG_WARNING, "WaitForRing requires an argument (minimum seconds)\n");
return 0;
}
ms *= 1000;
diff --git a/apps/app_zapras.c b/apps/app_zapras.c
index 57a64ab5d..9d88a06e3 100755
--- a/apps/app_zapras.c
+++ b/apps/app_zapras.c
@@ -44,7 +44,7 @@ static char *synopsis = "Executes Zaptel ISDN RAS application";
static char *descrip =
" ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
"The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
-"channel to be able to use this function (No modem emulcation is included).\n"
+"channel to be able to use this function (No modem emulation is included).\n"
"Your pppd must be patched to be zaptel aware. Arguments should be\n"
"separated by | characters. Always returns -1.\n";
diff --git a/apps/app_zapscan.c b/apps/app_zapscan.c
index 54db27df0..b24fe5d57 100755
--- a/apps/app_zapscan.c
+++ b/apps/app_zapscan.c
@@ -43,8 +43,8 @@ static char *app = "ZapScan";
static char *synopsis = "Scan Zap channels to monitor calls";
static char *descrip =
-" ZapScan allows a call center manager to monitor\n"
-"phone conversations in a convenient way.";
+" ZapScan allows a call center manager to monitor Zap channels in\n"
+"a convenient way. Use '#' to select the next channel and use '*' to exit\n";
STANDARD_LOCAL_USER;
@@ -191,6 +191,9 @@ zapretry:
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
ret = 0;
break;
+ } else if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
+ ret = -1;
+ break;
} else if (fd != chan->fds[0]) {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_ULAW) {
@@ -245,6 +248,7 @@ static int conf_exec(struct ast_channel *chan, void *data)
int confno = 0;
char confstr[80], *tmp;
struct ast_channel *tempchan = NULL, *lastchan = NULL;
+ struct ast_frame *f;
LOCAL_USER_ADD(u);
@@ -252,10 +256,20 @@ static int conf_exec(struct ast_channel *chan, void *data)
ast_answer(chan);
for (;;) {
+ if (ast_waitfor(chan, 100) < 0)
+ break;
+ f = ast_read(chan);
+ if (!f)
+ break;
+ if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
+ ast_frfree(f);
+ break;
+ }
+ ast_frfree(f);
tempchan = ast_channel_walk(tempchan);
if ( !tempchan && !lastchan )
break;
- if ( tempchan && (!strcmp(tempchan->type, "Zap")) && (tempchan != chan) ) {
+ if ( tempchan && tempchan->type && (!strcmp(tempchan->type, "Zap")) && (tempchan != chan) ) {
ast_verbose(VERBOSE_PREFIX_3 "Zap channel %s is in-use, monitoring...\n", tempchan->name);
strcpy(confstr, tempchan->name);
if ((tmp = strchr(confstr,'-'))) {
diff --git a/asterisk.c b/asterisk.c
index b1be8c046..2c791af19 100755
--- a/asterisk.c
+++ b/asterisk.c
@@ -34,7 +34,7 @@
#include <signal.h>
#include <sched.h>
#include <asterisk/io.h>
-#include <pthread.h>
+#include <asterisk/lock.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/select.h>
@@ -65,7 +65,7 @@ int fully_booted = 0;
static int ast_socket = -1; /* UNIX Socket for allowing remote control */
static int ast_consock = -1; /* UNIX Socket for controlling another asterisk */
-static int mainpid;
+int ast_mainpid;
struct console {
int fd; /* File descriptor */
int p[2]; /* Pipe */
@@ -106,6 +106,11 @@ char ast_config_AST_PID[AST_CONFIG_MAX_PATH];
char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH];
char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH];
+static char *_argv[256];
+static int shuttingdown = 0;
+static int restartnow = 0;
+static pthread_t consolethread = AST_PTHREADT_NULL;
+
int ast_register_atexit(void (*func)(void))
{
int res = -1;
@@ -191,7 +196,7 @@ static void *netconsole(void *vconsole)
if (gethostname(hostname, sizeof(hostname)))
strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
- snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, mainpid, ASTERISK_VERSION);
+ snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, ast_mainpid, ASTERISK_VERSION);
fdprint(con->fd, tmp);
for(;;) {
FD_ZERO(&rfds);
@@ -252,13 +257,15 @@ static void *listener(void *unused)
FD_SET(ast_socket, &fds);
s = ast_select(ast_socket + 1, &fds, NULL, NULL, NULL);
if (s < 0) {
- ast_log(LOG_WARNING, "Select retured error: %s\n", strerror(errno));
+ if (errno != EINTR)
+ ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
continue;
}
len = sizeof(sun);
s = accept(ast_socket, (struct sockaddr *)&sun, &len);
if (s < 0) {
- ast_log(LOG_WARNING, "Accept retured %d: %s\n", s, strerror(errno));
+ if (errno != EINTR)
+ ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
} else {
for (x=0;x<AST_MAX_CONNECTS;x++) {
if (consoles[x].fd < 0) {
@@ -365,6 +372,8 @@ static void hup_handler(int num)
{
if (option_verbose > 1)
printf("Received HUP signal -- Reloading configs\n");
+ if (restartnow)
+ execvp(_argv[0], _argv);
/* XXX This could deadlock XXX */
ast_module_reload();
}
@@ -436,10 +445,6 @@ static int set_priority(int pri)
return 0;
}
-static char *_argv[256];
-
-static int shuttingdown = 0;
-
static void ast_run_atexits(void)
{
struct ast_atexit *ae;
@@ -536,7 +541,16 @@ static void quit_handler(int num, int nice, int safeshutdown, int restart)
}
if (option_verbose || option_console)
ast_verbose("Restarting Asterisk NOW...\n");
- execvp(_argv[0], _argv);
+ restartnow = 1;
+ /* If there is a consolethread running send it a SIGHUP
+ so it can execvp, otherwise we can do it ourselves */
+ if (consolethread != AST_PTHREADT_NULL) {
+ pthread_kill(consolethread, SIGHUP);
+ /* Give the signal handler some time to complete */
+ sleep(2);
+ } else
+ execvp(_argv[0], _argv);
+
}
exit(0);
}
@@ -546,8 +560,6 @@ static void __quit_handler(int num)
quit_handler(num, 0, 1, 0);
}
-static pthread_t consolethread = (pthread_t) -1;
-
static const char *fix_header(char *outbuf, int maxout, const char *s, char *cmp)
{
const char *c;
@@ -579,7 +591,7 @@ static void console_verboser(const char *s, int pos, int replace, int complete)
fflush(stdout);
if (complete)
/* Wake up a select()ing console */
- if (consolethread != (pthread_t) -1)
+ if (option_console && consolethread != AST_PTHREADT_NULL)
pthread_kill(consolethread, SIGURG);
}
@@ -928,7 +940,7 @@ static char *cli_complete(EditLine *el, int ch)
int nummatches = 0;
char **matches;
int retval = CC_ERROR;
- char buf[1024];
+ char buf[2048];
int res;
LineInfo *lf = (LineInfo *)el_line(el);
@@ -1036,6 +1048,8 @@ static int ast_el_initialize(void)
el_set(el, EL_BIND, "^I", "ed-complete", NULL);
/* Bind ? to command completion */
el_set(el, EL_BIND, "?", "ed-complete", NULL);
+ /* Bind ^D to redisplay */
+ el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
return 0;
}
@@ -1254,7 +1268,7 @@ int main(int argc, char *argv[])
if (gethostname(hostname, sizeof(hostname)))
strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
- mainpid = getpid();
+ ast_mainpid = getpid();
ast_ulaw_init();
ast_alaw_init();
callerid_init();
@@ -1462,6 +1476,8 @@ int main(int argc, char *argv[])
ast_verbose(" ]\n");
if (option_verbose || option_console)
ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
+ if (option_nofork)
+ consolethread = pthread_self();
fully_booted = 1;
pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
#ifdef __AST_DEBUG_MALLOC
@@ -1481,11 +1497,10 @@ int main(int argc, char *argv[])
/* Register our quit function */
char title[256];
set_icon("Asterisk");
- snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, mainpid);
+ snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, ast_mainpid);
set_title(title);
ast_cli_register(&quit);
ast_cli_register(&astexit);
- consolethread = pthread_self();
for (;;) {
buf = (char *)el_gets(el, &num);
diff --git a/astman/astman.c b/astman/astman.c
index f7ce241ac..5ed355265 100755
--- a/astman/astman.c
+++ b/astman/astman.c
@@ -170,6 +170,7 @@ static struct event {
{ "Status", event_status },
{ "Link", event_ignore },
{ "Unlink", event_ignore },
+ { "StatusComplete", event_ignore }
};
static int process_message(struct ast_mansession *s, struct message *m)
diff --git a/autoservice.c b/autoservice.c
index 7e5699b97..3f24db8c1 100755
--- a/autoservice.c
+++ b/autoservice.c
@@ -44,7 +44,7 @@ struct asent {
};
static struct asent *aslist = NULL;
-static pthread_t asthread = (pthread_t) -1;
+static pthread_t asthread = AST_PTHREADT_NULL;
static void *autoservice_run(void *ign)
{
@@ -80,7 +80,7 @@ static void *autoservice_run(void *ign)
ast_frfree(f);
}
}
- asthread = (pthread_t) -1;
+ asthread = AST_PTHREADT_NULL;
return NULL;
}
@@ -90,7 +90,7 @@ int ast_autoservice_start(struct ast_channel *chan)
struct asent *as;
int needstart;
ast_mutex_lock(&autolock);
- needstart = (asthread == (pthread_t) -1) ? 1 : 0 /* aslist ? 0 : 1 */;
+ needstart = (asthread == AST_PTHREADT_NULL) ? 1 : 0 /* aslist ? 0 : 1 */;
as = aslist;
while(as) {
if (as->chan == chan)
@@ -142,7 +142,7 @@ int ast_autoservice_stop(struct ast_channel *chan)
if (!chan->_softhangup)
res = 0;
}
- if (asthread != (pthread_t) -1)
+ if (asthread != AST_PTHREADT_NULL)
pthread_kill(asthread, SIGURG);
ast_mutex_unlock(&autolock);
/* Wait for it to un-block */
diff --git a/channel.c b/channel.c
index ee971f8cd..f946f2a21 100755
--- a/channel.c
+++ b/channel.c
@@ -630,8 +630,8 @@ int ast_hangup(struct ast_channel *chan)
/* If this channel is one which will be masqueraded into something,
mark it as a zombie already, so we know to free it later */
if (chan->masqr) {
- ast_mutex_unlock(&chan->lock);
chan->zombie=1;
+ ast_mutex_unlock(&chan->lock);
return 0;
}
free_translation(chan);
@@ -733,7 +733,8 @@ int ast_answer(struct ast_channel *chan)
void ast_deactivate_generator(struct ast_channel *chan)
{
if (chan->generatordata) {
- chan->generator->release(chan, chan->generatordata);
+ if (chan->generator && chan->generator->release)
+ chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
chan->generator = NULL;
chan->writeinterrupt = 0;
@@ -743,7 +744,8 @@ void ast_deactivate_generator(struct ast_channel *chan)
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
{
if (chan->generatordata) {
- chan->generator->release(chan, chan->generatordata);
+ if (chan->generator && chan->generator->release)
+ chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
}
ast_prod(chan);
@@ -809,15 +811,26 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
fd_set rfds, efds;
int res;
int x, y, max=-1;
+ time_t now = 0;
+ long whentohangup = 0, havewhen = 0, diff;
struct ast_channel *winner = NULL;
if (outfd)
- *outfd = -1;
+ *outfd = -99999;
if (exception)
*exception = 0;
/* Perform any pending masquerades */
for (x=0;x<n;x++) {
ast_mutex_lock(&c[x]->lock);
+ if (c[x]->whentohangup) {
+ if (!havewhen)
+ time(&now);
+ diff = c[x]->whentohangup - now;
+ if (!havewhen || (diff < whentohangup)) {
+ havewhen++;
+ whentohangup = diff;
+ }
+ }
if (c[x]->masq) {
if (ast_do_masquerade(c[x])) {
ast_log(LOG_WARNING, "Masquerade failed\n");
@@ -831,6 +844,13 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
tv.tv_sec = *ms / 1000;
tv.tv_usec = (*ms % 1000) * 1000;
+
+ if (havewhen) {
+ if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
+ tv.tv_sec = whentohangup;
+ tv.tv_usec = 0;
+ }
+ }
FD_ZERO(&rfds);
FD_ZERO(&efds);
@@ -851,7 +871,7 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
if (fds[x] > max)
max = fds[x];
}
- if (*ms >= 0)
+ if ((*ms >= 0) || (havewhen))
res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
else
res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
@@ -871,8 +891,15 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds,
return NULL;
}
+ if (havewhen)
+ time(&now);
for (x=0;x<n;x++) {
c[x]->blocking = 0;
+ if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
+ c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
+ if (!winner)
+ winner = c[x];
+ }
for (y=0;y<AST_MAX_FDS;y++) {
if (c[x]->fds[y] > -1) {
if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) {
@@ -1551,6 +1578,8 @@ struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, i
state = f->subclass;
ast_frfree(f);
break;
+ } else if (f->subclass == -1) {
+ /* Ignore -- just stopping indications */
} else {
ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
}
@@ -2087,19 +2116,6 @@ static int ast_do_masquerade(struct ast_channel *original)
/* Context, extension, priority, app data, jump table, remain the same */
/* pvt switches. pbx stays the same, as does next */
- /* Now, at this point, the "clone" channel is totally F'd up. We mark it as
- a zombie so nothing tries to touch it. If it's already been marked as a
- zombie, then free it now (since it already is considered invalid). */
- if (clone->zombie) {
- ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name);
- ast_mutex_unlock(&clone->lock);
- ast_channel_free(clone);
- manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn);
- } else {
- ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
- clone->zombie=1;
- ast_mutex_unlock(&clone->lock);
- }
/* Set the write format */
ast_set_write_format(original, wformat);
@@ -2120,6 +2136,21 @@ static int ast_do_masquerade(struct ast_channel *original)
} else
ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)! Bad things may happen.\n",
original->type, original->name);
+
+ /* Now, at this point, the "clone" channel is totally F'd up. We mark it as
+ a zombie so nothing tries to touch it. If it's already been marked as a
+ zombie, then free it now (since it already is considered invalid). */
+ if (clone->zombie) {
+ ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name);
+ ast_mutex_unlock(&clone->lock);
+ ast_channel_free(clone);
+ manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn);
+ } else {
+ ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
+ clone->zombie=1;
+ ast_mutex_unlock(&clone->lock);
+ }
+
/* Signal any blocker */
if (original->blocking)
pthread_kill(original->blocker, SIGURG);
@@ -2276,7 +2307,7 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
*fo = f;
*rc = who;
res = 0;
- ast_log(LOG_DEBUG, "Got a FRAME_CONTROL frame on channel %s\n",who->name);
+ ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
break;
}
if ((f->frametype == AST_FRAME_VOICE) ||
@@ -2492,3 +2523,36 @@ int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, i
return 0;
}
+unsigned int ast_get_group(char *s)
+{
+ char *copy;
+ char *piece;
+ char *c=NULL;
+ int start=0, finish=0,x;
+ unsigned int group = 0;
+ copy = ast_strdupa(s);
+ if (!copy) {
+ ast_log(LOG_ERROR, "Out of memory\n");
+ return 0;
+ }
+ c = copy;
+
+ while((piece = strsep(&c, ","))) {
+ if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
+ /* Range */
+ } else if (sscanf(piece, "%d", &start)) {
+ /* Just one */
+ finish = start;
+ } else {
+ ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'. Using '0'\n", s,piece);
+ return 0;
+ }
+ for (x=start;x<=finish;x++) {
+ if ((x > 31) || (x < 0)) {
+ ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x);
+ } else
+ group |= (1 << x);
+ }
+ }
+ return group;
+}
diff --git a/channels/Makefile b/channels/Makefile
index 1d04f11d3..8f0640c9c 100755
--- a/channels/Makefile
+++ b/channels/Makefile
@@ -14,14 +14,21 @@
OSARCH=$(shell uname -s)
USE_MYSQL_FRIENDS=0
+USE_SIP_MYSQL_FRIENDS=0
-CHANNEL_LIBS=chan_modem.so chan_iax.so chan_sip.so \
+CHANNEL_LIBS=chan_modem.so chan_sip.so \
chan_modem_aopen.so \
chan_modem_bestdata.so chan_modem_i4l.so \
chan_agent.so chan_mgcp.so chan_iax2.so \
chan_local.so chan_skinny.so
#
+# If you really want IAX1 uncomment the following, but it is
+# unmaintained
+#
+#CHANNEL_LIBS+=chan_iax.so
+
+#
# If you really want VoFR you can have it :-P
#
#CHANNEL_LIBS+=chan_vofr
@@ -43,6 +50,7 @@ ZAPPRI=$(shell [ -f /usr/lib/libpri.so.1 ] && echo "-lpri")
ZAPR2=$(shell [ -f /usr/lib/libmfcr2.so.1 ] && echo "-lmfcr2")
CFLAGS+=$(shell [ -f /usr/include/linux/zaptel.h ] && echo "-DIAX_TRUNKING")
CHANNEL_LIBS+=$(shell [ -f /usr/include/vpbapi.h ] && echo "chan_vpb.so" )
+CFLAGS+=$(shell [ -f /usr/include/vpbapi.h ] && echo " -DLINUX")
ALSA_SRC=chan_alsa.c
ALSA_SRC+=$(shell [ -f alsa-monitor.h ] && echo "alsa-monitor.h")
@@ -53,6 +61,9 @@ CFLAGS+=-fPIC
ifeq ($(USE_MYSQL_FRIENDS),1)
CFLAGS+=-DMYSQL_FRIENDS
endif
+ifeq ($(USE_SIP_MYSQL_FRIENDS),1)
+CFLAGS+=-DSIP_MYSQL_FRIENDS
+endif
CFLAGS+=#-DVOFRDUMPER
@@ -106,7 +117,7 @@ endif
chan_iax2.so: chan_iax2.o iax2-parser.o
ifeq ($(USE_MYSQL_FRIENDS),1)
- $(CC) $(SOLINK) -o $@ chan_iax2.o iax2-parser.o -lmysqlclient -lz
+ $(CC) $(SOLINK) -o $@ chan_iax2.o iax2-parser.o -L/usr/lib/mysql -lmysqlclient -lz
else
$(CC) $(SOLINK) -o $@ chan_iax2.o iax2-parser.o
endif
@@ -155,6 +166,7 @@ chan_h323.so: chan_h323.o h323/libchanh323.a
install: all
for x in $(CHANNEL_LIBS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
+ if ! [ -f chan_iax.so ]; then rm -f $(DESTDIR)$(MODULES_DIR)/chan_iax.so ; fi
depend: .depend
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index 90734a61b..cdafe58ae 100755
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -87,12 +87,12 @@ static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
/* Protect the interface list (of sip_pvt's) */
static ast_mutex_t agentlock = AST_MUTEX_INITIALIZER;
-int recordagentcalls = 0;
-char recordformat[AST_MAX_BUF];
-char recordformatext[AST_MAX_BUF];
-int createlink = 0;
-char urlprefix[AST_MAX_BUF];
-char savecallsin[AST_MAX_BUF];
+static int recordagentcalls = 0;
+static char recordformat[AST_MAX_BUF];
+static char recordformatext[AST_MAX_BUF];
+static int createlink = 0;
+static char urlprefix[AST_MAX_BUF];
+static char savecallsin[AST_MAX_BUF];
static struct agent_pvt {
ast_mutex_t lock; /* Channel private lock */
@@ -337,7 +337,7 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
}
CLEANUP(ast,p);
ast_mutex_unlock(&p->lock);
- if (f == &answer_frame)
+ if (recordagentcalls && f == &answer_frame)
agent_start_monitoring(ast,0);
return f;
}
@@ -467,7 +467,8 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
ast_setstate(ast, AST_STATE_RINGING);
else {
ast_setstate(ast, AST_STATE_UP);
- agent_start_monitoring(ast,0);
+ if (recordagentcalls)
+ agent_start_monitoring(ast,0);
p->acknowledged = 1;
}
res = 0;
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 112a20b27..4a5f8251c 100755
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -26,7 +26,11 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#define ALSA_PCM_NEW_SW_PARAMS_API
#include <alsa/asoundlib.h>
+
#include "busy.h"
#include "ringtone.h"
#include "ring10.h"
@@ -316,14 +320,15 @@ static void *sound_thread(void *unused)
static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
{
int err;
+ int direction;
snd_pcm_t *handle = NULL;
snd_pcm_hw_params_t *hwparams = NULL;
snd_pcm_sw_params_t *swparams = NULL;
struct pollfd pfd;
- int period_size = PERIOD_FRAMES * 4;
+ snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4;
//int period_bytes = 0;
- int buffer_size = 0;
-
+ snd_pcm_uframes_t buffer_size = 0;
+
unsigned int rate = DESIRED_RATE;
unsigned int per_min = 1;
//unsigned int per_max = 8;
@@ -355,35 +360,35 @@ static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err));
}
- rate = snd_pcm_hw_params_set_rate_near(handle, hwparams, rate, 0);
-
+ direction = 0;
+ err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction);
if (rate != DESIRED_RATE) {
ast_log(LOG_WARNING, "Rate not correct, requested %d, got %d\n", DESIRED_RATE, rate);
}
- err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, period_size, 0);
+ direction = 0;
+ err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction);
if (err < 0) {
- ast_log(LOG_ERROR, "period_size(%d frames) is bad: %s\n", period_size, snd_strerror(err));
+ ast_log(LOG_ERROR, "period_size(%ld frames) is bad: %s\n", period_size, snd_strerror(err));
} else {
ast_log(LOG_DEBUG, "Period size is %d\n", err);
}
- period_size = err;
buffer_size = 4096 * 2; //period_size * 16;
- err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, buffer_size);
+ err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
if (err < 0) {
- ast_log(LOG_WARNING, "Problem setting buffer size of %d: %s\n", buffer_size, snd_strerror(err));
+ ast_log(LOG_WARNING, "Problem setting buffer size of %ld: %s\n", buffer_size, snd_strerror(err));
} else {
ast_log(LOG_DEBUG, "Buffer size is set to %d frames\n", err);
}
- buffer_size = err;
- err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, 0);
+#if 0
+ direction = 0;
+ err = snd_pcm_hw_params_set_periods_min(handle, hwparams, &per_min, &direction);
if (err < 0) {
ast_log(LOG_ERROR, "periods_min: %s\n", snd_strerror(err));
}
-#if 0
err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &per_max, 0);
if (err < 0) {
ast_log(LOG_ERROR, "periods_max: %s\n", snd_strerror(err));
@@ -429,11 +434,12 @@ static snd_pcm_t *alsa_card_init(char *dev, snd_pcm_stream_t stream)
}
#endif
+#if 0
err = snd_pcm_sw_params_set_silence_threshold(handle, swparams, silencethreshold);
if (err < 0) {
ast_log(LOG_ERROR, "Unable to set silence threshold: %s\n", snd_strerror(err));
}
-
+#endif
err = snd_pcm_sw_params(handle, swparams);
if (err < 0) {
ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err));
@@ -788,7 +794,7 @@ static int alsa_indicate(struct ast_channel *chan, int cond)
static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
{
struct ast_channel *tmp;
- tmp = ast_channel_alloc(0);
+ tmp = ast_channel_alloc(1);
if (tmp) {
snprintf(tmp->name, sizeof(tmp->name), "ALSA/%s", indevname);
tmp->type = type;
@@ -943,8 +949,9 @@ static int console_hangup(int fd, int argc, char *argv[])
return RESULT_FAILURE;
}
hookstate = 0;
- if (alsa.owner)
- needhangup++;
+ if (alsa.owner) {
+ ast_queue_hangup(alsa.owner, 1);
+ }
return RESULT_SUCCESS;
}
@@ -988,7 +995,7 @@ static int console_dial(int fd, int argc, char *argv[])
strncpy(alsa.exten, mye, sizeof(alsa.exten)-1);
strncpy(alsa.context, myc, sizeof(alsa.context)-1);
hookstate = 1;
- alsa_new(&alsa, AST_STATE_UP);
+ alsa_new(&alsa, AST_STATE_RINGING);
} else
ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
return RESULT_SUCCESS;
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index 4077ea614..45f0a0c4d 100755
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -148,7 +148,7 @@ static ast_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. */
-static pthread_t monitor_thread = 0;
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
static int restart_monitor(void);
@@ -1259,7 +1259,7 @@ restartsearch:
static int restart_monitor(void)
{
/* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == -2)
+ if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
@@ -1270,7 +1270,7 @@ static int restart_monitor(void)
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
- if (monitor_thread && (monitor_thread != -2)) {
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) {
/* Wake up the thread */
pthread_kill(monitor_thread, SIGURG);
} else {
@@ -1839,12 +1839,12 @@ int unload_module()
}
if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread && (monitor_thread != -2)) {
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
pthread_cancel(monitor_thread);
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
- monitor_thread = (pthread_t) -2;
+ monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
diff --git a/channels/chan_iax.c b/channels/chan_iax.c
index fc6ef0ff5..7839f2c3d 100755
--- a/channels/chan_iax.c
+++ b/channels/chan_iax.c
@@ -149,7 +149,7 @@ static int iaxdebug = 0;
static char accountcode[20];
static int amaflags = 0;
-static pthread_t netthreadid;
+static pthread_t netthreadid = AST_PTHREADT_NULL;
#define IAX_STATE_STARTED (1 << 0)
#define IAX_STATE_AUTHENTICATED (1 << 1)
@@ -3686,7 +3686,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
|| (f.subclass == AST_IAX_COMMAND_POKE)))
new = NEW_ALLOW;
} else {
- /* Don't knwo anything about it yet */
+ /* Don't know anything about it yet */
f.frametype = AST_FRAME_NULL;
f.subclass = 0;
}
@@ -5344,8 +5344,10 @@ static int __unload_module(void)
{
int x;
/* Cancel the network thread, close the net socket */
- pthread_cancel(netthreadid);
- pthread_join(netthreadid, NULL);
+ if (netthreadid != AST_PTHREADT_NULL) {
+ pthread_cancel(netthreadid);
+ pthread_join(netthreadid, NULL);
+ }
close(netsocket);
for (x=0;x<AST_IAX_MAX_CALLS;x++)
if (iaxs[x])
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 8ffd12037..9b549d0ec 100755
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -49,6 +49,7 @@
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
+#include <sys/stat.h>
#ifdef IAX_TRUNKING
#include <sys/ioctl.h>
#include <linux/zaptel.h>
@@ -71,6 +72,8 @@
#define BRIDGE_OPTIMIZATION
+#define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
+#define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
#define DEFAULT_RETRY_TIME 1000
#define MEMORY_SIZE 100
@@ -164,7 +167,7 @@ static char accountcode[20];
static int amaflags = 0;
static int notransfer = 0;
-static pthread_t netthreadid;
+static pthread_t netthreadid = AST_PTHREADT_NULL;
#define IAX_STATE_STARTED (1 << 0)
#define IAX_STATE_AUTHENTICATED (1 << 1)
@@ -480,7 +483,7 @@ static struct timeval lastused[IAX_MAX_CALLS];
static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
-static int send_command_locked(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
+static int send_command_locked(unsigned short callno, char, int, unsigned int, char *, int, int);
static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, char *, int);
@@ -1038,9 +1041,11 @@ retry:
goto retry;
}
}
- iaxs[callno] = NULL;
+ if (!owner)
+ iaxs[callno] = NULL;
if (pvt) {
- pvt->owner = NULL;
+ if (!owner)
+ pvt->owner = NULL;
/* No more pings or lagrq's */
if (pvt->pingid > -1)
ast_sched_del(sched, pvt->pingid);
@@ -1063,7 +1068,6 @@ retry:
if (owner) {
/* If there's an owner, prod it to give up */
- owner->pvt->pvt = NULL;
owner->_softhangup |= AST_SOFTHANGUP_DEV;
ast_queue_hangup(owner, 0);
}
@@ -1076,7 +1080,8 @@ retry:
if (pvt->reg) {
pvt->reg->callno = 0;
}
- free(pvt);
+ if (!owner)
+ free(pvt);
}
if (owner) {
ast_mutex_unlock(&owner->lock);
@@ -1497,30 +1502,35 @@ static int iax2_transmit(struct iax_frame *fr)
static int iax2_digit(struct ast_channel *c, char digit)
{
- return send_command_locked(c->pvt->pvt, AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
+ return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
}
static int iax2_sendtext(struct ast_channel *c, char *text)
{
- return send_command_locked(c->pvt->pvt, AST_FRAME_TEXT,
+ return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_TEXT,
0, 0, text, strlen(text) + 1, -1);
}
static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
{
- return send_command_locked(c->pvt->pvt, AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
+ return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
}
static int iax2_sendhtml(struct ast_channel *c, int subclass, char *data, int datalen)
{
- return send_command_locked(c->pvt->pvt, AST_FRAME_HTML, subclass, 0, data, datalen, -1);
+ return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_HTML, subclass, 0, data, datalen, -1);
}
static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
{
- struct chan_iax2_pvt *pvt = newchan->pvt->pvt;
- pvt->owner = newchan;
+ unsigned short callno = PTR_TO_CALLNO(newchan->pvt->pvt);
+ ast_mutex_lock(&iaxsl[callno]);
+ if (iaxs[callno])
+ iaxs[callno]->owner = newchan;
+ else
+ ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
+ ast_mutex_unlock(&iaxsl[callno]);
return 0;
}
@@ -1593,6 +1603,8 @@ static struct iax2_peer *mysql_peer(char *peer)
if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE)
memset(&p->addr, 0, sizeof(p->addr));
}
+ mysql_free_result(result);
+ result = NULL;
}
ast_mutex_unlock(&mysqllock);
}
@@ -1648,6 +1660,8 @@ static struct iax2_user *mysql_user(char *user)
}
}
}
+ mysql_free_result(result);
+ result = NULL;
}
ast_mutex_unlock(&mysqllock);
}
@@ -1741,7 +1755,7 @@ static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, i
static int auto_congest(void *nothing)
{
- int callno = (int)(long)(nothing);
+ int callno = PTR_TO_CALLNO(nothing);
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
ast_mutex_lock(&iaxsl[callno]);
if (iaxs[callno]) {
@@ -1785,7 +1799,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
char context[AST_MAX_EXTENSION] ="";
char *portno = NULL;
char *opts = "";
- struct chan_iax2_pvt *p = c->pvt->pvt;
+ unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
char *stringp=NULL;
char storedsecret[80];
if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
@@ -1857,7 +1871,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
if (n)
iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
- if (p->sendani && c->ani) {
+ if (iaxs[callno]->sendani && c->ani) {
l = n = NULL;
strncpy(cid, c->ani, sizeof(cid) - 1);
ast_callerid_parse(cid, &n, &l);
@@ -1876,18 +1890,21 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
iax_ie_append_str(&ied, IAX_IE_USERNAME, username);
if (!secret && strlen(storedsecret))
secret = storedsecret;
+ ast_mutex_lock(&iaxsl[callno]);
+ if (strlen(c->context))
+ strncpy(iaxs[callno]->context, c->context, sizeof(iaxs[callno]->context));
if (secret) {
if (secret[0] == '[') {
/* This is an RSA key, not a normal secret */
- strncpy(p->outkey, secret + 1, sizeof(p->secret)-1);
- if (strlen(p->outkey)) {
- p->outkey[strlen(p->outkey) - 1] = '\0';
+ strncpy(iaxs[callno]->outkey, secret + 1, sizeof(iaxs[callno]->secret)-1);
+ if (strlen(iaxs[callno]->outkey)) {
+ iaxs[callno]->outkey[strlen(iaxs[callno]->outkey) - 1] = '\0';
}
} else
- strncpy(p->secret, secret, sizeof(p->secret)-1);
+ strncpy(iaxs[callno]->secret, secret, sizeof(iaxs[callno]->secret)-1);
}
iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
- iax_ie_append_int(&ied, IAX_IE_CAPABILITY, p->capability);
+ iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime());
/* Transmit the string in a "NEW" request */
@@ -1896,30 +1913,29 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Calling using options '%s'\n", requeststr);
#endif
- if (p->maxtime) {
+ if (iaxs[callno]->maxtime) {
/* Initialize pingtime and auto-congest time */
- p->pingtime = p->maxtime / 2;
- p->initid = ast_sched_add(sched, p->maxtime * 2, auto_congest, (void *)(long)p->callno);
+ iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
+ iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
}
- send_command_locked(p, AST_FRAME_IAX,
+ send_command(iaxs[callno], AST_FRAME_IAX,
IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
+ ast_mutex_unlock(&iaxsl[callno]);
ast_setstate(c, AST_STATE_RINGING);
return 0;
}
static int iax2_hangup(struct ast_channel *c)
{
- struct chan_iax2_pvt *pvt = c->pvt->pvt;
+ unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
int alreadygone;
- int callno;
- if (pvt) {
- callno = pvt->callno;
- ast_mutex_lock(&iaxsl[callno]);
+ ast_mutex_lock(&iaxsl[callno]);
+ if (callno && iaxs[callno]) {
ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
- alreadygone = pvt->alreadygone;
+ alreadygone = iaxs[callno]->alreadygone;
/* Send the hangup unless we have had a transmission error or are already gone */
- if (!pvt->error && !alreadygone)
- send_command_final(pvt, AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, NULL, 0, -1);
+ if (!iaxs[callno]->error && !alreadygone)
+ send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, NULL, 0, -1);
/* Explicitly predestroy it */
iax2_predestroy_nolock(callno);
/* If we were already gone to begin with, destroy us now */
@@ -1927,8 +1943,8 @@ static int iax2_hangup(struct ast_channel *c)
ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
iax2_destroy_nolock(callno);
}
- ast_mutex_unlock(&iaxsl[callno]);
}
+ ast_mutex_unlock(&iaxsl[callno]);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
return 0;
@@ -1943,7 +1959,7 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat
h->flag = AST_OPTION_FLAG_REQUEST;
h->option = htons(option);
memcpy(h->data, data, datalen);
- res = send_command_locked((struct chan_iax2_pvt *)c->pvt->pvt, AST_FRAME_CONTROL,
+ res = send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_CONTROL,
AST_CONTROL_OPTION, 0, (char *)h, datalen + sizeof(struct ast_option_header), -1);
free(h);
return res;
@@ -1951,6 +1967,7 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
+
static struct ast_frame *iax2_read(struct ast_channel *c)
{
static struct ast_frame f = { AST_FRAME_NULL, };
@@ -1958,49 +1975,47 @@ static struct ast_frame *iax2_read(struct ast_channel *c)
return &f;
}
-static int iax2_start_transfer(struct ast_channel *c0, struct ast_channel *c1)
+static int iax2_start_transfer(unsigned short callno0, unsigned short callno1)
{
int res;
struct iax_ie_data ied0;
struct iax_ie_data ied1;
- struct chan_iax2_pvt *p0 = c0->pvt->pvt;
- struct chan_iax2_pvt *p1 = c1->pvt->pvt;
unsigned int transferid = rand();
memset(&ied0, 0, sizeof(ied0));
- iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &p1->addr);
- iax_ie_append_short(&ied0, IAX_IE_CALLNO, p1->peercallno);
+ iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
+ iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &p0->addr);
- iax_ie_append_short(&ied1, IAX_IE_CALLNO, p0->peercallno);
+ iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
+ iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
- res = send_command(p0, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
+ res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
if (res)
return -1;
- res = send_command(p1, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
+ res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
if (res)
return -1;
- p0->transferring = TRANSFER_BEGIN;
- p1->transferring = TRANSFER_BEGIN;
+ iaxs[callno0]->transferring = TRANSFER_BEGIN;
+ iaxs[callno1]->transferring = TRANSFER_BEGIN;
return 0;
}
-static void lock_both(struct chan_iax2_pvt *p0, struct chan_iax2_pvt *p1)
+static void lock_both(unsigned short callno0, unsigned short callno1)
{
- ast_mutex_lock(&iaxsl[p0->callno]);
- while (ast_mutex_trylock(&iaxsl[p1->callno])) {
- ast_mutex_unlock(&iaxsl[p0->callno]);
+ ast_mutex_lock(&iaxsl[callno0]);
+ while (ast_mutex_trylock(&iaxsl[callno1])) {
+ ast_mutex_unlock(&iaxsl[callno0]);
usleep(10);
- ast_mutex_lock(&iaxsl[p0->callno]);
+ ast_mutex_lock(&iaxsl[callno0]);
}
}
-static void unlock_both(struct chan_iax2_pvt *p0, struct chan_iax2_pvt *p1)
+static void unlock_both(unsigned short callno0, unsigned short callno1)
{
- ast_mutex_unlock(&iaxsl[p1->callno]);
- ast_mutex_unlock(&iaxsl[p0->callno]);
+ ast_mutex_unlock(&iaxsl[callno1]);
+ ast_mutex_unlock(&iaxsl[callno0]);
}
static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
@@ -2011,15 +2026,15 @@ static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
int res = -1;
int transferstarted=0;
struct ast_frame *f;
- struct chan_iax2_pvt *p0 = c0->pvt->pvt;
- struct chan_iax2_pvt *p1 = c1->pvt->pvt;
+ unsigned short callno0 = PTR_TO_CALLNO(c0->pvt->pvt);
+ unsigned short callno1 = PTR_TO_CALLNO(c1->pvt->pvt);
struct timeval waittimer = {0, 0}, tv;
- lock_both(p0, p1);
+ lock_both(callno0, callno1);
/* Put them in native bridge mode */
- p0->bridgecallno = p1->callno;
- p1->bridgecallno = p0->callno;
- unlock_both(p0, p1);
+ iaxs[callno0]->bridgecallno = callno1;
+ iaxs[callno1]->bridgecallno = callno0;
+ unlock_both(callno0, callno1);
/* If not, try to bridge until we can execute a transfer, if we can */
cs[0] = c0;
@@ -2031,34 +2046,34 @@ static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
/* Remove from native mode */
if (c0->type == type) {
- ast_mutex_lock(&iaxsl[p0->callno]);
- p0->bridgecallno = 0;
- ast_mutex_unlock(&iaxsl[p0->callno]);
+ ast_mutex_lock(&iaxsl[callno0]);
+ iaxs[callno0]->bridgecallno = 0;
+ ast_mutex_unlock(&iaxsl[callno0]);
}
if (c1->type == type) {
- ast_mutex_lock(&iaxsl[p1->callno]);
- p1->bridgecallno = 0;
- ast_mutex_unlock(&iaxsl[p1->callno]);
+ ast_mutex_lock(&iaxsl[callno1]);
+ iaxs[callno1]->bridgecallno = 0;
+ ast_mutex_unlock(&iaxsl[callno1]);
}
return -2;
}
if (c0->nativeformats != c1->nativeformats) {
ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs, can't native bridge...\n");
/* Remove from native mode */
- lock_both(p0, p1);
- p0->bridgecallno = 0;
- p1->bridgecallno = 0;
- unlock_both(p0, p1);
+ lock_both(callno0, callno1);
+ iaxs[callno0]->bridgecallno = 0;
+ iaxs[callno1]->bridgecallno = 0;
+ unlock_both(callno0, callno1);
return -2;
}
/* check if transfered and if we really want native bridging */
- if (!transferstarted && !p0->notransfer && !p1->notransfer) {
+ if (!transferstarted && !iaxs[callno0]->notransfer && !iaxs[callno1]->notransfer) {
/* Try the transfer */
- if (iax2_start_transfer(c0, c1))
+ if (iax2_start_transfer(callno0, callno1))
ast_log(LOG_WARNING, "Unable to start the transfer\n");
transferstarted = 1;
}
- if ((p0->transferring == TRANSFER_RELEASED) && (p1->transferring == TRANSFER_RELEASED)) {
+ if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
/* Call has been transferred. We're no longer involved */
gettimeofday(&tv, NULL);
if (!waittimer.tv_sec && !waittimer.tv_usec) {
@@ -2144,32 +2159,32 @@ tackygoto:
cs[0] = cs[1];
cs[1] = cs[2];
}
- lock_both(p0, p1);
- p0->bridgecallno = 0;
- p1->bridgecallno = 0;
- unlock_both(p0, p1);
+ lock_both(callno0, callno1);
+ iaxs[callno0]->bridgecallno = 0;
+ iaxs[callno1]->bridgecallno = 0;
+ unlock_both(callno0, callno1);
return res;
}
static int iax2_answer(struct ast_channel *c)
{
- struct chan_iax2_pvt *pvt = c->pvt->pvt;
+ unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
if (option_debug)
ast_log(LOG_DEBUG, "Answering\n");
- return send_command(pvt, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
+ return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
}
static int iax2_indicate(struct ast_channel *c, int condition)
{
- struct chan_iax2_pvt *pvt = c->pvt->pvt;
+ unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
if (option_debug)
ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
- return send_command(pvt, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
+ return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
}
static int iax2_transfer(struct ast_channel *c, char *dest)
{
- struct chan_iax2_pvt *pvt = c->pvt->pvt;
+ unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
struct iax_ie_data ied;
char tmp[256] = "", *context;
strncpy(tmp, dest, sizeof(tmp) - 1);
@@ -2184,7 +2199,7 @@ static int iax2_transfer(struct ast_channel *c, char *dest)
iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
if (option_debug)
ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
- return send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
+ return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
}
@@ -2222,7 +2237,7 @@ static struct ast_channel *ast_iax2_new(struct chan_iax2_pvt *i, int state, int
tmp->nativeformats = capability;
tmp->readformat = 0;
tmp->writeformat = 0;
- tmp->pvt->pvt = i;
+ tmp->pvt->pvt = CALLNO_TO_PTR(i->callno);
tmp->pvt->send_digit = iax2_digit;
tmp->pvt->send_text = iax2_sendtext;
tmp->pvt->send_image = iax2_sendimage;
@@ -2763,27 +2778,31 @@ static struct ast_cli_entry cli_no_debug =
static int iax2_write(struct ast_channel *c, struct ast_frame *f)
{
- struct chan_iax2_pvt *i = c->pvt->pvt;
- if (!i)
- return -1;
+ unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
+ int res = -1;
+ ast_mutex_lock(&iaxsl[callno]);
+ if (iaxs[callno]) {
/* If there's an outstanding error, return failure now */
- if (i->error) {
- ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
- return -1;
+ if (!iaxs[callno]->error) {
+ if (iaxs[callno]->alreadygone)
+ res = 0;
+ /* Don't waste bandwidth sending null frames */
+ else if (f->frametype == AST_FRAME_NULL)
+ res = 0;
+ else if ((f->frametype == AST_FRAME_VOICE) && iaxs[callno]->quelch)
+ res = 0;
+ else if (!(iaxs[callno]->state & IAX_STATE_STARTED))
+ res = 0;
+ else
+ /* Simple, just queue for transmission */
+ res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
+ } else {
+ ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
+ }
}
/* If it's already gone, just return */
- if (i->alreadygone)
- return 0;
- /* Don't waste bandwidth sending null frames */
- if (f->frametype == AST_FRAME_NULL)
- return 0;
- /* If we're quelching voice, don't bother sending it */
- if ((f->frametype == AST_FRAME_VOICE) && i->quelch)
- return 0;
- if (!(i->state & IAX_STATE_STARTED))
- return 0;
- /* Simple, just queue for transmission */
- return iax2_send(i, f, 0, -1, 0, 0, 0);
+ ast_mutex_unlock(&iaxsl[callno]);
+ return res;
}
static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno,
@@ -2806,12 +2825,12 @@ static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigne
return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
}
-static int send_command_locked(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno)
+static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, char *data, int datalen, int seqno)
{
int res;
- ast_mutex_lock(&iaxsl[i->callno]);
- res = send_command(i, type, command, ts, data, datalen, seqno);
- ast_mutex_unlock(&iaxsl[i->callno]);
+ ast_mutex_lock(&iaxsl[callno]);
+ res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
+ ast_mutex_unlock(&iaxsl[callno]);
return res;
}
@@ -4054,7 +4073,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
fr.callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1);
minivid = 1;
} else if (meta->zeros == 0) {
- /* This is a a meta header */
+ /* This is a meta header */
switch(meta->metacmd) {
case IAX_META_TRUNK:
if (res < sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) {
@@ -4161,7 +4180,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
|| (f.subclass == IAX_COMMAND_POKE)))
new = NEW_ALLOW;
} else {
- /* Don't knwo anything about it yet */
+ /* Don't know anything about it yet */
f.frametype = AST_FRAME_NULL;
f.subclass = 0;
}
@@ -4558,11 +4577,22 @@ retryowner:
iaxs[fr.callno]->owner->nativeformats = iaxs[fr.callno]->peerformat;
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr.callno]->owner->nativeformats));
- /* Setup read/write formats properly. */
- if (iaxs[fr.callno]->owner->writeformat)
- ast_set_write_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->writeformat);
- if (iaxs[fr.callno]->owner->readformat)
- ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat);
+retryowner2:
+ if (ast_mutex_trylock(&iaxs[fr.callno]->owner->lock)) {
+ ast_mutex_unlock(&iaxsl[fr.callno]);
+ usleep(1);
+ ast_mutex_lock(&iaxsl[fr.callno]);
+ if (iaxs[fr.callno] && iaxs[fr.callno]->owner) goto retryowner2;
+ }
+
+ if (iaxs[fr.callno] && iaxs[fr.callno]->owner) {
+ /* Setup read/write formats properly. */
+ if (iaxs[fr.callno]->owner->writeformat)
+ ast_set_write_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->writeformat);
+ if (iaxs[fr.callno]->owner->readformat)
+ ast_set_read_format(iaxs[fr.callno]->owner, iaxs[fr.callno]->owner->readformat);
+ ast_mutex_unlock(&iaxs[fr.callno]->owner->lock);
+ }
}
}
ast_mutex_lock(&dpcache_lock);
@@ -5208,6 +5238,7 @@ static struct iax2_peer *build_peer(char *name, struct ast_variable *v)
{
struct iax2_peer *peer;
struct iax2_peer *prev;
+ struct ast_ha *oldha = NULL;
int maskfound=0;
int format;
int found=0;
@@ -5223,6 +5254,8 @@ static struct iax2_peer *build_peer(char *name, struct ast_variable *v)
}
if (peer) {
found++;
+ oldha = peer->ha;
+ peer->ha = NULL;
/* Already in the list, remove it and it will be added back (or FREE'd) */
if (prev) {
prev->next = peer->next;
@@ -5349,6 +5382,8 @@ static struct iax2_peer *build_peer(char *name, struct ast_variable *v)
if (!found && peer->dynamic)
reg_source_db(peer);
}
+ if (oldha)
+ ast_free_ha(oldha);
return peer;
}
@@ -5356,6 +5391,8 @@ static struct iax2_user *build_user(char *name, struct ast_variable *v)
{
struct iax2_user *prev, *user;
struct iax2_context *con, *conl = NULL;
+ struct ast_ha *oldha = NULL;
+ struct iax2_context *oldcon = NULL;
int format;
int found;
@@ -5371,6 +5408,10 @@ static struct iax2_user *build_user(char *name, struct ast_variable *v)
}
if (user) {
found++;
+ oldha = user->ha;
+ oldcon = user->contexts;
+ user->ha = NULL;
+ user->contexts = NULL;
/* Already in the list, remove it and it will be added back (or FREE'd) */
if (prev) {
prev->next = user->next;
@@ -5456,6 +5497,10 @@ static struct iax2_user *build_user(char *name, struct ast_variable *v)
}
user->delme = 0;
}
+ if (oldha)
+ ast_free_ha(oldha);
+ if (oldcon)
+ free_context(oldcon);
return user;
}
@@ -5497,7 +5542,6 @@ static void prune_users(void)
if (user->delme) {
ast_free_ha(user->ha);
free_context(user->contexts);
- user=user->next;
free(user);
if (userlast)
userlast->next = usernext;
@@ -5519,6 +5563,7 @@ static void prune_peers(void){
for (peer=peerl.peers;peer;) {
peernext = peer->next;
if (peer->delme) {
+ ast_free_ha(peer->ha);
for (x=0;x<IAX_MAX_CALLS;x++) {
ast_mutex_lock(&iaxsl[x]);
if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
@@ -6113,8 +6158,10 @@ static int __unload_module(void)
{
int x;
/* Cancel the network thread, close the net socket */
- pthread_cancel(netthreadid);
- pthread_join(netthreadid, NULL);
+ if (netthreadid != AST_PTHREADT_NULL) {
+ pthread_cancel(netthreadid);
+ pthread_join(netthreadid, NULL);
+ }
close(netsocket);
for (x=0;x<IAX_MAX_CALLS;x++)
if (iaxs[x])
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index d4131c656..91b5c7e59 100755
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -167,7 +167,7 @@ static ast_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. */
-static pthread_t monitor_thread = 0;
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
static int restart_monitor(void);
@@ -2558,7 +2558,7 @@ static int restart_monitor(void)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
/* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == (pthread_t) -2)
+ if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
@@ -2569,7 +2569,7 @@ static int restart_monitor(void)
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
- if (monitor_thread) {
+ if (monitor_thread != AST_PTHREADT_NULL) {
/* Wake up the thread */
pthread_kill(monitor_thread, SIGURG);
} else {
@@ -3052,12 +3052,12 @@ int unload_module()
return -1;
}
if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread && (monitor_thread != -2)) {
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
pthread_cancel(monitor_thread);
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
- monitor_thread = -2;
+ monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
diff --git a/channels/chan_modem.c b/channels/chan_modem.c
index 09451decd..728aa361a 100755
--- a/channels/chan_modem.c
+++ b/channels/chan_modem.c
@@ -83,7 +83,7 @@ static ast_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. */
-static pthread_t monitor_thread = (pthread_t) -1;
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
static int restart_monitor(void);
@@ -646,7 +646,7 @@ static void *do_monitor(void *data)
static int restart_monitor()
{
/* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == (pthread_t) -2)
+ if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
@@ -657,7 +657,7 @@ static int restart_monitor()
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
- if (monitor_thread != (pthread_t) -1) {
+ if (monitor_thread != AST_PTHREADT_NULL) {
pthread_cancel(monitor_thread);
/* Nudge it a little, as it's probably stuck in select */
pthread_kill(monitor_thread, SIGURG);
@@ -861,11 +861,11 @@ static int __unload_module(void)
return -1;
}
if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread != (pthread_t) -1 && monitor_thread != (pthread_t) -2) {
+ if (monitor_thread != AST_PTHREADT_NULL && monitor_thread != AST_PTHREADT_STOP) {
pthread_cancel(monitor_thread);
pthread_join(monitor_thread, NULL);
}
- monitor_thread = (pthread_t) -2;
+ monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
diff --git a/channels/chan_nbs.c b/channels/chan_nbs.c
index cd40ce167..1960acbe2 100755
--- a/channels/chan_nbs.c
+++ b/channels/chan_nbs.c
@@ -149,7 +149,7 @@ static int nbs_hangup(struct ast_channel *ast)
return 0;
}
-static struct ast_frame *nbs_read(struct ast_channel *ast)
+static struct ast_frame *nbs_xread(struct ast_channel *ast)
{
struct nbs_pvt *p = ast->pvt->pvt;
@@ -209,7 +209,7 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state)
tmp->pvt->pvt = i;
tmp->pvt->call = nbs_call;
tmp->pvt->hangup = nbs_hangup;
- tmp->pvt->read = nbs_read;
+ tmp->pvt->read = nbs_xread;
tmp->pvt->write = nbs_xwrite;
strncpy(tmp->context, context, sizeof(tmp->context)-1);
strncpy(tmp->exten, "s", sizeof(tmp->exten) - 1);
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 775734842..5ebe02192 100755
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -67,7 +67,7 @@ static ast_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. */
-static pthread_t monitor_thread = -1;
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
static int restart_monitor(void);
@@ -910,7 +910,7 @@ static void *do_monitor(void *data)
static int restart_monitor()
{
/* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == -2)
+ if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
@@ -921,7 +921,7 @@ static int restart_monitor()
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
- if (monitor_thread != -1) {
+ if (monitor_thread != AST_PTHREADT_NULL) {
pthread_cancel(monitor_thread);
#if 0
pthread_join(monitor_thread, NULL);
@@ -1071,11 +1071,11 @@ static int __unload_module(void)
return -1;
}
if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread > -1) {
+ if (monitor_thread > AST_PTHREADT_NULL) {
pthread_cancel(monitor_thread);
pthread_join(monitor_thread, NULL);
}
- monitor_thread = -2;
+ monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 873bc1dcb..e63d34516 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -54,7 +54,8 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#ifdef MYSQL_FRIENDS
+#ifdef SIP_MYSQL_FRIENDS
+#define MYSQL_FRIENDS
#include <mysql/mysql.h>
#endif
@@ -134,7 +135,7 @@ static ast_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. */
-static pthread_t monitor_thread = 0;
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
static int restart_monitor(void);
@@ -252,6 +253,7 @@ static struct sip_pvt {
char our_contact[256]; /* Our contact header */
char realm[256]; /* Authorization realm */
char nonce[256]; /* Authorization nonce */
+ char opaque[256]; /* Opaque nonsense */
char domain[256]; /* Authorization nonce */
char lastmsg[256]; /* Last Message sent/received */
int amaflags; /* AMA Flags */
@@ -687,17 +689,20 @@ static int sip_sendtext(struct ast_channel *ast, char *text)
#ifdef MYSQL_FRIENDS
-static void mysql_update_peer(char *peer, struct sockaddr_in *sin)
+static void mysql_update_peer(char *peer, struct sockaddr_in *sin, char *username, int expiry)
{
if (mysql && (strlen(peer) < 128)) {
char query[512];
char *name;
+ char *uname;
time_t nowtime;
name = alloca(strlen(peer) * 2 + 1);
+ uname = alloca(strlen(username) * 2 + 1);
time(&nowtime);
mysql_real_escape_string(mysql, name, peer, strlen(peer));
- snprintf(query, sizeof(query), "UPDATE sipfriends SET ipaddr=\"%s\", port=\"%d\", regseconds=\"%ld\" WHERE name=\"%s\"",
- inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), nowtime, name);
+ mysql_real_escape_string(mysql, uname, username, strlen(username));
+ snprintf(query, sizeof(query), "UPDATE sipfriends SET ipaddr=\"%s\", port=\"%d\", regseconds=\"%ld\", username=\"%s\" WHERE name=\"%s\"",
+ inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), nowtime + expiry, uname, name);
ast_mutex_lock(&mysqllock);
if (mysql_real_query(mysql, query, strlen(query)))
ast_log(LOG_WARNING, "Unable to update database\n");
@@ -745,6 +750,8 @@ static struct sip_peer *mysql_peer(char *peer, struct sockaddr_in *sin)
strncpy(p->name, rowval[x], sizeof(p->name) - 1);
} else if (!strcasecmp(fields[x].name, "context")) {
strncpy(p->context, rowval[x], sizeof(p->context) - 1);
+ } else if (!strcasecmp(fields[x].name, "username")) {
+ strncpy(p->username, rowval[x], sizeof(p->username) - 1);
} else if (!strcasecmp(fields[x].name, "ipaddr")) {
inet_aton(rowval[x], &p->addr.sin_addr);
} else if (!strcasecmp(fields[x].name, "port")) {
@@ -758,9 +765,11 @@ static struct sip_peer *mysql_peer(char *peer, struct sockaddr_in *sin)
}
}
time(&nowtime);
- if ((nowtime - regseconds) > default_expiry)
+ if (nowtime > regseconds)
memset(&p->addr, 0, sizeof(p->addr));
}
+ mysql_free_result(result);
+ result = NULL;
}
ast_mutex_unlock(&mysqllock);
}
@@ -853,8 +862,11 @@ static int create_addr(struct sip_pvt *r, char *peer)
r->sa.sin_port = p->defaddr.sin_port;
}
memcpy(&r->recv, &r->sa, sizeof(r->recv));
- } else
+ } else {
+ if (p->temponly)
+ free(p);
p = NULL;
+ }
}
ast_mutex_unlock(&peerl.lock);
if (!p && !found) {
@@ -1029,7 +1041,7 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner)
struct sip_pvt *cur, *prev = NULL;
struct sip_pkt *cp;
if (sipdebug)
- ast_log(LOG_DEBUG, "Destorying call '%s'\n", p->callid);
+ ast_log(LOG_DEBUG, "Destroying call '%s'\n", p->callid);
if (p->stateid > -1)
ast_extension_state_del(p->stateid, NULL);
if (p->initid > -1)
@@ -1397,7 +1409,7 @@ static int sip_indicate(struct ast_channel *ast, int condition)
switch(condition) {
case AST_CONTROL_RINGING:
if (ast->_state == AST_STATE_RING) {
- if (!p->progress && !p->ringing) {
+ if (!p->progress) {
transmit_response(p, "180 Ringing", &p->initreq);
p->ringing = 1;
break;
@@ -2608,7 +2620,7 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
char a2[1024] = "";
int x;
struct sockaddr_in dest;
- struct sockaddr_in vdest;
+ struct sockaddr_in vdest = { 0, };
/* XXX We break with the "recommendation" and send our IP, in order that our
peer doesn't have to gethostbyname() us XXX */
len = 0;
@@ -2682,7 +2694,7 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
cur = cur->next;
}
/* Now send any other common codecs, and non-codec formats: */
- for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) {
+ for (x = 1; x <= (videosupport ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
if ((p->jointcapability & x) && !(alreadysent & x)) {
if (sipdebug)
ast_verbose("Answering with capability %d\n", x);
@@ -2720,6 +2732,7 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
}
}
}
+ strncat(a, "a=silenceSupp:off - - - -\r\n", sizeof(a) - strlen(a));
if (strlen(m) < sizeof(m) - 2)
strcat(m, "\r\n");
if (strlen(m2) < sizeof(m2) - 2)
@@ -2902,8 +2915,10 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, char *cmd, c
l = callerid;
}
/* if user want's his callerid restricted */
- if (p->restrictcid)
+ if (p->restrictcid) {
l = CALLERID_UNKNOWN;
+ n = l;
+ }
if (!n || !strlen(n))
n = l;
/* Allow user to be overridden */
@@ -3252,7 +3267,7 @@ static int transmit_register(struct sip_registry *r, char *cmd, char *auth, char
add_header(&req, "Expires", tmp);
add_header(&req, "Contact", p->our_contact);
add_header(&req, "Event", "registration");
- add_header(&req, "Content-length", "0");
+ add_header(&req, "Content-Length", "0");
add_blank_header(&req);
copy_request(&p->initreq, &req);
parse(&p->initreq);
@@ -3305,6 +3320,7 @@ static int transmit_refer(struct sip_pvt *p, char *dest)
add_header(&req, "Refer-To", referto);
if (strlen(p->our_contact))
add_header(&req, "Referred-By", p->our_contact);
+ add_blank_header(&req);
return send_request(p, &req, 1, p->ocseq);
}
@@ -3492,14 +3508,10 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
if (!p->temponly)
p->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, p);
pvt->expiry = expiry;
+ snprintf(data, sizeof(data), "%s:%d:%d:%s", inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username);
+ ast_db_put("SIP/Registry", p->name, data);
if (inaddrcmp(&p->addr, &oldsin)) {
-#ifdef MYSQL_FRIENDS
- if (p->temponly)
- mysql_update_peer(p->name, &p->addr);
-#endif
sip_poke_peer(p);
- snprintf(data, sizeof(data), "%s:%d:%d:%s", inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username);
- ast_db_put("SIP/Registry", p->name, data);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", p->name, inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port), expiry);
}
@@ -3628,13 +3640,26 @@ static void md5_hash(char *output, char *input)
ptr += sprintf(ptr, "%2.2x", digest[x]);
}
-static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, char *username, char *secret, char *md5secret, char *method, char *uri, int reliable)
+static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, char *username, char *secret, char *md5secret, char *method, char *uri, int reliable, int ignore)
{
int res = -1;
/* Always OK if no secret */
if (!strlen(secret) && !strlen(md5secret))
return 0;
- if (!strlen(randdata) || !strlen(get_header(req, "Proxy-Authorization"))) {
+ if (ignore) {
+ /* This is a retransmitted invite/register/etc, don't reconstruct authentication
+ information */
+ if (strlen(randdata)) {
+ if (!reliable) {
+ /* Resend message if this was NOT a reliable delivery. Otherwise the
+ retransmission should get it */
+ transmit_response_with_auth(p, "407 Proxy Authentication Required", req, randdata, reliable);
+ /* Schedule auto destroy in 15 seconds */
+ sip_scheddestroy(p, 15000);
+ }
+ res = 1;
+ }
+ } else if (!strlen(randdata) || !strlen(get_header(req, "Proxy-Authorization"))) {
snprintf(randdata, randlen, "%08x", rand());
transmit_response_with_auth(p, "407 Proxy Authentication Required", req, randdata, reliable);
/* Schedule auto destroy in 15 seconds */
@@ -3648,7 +3673,7 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata
char a1_hash[256];
char a2_hash[256];
char resp[256];
- char resp_hash[256];
+ char resp_hash[256]="";
char tmp[256] = "";
char *c;
char *z;
@@ -3735,7 +3760,7 @@ static int cb_extensionstate(char *context, char* exten, int state, void *data)
return 0;
}
-static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri)
+static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore)
{
int res = -1;
struct sip_peer *peer;
@@ -3780,15 +3805,19 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
#endif
if (peer) {
if (!peer->dynamic) {
- ast_log(LOG_NOTICE, "Peer '%s' isn't dynamic\n", peer->name);
+ ast_log(LOG_NOTICE, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
} else {
p->nat = peer->nat;
transmit_response(p, "100 Trying", req);
- if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, "REGISTER", uri, 0))) {
+ if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, "REGISTER", uri, 0, ignore))) {
sip_cancel_destroy(p);
if (parse_contact(p, peer, req)) {
ast_log(LOG_WARNING, "Failed to parse contact info\n");
} else {
+#ifdef MYSQL_FRIENDS
+ if (peer->temponly)
+ mysql_update_peer(peer->name, &peer->addr, peer->username, p->expiry);
+#endif
/* Say OK and ask subsystem to retransmit msg counter */
transmit_response_with_date(p, "200 OK", req);
peer->lastmsgssent = -1;
@@ -3808,7 +3837,7 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
if (parse_contact(p, peer, req)) {
ast_log(LOG_WARNING, "Failed to parse contact info\n");
} else {
- /* Say OK and ask subsystem to retransmit msg counter */
+ /* Say OK and ask subsystem to retransmit msg counter */
transmit_response_with_date(p, "200 OK", req);
peer->lastmsgssent = -1;
res = 0;
@@ -3888,8 +3917,10 @@ static int get_destination(struct sip_pvt *p, struct sip_request *oreq)
if ((a = strchr(c, ';'))) {
*a = '\0';
}
- if ((a = strchr(fr, '@')) || (a = strchr(fr, ';'))) {
- *a = '\0';
+ if (fr) {
+ if ((a = strchr(fr, '@')) || (a = strchr(fr, ';'))) {
+ *a = '\0';
+ }
}
if (sipdebug)
ast_verbose("Looking for %s in %s\n", c, p->context);
@@ -3955,11 +3986,15 @@ static int get_refer_info(struct sip_pvt *p, struct sip_request *oreq)
a++;
if (!strncasecmp(a, "REPLACES=", strlen("REPLACES="))) {
strncpy(tmp5, a + strlen("REPLACES="), sizeof(tmp5) - 1);
- if ((a = strchr(tmp5, '%'))) {
+ a = tmp5;
+ while ((a = strchr(a, '%'))) {
/* Yuck! Pingtel converts the '@' to a %40, icky icky! Convert
back to an '@' */
+ if (strlen(a) < 3)
+ break;
*a = hex2int(a[1]) * 16 + hex2int(a[2]);
memmove(a + 1, a+3, strlen(a + 3) + 1);
+ a++;
}
if ((a = strchr(tmp5, '%')))
*a = '\0';
@@ -4147,7 +4182,7 @@ static char *get_calleridname(char *input,char *output)
}
return output;
}
-static int check_user(struct sip_pvt *p, struct sip_request *req, char *cmd, char *uri, int reliable, struct sockaddr_in *sin)
+static int check_user(struct sip_pvt *p, struct sip_request *req, char *cmd, char *uri, int reliable, struct sockaddr_in *sin, int ignore)
{
struct sip_user *user;
struct sip_peer *peer;
@@ -4204,7 +4239,7 @@ static int check_user(struct sip_pvt *p, struct sip_request *req, char *cmd, cha
ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", p->nat);
ast_rtp_setnat(p->vrtp, p->nat);
}
- if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, cmd, uri, reliable))) {
+ if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, cmd, uri, reliable, ignore))) {
sip_cancel_destroy(p);
if (strlen(user->context))
strncpy(p->context, user->context, sizeof(p->context) - 1);
@@ -4620,7 +4655,7 @@ static int sip_no_debug(int fd, int argc, char *argv[])
static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, char *digest, int digest_len);
static int do_register_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) {
- char digest[256];
+ char digest[1024];
p->authtries++;
memset(digest,0,sizeof(digest));
if (reply_digest(p,req, header, "REGISTER", digest, sizeof(digest))) {
@@ -4631,7 +4666,7 @@ static int do_register_auth(struct sip_pvt *p, struct sip_request *req, char *he
}
static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, char *msg, int init) {
- char digest[256];
+ char digest[1024];
p->authtries++;
memset(digest,0,sizeof(digest));
if (reply_digest(p,req, "Proxy-Authenticate", msg, digest, sizeof(digest) )) {
@@ -4643,10 +4678,11 @@ static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *heade
static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, char *orig_header, char *digest, int digest_len) {
- char tmp[256] = "";
+ char tmp[512] = "";
char *realm = "";
char *nonce = "";
char *domain = "";
+ char *opaque = "";
char *c;
@@ -4681,6 +4717,17 @@ static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header
if ((c = strchr(c,',')))
*c = '\0';
}
+ } else if (!strncasecmp(c, "opaque=", strlen("opaque="))) {
+ c+=strlen("opaque=");
+ if ((*c == '\"')) {
+ opaque=++c;
+ if ((c = strchr(c,'\"')))
+ *c = '\0';
+ } else {
+ opaque = c;
+ if ((c = strchr(c,',')))
+ *c = '\0';
+ }
} else if (!strncasecmp(c, "domain=", strlen("domain="))) {
c+=strlen("domain=");
if ((*c == '\"')) {
@@ -4704,6 +4751,7 @@ static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header
strncpy(p->realm, realm, sizeof(p->realm)-1);
strncpy(p->nonce, nonce, sizeof(p->nonce)-1);
strncpy(p->domain, domain, sizeof(p->domain)-1);
+ strncpy(p->opaque, opaque, sizeof(p->opaque)-1);
build_reply_digest(p, orig_header, digest, digest_len);
return 0;
}
@@ -4735,7 +4783,7 @@ static int build_reply_digest(struct sip_pvt *p, char* orig_header, char* digest
snprintf(resp,sizeof(resp),"%s:%s:%s",a1_hash,p->nonce,a2_hash);
md5_hash(resp_hash,resp);
- snprintf(digest,digest_len,"Digest username=\"%s\", realm=\"%s\", algorithm=\"MD5\", uri=\"%s\", nonce=\"%s\", response=\"%s\"",p->peername,p->realm,uri,p->nonce,resp_hash);
+ snprintf(digest,digest_len,"Digest username=\"%s\", realm=\"%s\", algorithm=\"MD5\", uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"",p->peername,p->realm,uri,p->nonce,resp_hash, p->opaque);
return 0;
}
@@ -4905,9 +4953,13 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
case 100:
break;
case 183:
- if (p->owner) {
- /* Queue a progress frame */
- ast_queue_control(p->owner, AST_CONTROL_PROGRESS, 0);
+ if (!strcasecmp(msg, "INVITE")) {
+ if (strlen(get_header(req, "Content-Type")))
+ process_sdp(p, req);
+ if (p->owner) {
+ /* Queue a progress frame */
+ ast_queue_control(p->owner, AST_CONTROL_PROGRESS, 0);
+ }
}
break;
case 180:
@@ -5046,7 +5098,10 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
}
/* XXX Locking issues?? XXX */
switch(resp) {
+ case 300: /* Multiple Choices */
+ case 301: /* Moved permenantly */
case 302: /* Moved temporarily */
+ case 305: /* Use Proxy */
parse_moved_contact(p, req);
if (p->owner)
ast_queue_control(p->owner, AST_CONTROL_BUSY, 0);
@@ -5267,7 +5322,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
return -1;
} else {
p->jointcapability = p->capability;
- ast_log(LOG_DEBUG, "Hm.... No sdp for the moemnt\n");
+ ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n");
}
/* Queue NULL frame to prod ast_rtp_bridge if appropriate */
if (p->owner)
@@ -5276,7 +5331,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
ast_verbose("Ignoring this request\n");
if (!p->lastinvite) {
/* Handle authentication if this is our first invite */
- res = check_user(p, req, cmd, e, 1, sin);
+ res = check_user(p, req, cmd, e, 1, sin, ignore);
if (res) {
if (res < 0) {
ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
@@ -5458,7 +5513,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
ast_rtp_stop(p->vrtp);
}
if (strlen(get_header(req, "Also"))) {
- ast_log(LOG_NOTICE, "Client '%s' using depreciated BYE/Also transfer method. Ask vendor to support REFER instead\n",
+ ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n",
inet_ntoa(p->recv.sin_addr));
if (!strlen(p->context))
strncpy(p->context, context, sizeof(p->context) - 1);
@@ -5502,7 +5557,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
if (!p->lastinvite) {
/* Handle authentication if this is our first subscribe */
- res = check_user(p, req, cmd, e, 0, sin);
+ res = check_user(p, req, cmd, e, 0, sin, ignore);
if (res) {
if (res < 0) {
ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
@@ -5564,7 +5619,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
ast_verbose("Using latest request as basis request\n");
copy_request(&p->initreq, req);
check_via(p, req);
- if ((res = register_verify(p, sin, req, e)) < 0)
+ if ((res = register_verify(p, sin, req, e, ignore)) < 0)
ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s'\n", get_header(req, "To"), inet_ntoa(sin->sin_addr));
if (res < 1) {
p->needdestroy = 1;
@@ -5592,7 +5647,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
transmit_response_with_allow(p, "405 Method Not Allowed", req);
ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n",
cmd, inet_ntoa(p->sa.sin_addr));
- /* If this is some new method, and we don't have a call, destory it now */
+ /* If this is some new method, and we don't have a call, destroy it now */
if (!p->initreq.headers)
p->needdestroy = 1;
}
@@ -5790,7 +5845,7 @@ restartsearch:
static int restart_monitor(void)
{
/* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == (pthread_t) -2)
+ if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
@@ -5801,7 +5856,7 @@ static int restart_monitor(void)
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
- if (monitor_thread) {
+ if (monitor_thread != AST_PTHREADT_NULL) {
/* Wake up the thread */
pthread_kill(monitor_thread, SIGURG);
} else {
@@ -6837,12 +6892,12 @@ int unload_module()
return -1;
}
if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread && ((int)monitor_thread != -2)) {
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
pthread_cancel(monitor_thread);
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
- monitor_thread = (pthread_t) -2;
+ monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index b396605b4..5b15f2ae7 100755
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -599,7 +599,7 @@ static ast_mutex_t devicelock = AST_MUTEX_INITIALIZER;
/* This is the thread for the monitor which checks for input on the channels
which are not currently in use. */
-static pthread_t monitor_thread = 0;
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
/* Wait up to 16 seconds for first digit */
static int firstdigittimeout = 16000;
@@ -2425,7 +2425,7 @@ static int restart_monitor(void)
{
/* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == (pthread_t)-2)
+ if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
@@ -2436,7 +2436,7 @@ static int restart_monitor(void)
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
- if (monitor_thread) {
+ if (monitor_thread != AST_PTHREADT_NULL) {
/* Wake up the thread */
pthread_kill(monitor_thread, SIGURG);
} else {
@@ -2740,12 +2740,12 @@ int unload_module()
return -1;
}
if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread && (monitor_thread != -2)) {
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
pthread_cancel(monitor_thread);
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
- monitor_thread = -2;
+ monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
diff --git a/channels/chan_vofr.c b/channels/chan_vofr.c
index 289e101a9..444701fd7 100755
--- a/channels/chan_vofr.c
+++ b/channels/chan_vofr.c
@@ -64,7 +64,7 @@ static ast_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. */
-static pthread_t monitor_thread = 0;
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
static int restart_monitor(void);
@@ -997,7 +997,7 @@ static void *do_monitor(void *data)
static int restart_monitor(void)
{
/* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == -2)
+ if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
@@ -1008,7 +1008,7 @@ static int restart_monitor(void)
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
- if (monitor_thread) {
+ if (monitor_thread != AST_PTHREADT_NULL) {
/* Wake up the thread */
pthread_kill(monitor_thread, SIGURG);
} else {
@@ -1161,7 +1161,7 @@ static int __unload_module(void)
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
- monitor_thread = -2;
+ monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index 31a4113f2..89c174bd4 100755
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -225,7 +225,7 @@ static ast_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. */
-static pthread_t monitor_thread = 0;
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
static int restart_monitor(void);
@@ -388,6 +388,7 @@ static struct zt_pvt {
struct zt_pvt *prev; /* Prev channel in list */
struct zt_distRings drings;
+ int usedistinctiveringdetection;
char context[AST_MAX_EXTENSION];
char defcontext[AST_MAX_EXTENSION];
@@ -1598,7 +1599,8 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
p->prioffset, p->pri->nodetype == PRI_NETWORK ? 0 : 1, 1, l, p->pri->dialplan - 1, n,
l ? (ast->restrictcid ? PRES_PROHIB_USER_NUMBER_PASSED_SCREEN : (p->use_callingpres ? ast->callingpres : PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN)) : PRES_NUMBER_NOT_AVAILABLE,
c + p->stripmsd, p->pri->dialplan - 1,
- ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))) {
+ (p->digital ? -1 :
+ ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)))) {
ast_log(LOG_WARNING, "Unable to setup call to %s\n", c + p->stripmsd);
return -1;
}
@@ -1709,7 +1711,8 @@ static int zt_hangup(struct ast_channel *ast)
}
if (p->dsp)
ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
-
+ if (p->exten)
+ strcpy(p->exten, "");
ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
@@ -2192,13 +2195,23 @@ int x;
return 0;
}
-static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master)
+static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
{
/* Unlink a specific slave or all slaves/masters from a given master */
int x;
int hasslaves;
if (!master)
return;
+ if (needlock) {
+ ast_mutex_lock(&master->lock);
+ if (slave) {
+ while(ast_mutex_trylock(&slave->lock)) {
+ ast_mutex_unlock(&master->lock);
+ usleep(1);
+ ast_mutex_lock(&master->lock);
+ }
+ }
+ }
hasslaves = 0;
for (x=0;x<MAX_SLAVES;x++) {
if (master->slaves[x]) {
@@ -2233,6 +2246,11 @@ static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master)
master->master = NULL;
}
update_conf(master);
+ if (needlock) {
+ if (slave)
+ ast_mutex_unlock(&slave->lock);
+ ast_mutex_unlock(&master->lock);
+ }
}
static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
@@ -2296,8 +2314,11 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
oi2 = zt_get_index(c1, p1, 0);
oc1 = p0->owner;
oc2 = p1->owner;
- if ((oi1 < 0) || (oi2 < 0))
+ if ((oi1 < 0) || (oi2 < 0)) {
+ ast_mutex_unlock(&c0->lock);
+ ast_mutex_unlock(&c1->lock);
return -1;
+ }
@@ -2452,7 +2473,7 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
(oi1 != i1) ||
(oi2 != i2)) {
if (slave && master)
- zt_unlink(slave, master);
+ zt_unlink(slave, master, 1);
ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
op0->channel, oi1, op1->channel, oi2);
if (op0 == p0)
@@ -2480,7 +2501,7 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
*fo = NULL;
*rc = who;
if (slave && master)
- zt_unlink(slave, master);
+ zt_unlink(slave, master, 1);
if (op0 == p0)
zt_enable_ec(p0);
if (op1 == p1)
@@ -2493,7 +2514,7 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
*fo = f;
*rc = who;
if (slave && master)
- zt_unlink(slave, master);
+ zt_unlink(slave, master, 1);
return 0;
} else if ((who == c0) && p0->pulsedial) {
ast_write(c1, f);
@@ -2516,18 +2537,20 @@ static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
struct zt_pvt *p = newchan->pvt->pvt;
int x;
+ ast_mutex_lock(&p->lock);
ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
if (p->owner == oldchan)
p->owner = newchan;
for (x=0;x<3;x++)
if (p->subs[x].owner == oldchan) {
if (!x)
- zt_unlink(NULL, p);
+ zt_unlink(NULL, p, 0);
p->subs[x].owner = newchan;
}
if (newchan->_state == AST_STATE_RINGING)
zt_indicate(newchan, AST_CONTROL_RINGING);
update_conf(p);
+ ast_mutex_unlock(&p->lock);
return 0;
}
@@ -2982,7 +3005,6 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
if (res < 0) {
ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
p->dop.dialstr[0] = '\0';
- return NULL;
} else {
ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
p->subs[index].f.frametype = AST_FRAME_NULL;
@@ -3107,7 +3129,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
} else if (!p->subs[SUB_THREEWAY].owner) {
char callerid[256];
if (p->threewaycalling && !check_for_conference(p)) {
- if (p->zaptrcallerid && p->owner)
+ if (p->zaptrcallerid && p->owner && p->owner->callerid)
strncpy(callerid, p->owner->callerid, sizeof(callerid) - 1);
/* XXX This section needs much more error checking!!! XXX */
/* Start a 3-way call if feasible */
@@ -4638,7 +4660,7 @@ static void *ss_thread(void *data)
break;
}
}
- if (usedistinctiveringdetection == 1) {
+ if (p->usedistinctiveringdetection == 1) {
if(option_verbose > 2)
/* this only shows up if you have n of the dring patterns filled in */
ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
@@ -4793,6 +4815,7 @@ static int handle_init_event(struct zt_pvt *i, int event)
case SIG_FXOLS:
case SIG_FXOGS:
case SIG_FXOKS:
+ zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
if (i->cidspill) {
/* Cancel VMWI spill */
free(i->cidspill);
@@ -5136,7 +5159,7 @@ static int restart_monitor(void)
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
/* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == -2)
+ if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
@@ -5147,7 +5170,7 @@ static int restart_monitor(void)
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
- if (monitor_thread) {
+ if (monitor_thread != AST_PTHREADT_NULL) {
/* Just signal it to be sure it wakes up */
#if 0
pthread_cancel(monitor_thread);
@@ -5492,6 +5515,7 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio)
/* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */
tmp->destroy = 0;
tmp->drings = drings;
+ tmp->usedistinctiveringdetection = usedistinctiveringdetection;
tmp->callwaitingcallerid = callwaitingcallerid;
tmp->threewaycalling = threewaycalling;
tmp->adsi = adsi;
@@ -5845,6 +5869,11 @@ static int pri_fixup(struct zt_pri *pri, int channel, q931_call *c)
return 0;
return channel;
}
+ if ((channel >= 1) &&
+ (channel <= pri->channels) &&
+ (pri->pvt[channel]) &&
+ (pri->pvt[channel]->call == c))
+ return channel;
for (x=1;x<=pri->channels;x++) {
if (!pri->pvt[x]) continue;
if (pri->pvt[x]->call == c) {
@@ -5863,6 +5892,7 @@ static int pri_fixup(struct zt_pri *pri, int channel, q931_call *c)
if (pri->pvt[channel]->owner) {
pri->pvt[channel]->owner->pvt->pvt = pri->pvt[channel];
pri->pvt[channel]->owner->fds[0] = pri->pvt[channel]->subs[SUB_REAL].zfd;
+ pri->pvt[channel]->subs[SUB_REAL].owner = pri->pvt[x]->subs[SUB_REAL].owner;
} else
ast_log(LOG_WARNING, "Whoa, there's no owner, and we're having to fix up channel %d to channel %d\n", x, channel);
pri->pvt[channel]->call = pri->pvt[x]->call;
@@ -6393,7 +6423,7 @@ static void *pri_dchannel(void *vpri)
if ((chan >= 1) && (chan <= pri->channels))
if (pri->pvt[chan] && pri->overlapdial && !pri->pvt[chan]->proceeding) {
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
- ast_log(LOG_DEBUG, "queling frame from PRI_EVENT_PROCEEDING on channel %d span %d\n",chan,pri->pvt[chan]->span);
+ ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d span %d\n",chan,pri->pvt[chan]->span);
ast_queue_frame(pri->pvt[chan]->owner, &f, 0);
pri->pvt[chan]->proceeding=1;
@@ -6472,9 +6502,9 @@ static void *pri_dchannel(void *vpri)
if (!pri->pvt[chan]->alreadyhungup) {
/* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
pri->pvt[chan]->alreadyhungup = 1;
- pri->pvt[chan]->owner->hangupcause = hangup_pri2cause(e->hangup.cause);
/* Queue a BUSY instead of a hangup if our cause is appropriate */
if (pri->pvt[chan]->owner) {
+ pri->pvt[chan]->owner->hangupcause = hangup_pri2cause(e->hangup.cause);
switch(e->hangup.cause) {
case PRI_CAUSE_USER_BUSY:
pri->pvt[chan]->subs[SUB_REAL].needbusy =1;
@@ -6654,7 +6684,7 @@ static void *pri_dchannel(void *vpri)
x = 0;
res = ioctl(pri->fd, ZT_GETEVENT, &x);
if (x)
- printf("PRI got event: %d\n", x);
+ ast_log(LOG_NOTICE, "PRI got event: %d on span %d\n", x, pri->span);
if (option_debug)
ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
}
@@ -6687,7 +6717,7 @@ static int start_pri(struct zt_pri *pri)
if (p.sigtype != ZT_SIG_HDLCFCS) {
close(pri->fd);
pri->fd = -1;
- ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode. See /etc/tormenta.conf\n", x);
+ ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode. See /etc/zaptel.conf\n", x);
return -1;
}
bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
@@ -6725,7 +6755,7 @@ static char *complete_span(char *line, char *word, int pos, int state)
int span=1;
char tmp[50];
while(span <= NUM_SPANS) {
- if (span > state)
+ if (span > state && pris[span-1].pri)
break;
span++;
}
@@ -7202,12 +7232,12 @@ static int __unload_module(void)
return -1;
}
if (!ast_mutex_lock(&monlock)) {
- if (monitor_thread && (monitor_thread != -2)) {
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
pthread_cancel(monitor_thread);
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
- monitor_thread = -2;
+ monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
@@ -7332,7 +7362,8 @@ static int setup_zap(void)
chan = strsep(&c, ",");
}
} else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
- if (!strcasecmp(v->value, "yes")) usedistinctiveringdetection = 1;
+ if (ast_true(v->value))
+ usedistinctiveringdetection = 1;
} else if (!strcasecmp(v->name, "dring1context")) {
strncpy(drings.ringContext[0].contextData,v->value,sizeof(drings.ringContext[0].contextData)-1);
} else if (!strcasecmp(v->name, "dring2context")) {
@@ -7815,7 +7846,8 @@ static int reload_zt(void)
chan = strsep(&stringp, ",");
}
} else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
- if (!strcasecmp(v->value, "yes")) usedistinctiveringdetection = 1;
+ if (ast_true(v->value))
+ usedistinctiveringdetection = 1;
} else if (!strcasecmp(v->name, "dring1context")) {
strncpy(drings.ringContext[0].contextData,v->value,sizeof(drings.ringContext[0].contextData)-1);
} else if (!strcasecmp(v->name, "dring2context")) {
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index 8ffbd2c69..cad1321bb 100755
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -64,7 +64,7 @@ static void dump_string(char *output, int maxlen, void *value, int len)
static void dump_int(char *output, int maxlen, void *value, int len)
{
if (len == sizeof(unsigned int))
- snprintf(output, maxlen, "%ld", (long)ntohl(*((unsigned int *)value)));
+ snprintf(output, maxlen, "%lu", (unsigned long)ntohl(*((unsigned int *)value)));
else
snprintf(output, maxlen, "Invalid INT");
}
@@ -287,8 +287,8 @@ snprintf(tmp, sizeof(tmp),
retries, fh->oseqno, fh->iseqno, class, subclass);
outputf(tmp);
snprintf(tmp, sizeof(tmp),
-" Timestamp: %05ldms SCall: %5.5d DCall: %5.5d [%s:%d]\n",
- (long)ntohl(fh->ts),
+" Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n",
+ (unsigned long)ntohl(fh->ts),
ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
outputf(tmp);
diff --git a/cli.c b/cli.c
index 054535c1b..0068f1259 100755
--- a/cli.c
+++ b/cli.c
@@ -186,6 +186,8 @@ static char *format_uptimestr(time_t timeval)
#define WEEK (DAY*7)
#define YEAR (DAY*365)
+ if (timeval < 0)
+ return NULL;
if (timeval > YEAR) {
years = (timeval / YEAR);
timeval -= (years * YEAR);
@@ -551,7 +553,7 @@ static char *complete_fn(char *line, char *word, int pos, int state)
static int handle_help(int fd, int argc, char *argv[]);
static struct ast_cli_entry builtins[] = {
- /* Keep alphabetized */
+ /* Keep alphabetized, with longer matches first (example: abcd before abc) */
{ { "_command", "complete", NULL }, handle_commandcomplete, "Command complete", commandcomplete_help },
{ { "_command", "nummatches", NULL }, handle_commandnummatches, "Returns number of command matches", commandnummatches_help },
{ { "_command", "matchesarray", NULL }, handle_commandmatchesarray, "Returns command matches array", commandmatchesarray_help },
@@ -561,8 +563,8 @@ static struct ast_cli_entry builtins[] = {
{ { "no", "debug", "channel", NULL }, handle_nodebugchan, "Disable debugging on a channel", nodebugchan_help, complete_ch },
{ { "reload", NULL }, handle_reload, "Reload configuration", reload_help },
{ { "set", "verbose", NULL }, handle_set_verbose, "Set level of verboseness", set_verbose_help },
- { { "show", "channel", NULL }, handle_showchan, "Display information on a specific channel", showchan_help, complete_ch },
{ { "show", "channels", NULL }, handle_chanlist, "Display information on channels", chanlist_help },
+ { { "show", "channel", NULL }, handle_showchan, "Display information on a specific channel", showchan_help, complete_ch },
{ { "show", "modules", NULL }, handle_modlist, "List modules and info", modlist_help },
{ { "show", "uptime", NULL }, handle_showuptime, "Show uptime information", modlist_help },
{ { "show", "version", NULL }, handle_version, "Display version info", version_help },
@@ -948,7 +950,7 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock)
fullcmd = fullcmd1;
e1++;
}
- if ((fullcmd[0] != '_') && !strncasecmp(matchstr, fullcmd, strlen(matchstr))) {
+ if ((fullcmd[0] != '_') && !strncasecmp(text, fullcmd, strlen(text))) {
/* We contain the first part of one or more commands */
matchnum++;
if (matchnum > state) {
diff --git a/codecs/codec_adpcm.c b/codecs/codec_adpcm.c
index 28e4a2794..6ca656a23 100755
--- a/codecs/codec_adpcm.c
+++ b/codecs/codec_adpcm.c
@@ -27,7 +27,6 @@
#include <unistd.h>
#define BUFFER_SIZE 8096 /* size for the translation buffers */
-#define BUF_SHIFT 5
static ast_mutex_t localuser_lock = AST_MUTEX_INITIALIZER;
static int localusecnt = 0;
@@ -105,6 +104,8 @@ decode (unsigned char encoded, short *ssindex, short *signal, unsigned char *rke
*signal = -2047;
*next = 0;
+
+#ifdef AUTO_RETURN
if( encoded & 0x7 )
*rkey = 0;
else if ( ++(*rkey) == 24 ) {
@@ -114,6 +115,7 @@ decode (unsigned char encoded, short *ssindex, short *signal, unsigned char *rke
else if (*signal < 0)
*next = 0x2;
}
+#endif
*ssindex = *ssindex + indsft[(encoded & 7)];
if (*ssindex < 0)
@@ -200,6 +202,10 @@ struct adpcm_decoder_pvt
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */
+ short ssindex;
+ short signal;
+ unsigned char zero_count;
+ unsigned char next_flag;
int tail;
};
@@ -272,41 +278,21 @@ adpcmtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *) pvt;
int x;
- short signal;
- short ssindex;
unsigned char *b;
- unsigned char zero_count;
- unsigned char next_flag;
- if (f->datalen < BUF_SHIFT) {
- ast_log(LOG_WARNING, "Didn't have at least %d bytes of input\n", BUF_SHIFT);
- return -1;
- }
-
- if ((f->datalen - BUF_SHIFT) * 4 > sizeof(tmp->outbuf)) {
+ if (f->datalen * 4 > sizeof(tmp->outbuf)) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
- /* Reset ssindex and signal to frame's specified values */
b = f->data;
- ssindex = b[0];
- if (ssindex < 0)
- ssindex = 0;
- if (ssindex > 48)
- ssindex = 48;
-
- signal = (b[1] << 8) | b[2];
-
- zero_count = b[3];
- next_flag = b[4];
- for (x=BUF_SHIFT;x<f->datalen;x++) {
- decode((b[x] >> 4) & 0xf, &ssindex, &signal, &zero_count, &next_flag);
- tmp->outbuf[tmp->tail++] = signal << 4;
+ for (x=0;x<f->datalen;x++) {
+ decode((b[x] >> 4) & 0xf, &tmp->ssindex, &tmp->signal, &tmp->zero_count, &tmp->next_flag);
+ tmp->outbuf[tmp->tail++] = tmp->signal << 4;
- decode(b[x] & 0x0f, &ssindex, &signal, &zero_count, &next_flag);
- tmp->outbuf[tmp->tail++] = signal << 4;
+ decode(b[x] & 0x0f, &tmp->ssindex, &tmp->signal, &tmp->zero_count, &tmp->next_flag);
+ tmp->outbuf[tmp->tail++] = tmp->signal << 4;
}
return 0;
@@ -408,7 +394,7 @@ lintoadpcm_frameout (struct ast_translator_pvt *pvt)
adpcm0 = adpcm (tmp->inbuf[i], &tmp->ssindex, &tmp->signal, &tmp->zero_count, &tmp->next_flag);
adpcm1 = adpcm (tmp->inbuf[i+1], &tmp->ssindex, &tmp->signal, &tmp->zero_count, &tmp->next_flag);
- tmp->outbuf[i/2 + BUF_SHIFT] = (adpcm0 << 4) | adpcm1;
+ tmp->outbuf[i/2] = (adpcm0 << 4) | adpcm1;
};
@@ -419,7 +405,7 @@ lintoadpcm_frameout (struct ast_translator_pvt *pvt)
tmp->f.offset = AST_FRIENDLY_OFFSET;
tmp->f.src = __PRETTY_FUNCTION__;
tmp->f.data = tmp->outbuf;
- tmp->f.datalen = i_max / 2 + BUF_SHIFT;
+ tmp->f.datalen = i_max / 2;
/*
* If there is a signal left over (there should be no more than
diff --git a/codecs/gsm/Makefile b/codecs/gsm/Makefile
index 747de59e4..effdbcbac 100755
--- a/codecs/gsm/Makefile
+++ b/codecs/gsm/Makefile
@@ -40,10 +40,12 @@ WAV49 = -DWAV49
ifneq (${OSARCH},Darwin)
ifneq (${PROC},x86_64)
ifneq ($(shell uname -m),ppc)
+ifneq ($(shell uname -m),alpha)
OPTIMIZE+=-march=$(PROC)
endif
endif
endif
+endif
PG =
#PG = -g -pg
@@ -200,10 +202,12 @@ GSM_SOURCES = $(SRC)/add.c \
ifeq (${OSARCH},Linux)
ifneq (${PROC},x86_64)
ifneq ($(shell uname -m),ppc)
+ifneq ($(shell uname -m),alpha)
GSM_SOURCES+= $(SRC)/k6opt.s
endif
endif
endif
+endif
TOAST_SOURCES = $(SRC)/toast.c \
$(SRC)/toast_lin.c \
@@ -251,10 +255,12 @@ GSM_OBJECTS = $(SRC)/add.o \
ifeq (${OSARCH},Linux)
ifneq (${PROC},x86_64)
ifneq ($(shell uname -m), ppc)
+ifneq ($(shell uname -m), alpha)
GSM_OBJECTS+= $(SRC)/k6opt.o
endif
endif
endif
+endif
TOAST_OBJECTS = $(SRC)/toast.o \
$(SRC)/toast_lin.o \
diff --git a/codecs/lpc10/Makefile b/codecs/lpc10/Makefile
index e9dbd9d02..af8d907f6 100755
--- a/codecs/lpc10/Makefile
+++ b/codecs/lpc10/Makefile
@@ -25,14 +25,16 @@ WARNINGS = -Wall -Wno-comment -Wno-error
CFLAGS = $(OPTIMIZE) -I$(LIB_TARGET_DIR) $(WARNINGS) -fPIC
#CFLAGS+= $(shell if uname -m | grep -q 86; then echo "-mpentium" ; fi)
-#fix for PPC processors
+#fix for PPC processors and ALPHA too
ifneq ($(OSARCH),Darwin)
ifneq ($(PROC),ppc)
ifneq ($(PROC),x86_64)
+ifneq ($(PROC),alpha)
CFLAGS+= -march=$(PROC)
endif
endif
endif
+endif
LIB = $(LIB_TARGET_DIR)/liblpc10.a
diff --git a/config.c b/config.c
index c217ac624..e25b24235 100755
--- a/config.c
+++ b/config.c
@@ -128,6 +128,20 @@ int ast_true(char *s)
return 0;
}
+int ast_false(char *s)
+{
+ if (!s)
+ return 0;
+ /* Determine if this is a false value */
+ if (!strcasecmp(s, "no") ||
+ !strcasecmp(s, "false") ||
+ !strcasecmp(s, "n") ||
+ !strcasecmp(s, "f") ||
+ !strcasecmp(s, "0"))
+ return -1;
+ return 0;
+}
+
struct ast_variable *ast_variable_browse(struct ast_config *config, char *category)
{
struct ast_category *cat;
diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample
index 04833d63a..736693082 100755
--- a/configs/extensions.conf.sample
+++ b/configs/extensions.conf.sample
@@ -1,6 +1,9 @@
;
-; Static extension configuration files, used by
-; the pbx_config module.
+; Static extension configuration file, used by
+; the pbx_config module. This is where you configure all your
+; inbound and outbound calls in Asterisk.
+;
+
;
; The "General" category is for certain variables.
;
@@ -48,12 +51,14 @@ TRUNKMSD=1 ; MSD digits to strip (usually 1 or 0)
; literal. In patterns, some characters have special meanings:
;
; X - any digit from 0-9
+; Z - any digit from 1-9
; N - any digit from 2-9
; [1235-9] - any digit in the brackets (in this example, 1,2,3,5,6,7,8,9)
-; . - wildcard, matches anything remaining (e.g. _9011. matches anything starting with 9011 excluding 9011 itself)
+; . - wildcard, matches anything remaining (e.g. _9011. matches
+; anything starting with 9011 excluding 9011 itself)
;
-; For example the extenion _NXXXXXX would match normal 7 digit dialings, while
-; _1NXXNXXXXXX would represent an area code plus phone number
+; For example the extension _NXXXXXX would match normal 7 digit dialings,
+; while _1NXXNXXXXXX would represent an area code plus phone number
; preceeded by a one.
;
; Contexts contain several lines, one for each step of each
@@ -159,6 +164,7 @@ include => iaxprovider
; You can use an alternative switch type as well, to resolve
; extensions that are not known here, for example with remote
; IAX switching you transparently get access to the remote
+; Asterisk PBX
;
; switch => IAX2/user:password@bigserver/local
@@ -293,10 +299,13 @@ include => demo
;
;exten => 8600,1,Meetme,1234
;
-; Or playing an announce to the called party, as soon it answers
+; Or playing an announcement to the called party, as soon it answers
;
;exten = 8700,1,Dial(${MARK},30,A(/path/to/my/announcemsg))
;
; For more information on applications, just type "show applications" at your
; friendly Asterisk CLI prompt.
;
+; 'show application <command>' will show details of how you
+; use that particular application in this file, the dial plan.
+;
diff --git a/configs/iax.conf.sample b/configs/iax.conf.sample
index 42f5ed9e5..6c5015ae1 100755
--- a/configs/iax.conf.sample
+++ b/configs/iax.conf.sample
@@ -43,14 +43,16 @@ disallow=lpc10 ; Icky sound quality... Mr. Roboto.
; buffer. Specifically, you can provide a maximum jitter buffer,
; you can turn it off entirely, and you can specify an acceptable
; drop rate (per MEMORY_SIZE, by default 3 of 100). Disabling the
-; jitter buffer is not recommended. Finally, you can specify the maximum
+; jitter buffer is generally recommended unless you are on a highly
+; jittery network, since usually jitter buffering will cause you additional
+; latency. Finally, you can specify the maximum
; excess jitter buffer, which if exceeded, causes the jitter buffer to
; slowly shrink in order to improve latency.
;
jitterbuffer=no
;dropcount=3
;maxjitterbuffer=500
-;maxexccessbuffer=100
+;maxexcessbuffer=100
;
;trunkfreq=20 ; How frequently to send trunk msgs (in ms)
;
diff --git a/configs/mgcp.conf.sample b/configs/mgcp.conf.sample
index 544940d30..73b7c6cee 100755
--- a/configs/mgcp.conf.sample
+++ b/configs/mgcp.conf.sample
@@ -8,6 +8,7 @@
;[dlinkgw]
;host = 192.168.0.64
;context = default
+;canreinvite = no
;line => aaln/2
;line => aaln/1
diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample
index ec965e9e3..141cff453 100755
--- a/configs/sip.conf.sample
+++ b/configs/sip.conf.sample
@@ -1,28 +1,74 @@
;
; SIP Configuration for Asterisk
;
+; Syntax for specifying a SIP device in extensions.conf is
+; SIP/devicename where devicename is defined in a section below.
+;
+; You may also use
+; SIP/username@domain to call any SIP user on the Internet
+; (Don't forget to enable DNS SRV records if you want to use this)
+;
+; If you define a SIP proxy as a peer below, you may call
+; SIP/proxyhostname/user or SIP/user@proxyhostname
+; where the proxyhostname is defined in a section below
+;
+; Useful CLI commands to check peers/users:
+; sip show peers Show all SIP peers (including friends)
+; sip show users Show all SIP users (including friends)
+; sip show registry Show status of hosts we register with
+;
+; sip debug Show all SIP messages
+;
+
+
[general]
port = 5060 ; Port to bind to
-bindaddr = 0.0.0.0 ; Address to bind to
-;externip = 200.201.202.203 ; Address that we're going to put in SIP messages if we're behind a NAT
-;localnet = 192.168.1.0 ; Internal NETWORK address
-;localmask = 255.255.255.0 ; Internal netmask
-context = default ; Default for incoming calls
-;srvlookup = yes ; Enable SRV lookups on outbound calls
+bindaddr = 0.0.0.0 ; Address to bind SIP channel to
+context = default ; Default context for incoming calls
+;srvlookup = yes ; Enable DNS SRV lookups on outbound calls
+
;pedantic = yes ; Enable slow, pedantic checking for Pingtel
-;tos=lowdelay
-;tos=184
+;tos=lowdelay ; IP QoS parameter, either keyword or value
+
;maxexpirey=3600 ; Max length of incoming registration we allow
;defaultexpirey=120 ; Default length of incoming/outoing registration
;notifymimetype=text/plain ; Allow overriding of mime type in NOTIFY
;videosupport=yes ; Turn on support for SIP video
+
;disallow=all ; Disallow all codecs
;allow=ulaw ; Allow codecs in order of preference
;allow=ilbc
+
+; Asterisk can register as a SIP user agent to a SIP proxy (provider)
+; Format for the register statement is:
+; register => user[:secret[:authuser]]@host[:port][/extension]
+;
+; If no extension is given, the 's' extension is used. The extension
+; needs to be defined in extensions.conf to be able to accept calls
+; from this SIP proxy (provider)
;
-;register => 1234@mysipprovider.com ; Register with a SIP provider
-;register => 2345@mysipprovider.com/1234 ; Register 2345 at sip provider as 1234 here.
+; host is either a host name defined in DNS or the name of a
+; section defined below.
;
+; Examples:
+,
+;register => 1234:password@mysipprovider.com
+; Will call to the 's' extension
+;
+;register => 2345@mysipprovider.com/1234
+;
+; Register 2345 at sip provider. Calls from this provider connect to local
+; extension 1234 in extensions.conf default context, unless you define
+; [mysipprovider.com] in a section below, and configure a context
+
+;externip = 200.201.202.203 ; Address that we're going to put in outbound SIP messages
+ ; if we're behind a NAT
+;localnet = 192.168.1.0 ; Internet NETWORK address
+;localmask = 255.255.255.0 ; Internet netmask
+ ; The externip, localnet and localmask is used
+ ; when registering and communication with other proxies
+ ; that we're registered with
+
;[snomsip]
;type=friend
;secret=blah
@@ -38,6 +84,8 @@ context = default ; Default for incoming calls
;secret=blah
;host=dynamic
;qualify=1000 ; Consider it down if it's 1 second to reply
+ ; Helps with NAT session
+ ; qualify=yes uses default value
;callgroup=1,3-4
;pickupgroup=1,3-4
;defaultip=192.168.0.60
@@ -47,8 +95,14 @@ context = default ; Default for incoming calls
;username=cisco
;secret=blah
;nat=yes ; This phone may be natted
+ ; Use IP address that packet is received from
+ ; instead of trusting SIP headers
;host=dynamic
-;canreinvite=no ; Cisco poops on reinvite sometimes
+;canreinvite=no ; Asterisk by default tries to redirect the
+ ; RTP media stream (audio) to go directly from
+ ; the caller to the callee. Some devices do not
+ ; support this (especially if one of them is
+ ; behind a NAT).
;qualify=200 ; Qualify peer is no more than 200ms away
;defaultip=192.168.0.4
@@ -56,8 +110,12 @@ context = default ; Default for incoming calls
;type=friend
;username=cisco1
;fromuser=markster ; Specify user to put in "from" instead of callerid
+;fromdomain=yourdomain.com ; Specify domain to put in "from" instead of callerid
+ ; fromuser and fromdomain are used when Asterisk
+ ; places calls to this account. It is not used for
+ ; calls from this account.
;secret=blah
;host=dynamic
;defaultip=192.168.0.4
;amaflags=default ; Choices are default, omit, billing, documentation
-;accountcode=markster ; Users may be associated with an accountcode tp ease billing
+;accountcode=markster ; Users may be associated with an accountcode to ease billing
diff --git a/configs/voicemail.conf.sample b/configs/voicemail.conf.sample
index 50281e398..c15b99412 100755
--- a/configs/voicemail.conf.sample
+++ b/configs/voicemail.conf.sample
@@ -10,9 +10,9 @@ serveremail=asterisk
;serveremail=asterisk@linux-support.net
; Should the email contain the voicemail as an attachment
attach=yes
-; Maximum length of a voicemail message
+; Maximum length of a voicemail message in seconds
;maxmessage=180
-; Maximum length of greetings
+; Maximum length of greetings in seconds
;maxgreet=60
; How many miliseconds to skip forward/back when rew/ff in message playback
skipms=3000
diff --git a/configs/zapata.conf.sample b/configs/zapata.conf.sample
index dc7a4405e..5294b463c 100755
--- a/configs/zapata.conf.sample
+++ b/configs/zapata.conf.sample
@@ -73,19 +73,6 @@ switchtype=national
;
signalling=fxo_ls
;
-; A variety of timing parameters can be specified as well
-; Including:
-; prewink: Pre-wink time
-; preflash: Pre-flash time
-; wink: Wink time
-; flash: Flash time
-; start: Start time
-; rxwink: Receiver wink time
-; rxflash: Receiver flashtime
-; debounce: Debounce timing
-;
-rxwink=300 ; Atlas seems to use long (250ms) winks
-;
; Whether or not to do distinctive ring detection on FXO lines
;
;usedistinctiveringdetection=yes
diff --git a/contrib/scripts/sip-friends.sql b/contrib/scripts/sip-friends.sql
index 30e4ec366..15d7cb393 100755
--- a/contrib/scripts/sip-friends.sql
+++ b/contrib/scripts/sip-friends.sql
@@ -6,6 +6,7 @@ CREATE TABLE `sipfriends` (
`name` varchar(40) NOT NULL default '',
`secret` varchar(40) NOT NULL default '',
`context` varchar(40) NOT NULL default '',
+ `username` varchar(40) default '',
`ipaddr` varchar(20) NOT NULL default '',
`port` int(6) NOT NULL default '0',
`regseconds` int(11) NOT NULL default '0',
diff --git a/contrib/scripts/vmdb.sql b/contrib/scripts/vmdb.sql
index dbef17316..59238c659 100755
--- a/contrib/scripts/vmdb.sql
+++ b/contrib/scripts/vmdb.sql
@@ -1,2 +1,11 @@
drop table if exists users;
-create table users (mailbox VARCHAR(80) NOT NULL PRIMARY KEY, context VARCHAR(80), password VARCHAR(80), fullname VARCHAR(80), email VARCHAR(80), pager VARCHAR(80), options VARCHAR(160));
+create table users (
+context VARCHAR(80) NOT NULL,
+mailbox VARCHAR(80) NOT NULL,
+password VARCHAR(80) NOT NULL DEFAULT '',
+fullname VARCHAR(80) NOT NULL DEFAULT '',
+email VARCHAR(80) NOT NULL DEFAULT '',
+pager VARCHAR(80) NOT NULL DEFAULT '',
+options VARCHAR(160) NOT NULL DEFAULT '',
+PRIMARY KEY (context, mailbox)
+);
diff --git a/dns.c b/dns.c
index 7f8615424..7da02247c 100755
--- a/dns.c
+++ b/dns.c
@@ -137,8 +137,10 @@ static int dns_parse_answer(void *context,
if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) {
if (callback) {
- if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0)
+ if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) {
ast_log(LOG_WARNING, "Failed to parse result\n");
+ return -1;
+ }
if (res > 0)
return 1;
}
@@ -153,13 +155,13 @@ int ast_search_dns(void *context,
const char *dname, int class, int type,
int (*callback)(void *context, u_char *answer, int len, u_char *fullanswer))
{
-#ifdef __Linux__
+#ifdef linux
struct __res_state dnsstate;
#endif
char answer[MAX_SIZE];
int res, ret = -1;
-#ifdef __Linux__
+#ifdef linux
res_ninit(&dnsstate);
res = res_nsearch(&dnsstate, dname, class, type, answer, sizeof(answer));
#else
@@ -178,8 +180,8 @@ int ast_search_dns(void *context,
else
ret = 1;
}
-#if defined(__Linux__)
- res_nclose(&srvstate);
+#if defined(linux)
+ res_nclose(&dnsstate);
#else
#ifndef __APPLE__
res_close();
diff --git a/doc/README.cdr b/doc/README.cdr
index d6c9c0398..2b0c8f289 100755
--- a/doc/README.cdr
+++ b/doc/README.cdr
@@ -13,7 +13,7 @@ separated text file.
Applications
------------
- * Asterisk cmd setaccount: Set accound code for billing
+ * Asterisk cmd setaccount: Set account code for billing
* Asterisk cmd NoCDR: Make sure no CDR is saved for a specific call
* Asterisk cmd resetCDR: Reset CDR
* Asterisk cmd authenticate - Authenticates and sets the account code
@@ -36,7 +36,7 @@ Fields of the CDR in Asterisk
8. lastapp: Last application if appropriate (80 characters)
9. lastdata: Last application data (arguments) (80 characters)
10. start: Start of call (date/time)
- 11. answer: Anwer of call (date/time)
+ 11. answer: Answer of call (date/time)
12. end: End of call (date/time)
13. duration: Total time in system, in seconds (integer), from dial to hangup
14. billsec: Total time call is up, in seconds (integer), from answer to hangup
diff --git a/doc/README.iax b/doc/README.iax
index 58372e0d2..2e1c4cfd6 100755
--- a/doc/README.iax
+++ b/doc/README.iax
@@ -31,7 +31,7 @@ and H.323, some of which are:
* High performance, low overhead protocol
When running on low-bandwidth connections, or when running
large numbers of calls, optimized bandwidth utilization is
- imperitive. IAX uses only 4 bytes of overhead
+ imperative. IAX uses only 4 bytes of overhead
* Internationalization support
IAX transmits language information, so that remote PBX
@@ -198,7 +198,7 @@ these packets, improving voice quality.
> register => <name>[:<secret>]@<host>[:port]
-Any number of registery entries may be instantiated in the general
+Any number of registry entries may be instantiated in the general
section. Registration allows Asterisk to notify a remote Asterisk server
(with a fixed address) what our current address is. In order for
registration to work, the remote Asterisk server will need to have a
@@ -244,7 +244,7 @@ One or more context lines may be specified in a user, thus giving the user
access to place calls in the given contexts. Contexts are used by
Asterisk to divide dialing plans into logical units each with the ability
to have numbers interpreted differently, have their own security model,
-auxilliary switch handling, and include other contexts. Most users are
+auxiliary switch handling, and include other contexts. Most users are
given access to the default context. Trusted users could be given access
to the local context for example.
@@ -265,7 +265,7 @@ whereas:
> deny = 192.168.0.0/255.255.255.0
> permit = 0.0.0.0/0.0.0.0
-would not deny anyone since the final rule would permit anyone, thsu
+would not deny anyone since the final rule would permit anyone, thus
overriding the denial.
If no permit/deny rules are listed, it is assumed that someone may connect
@@ -283,7 +283,7 @@ You may select which authentication methods are permitted to be used by
the user to authenticate to us. Multiple methods may be specified,
separated by commas. If md5 or plaintext authentication is selected, a
secret must be provided. If RSA authentication is specified, then one or
-more key names must be specifed with "inkeys"
+more key names must be specified with "inkeys"
If no secret is specified and no authentication method is specified, then
no authentication will be required.
diff --git a/doc/README.variables b/doc/README.variables
index 7ade326a5..e924a8c2e 100755
--- a/doc/README.variables
+++ b/doc/README.variables
@@ -1,4 +1,4 @@
-GENERAL ENCHANCEMENTS TO EXTENSION LOGIC :
+GENERAL ENHANCEMENTS TO EXTENSION LOGIC :
QUOTING:
@@ -9,7 +9,7 @@ comma does not terminate the field.
Also, characters special to variable substitution, expression evaluation, etc
(see below), can be quoted. For example, to literally use a $ on the
-string "$1231", quote it with a preceeding \. Special characters that must
+string "$1231", quote it with a preceding \. Special characters that must
be quoted to be used, are [ ] $ " \. (to write \ itself, use \\).
VARIABLES:
diff --git a/doc/extensions.txt b/doc/extensions.txt
index 2d6ea2fe4..0fb2fd3b6 100755
--- a/doc/extensions.txt
+++ b/doc/extensions.txt
@@ -1,7 +1,7 @@
Extensions are routed according to priority, and may be based on any set
of digits, #, and *. For each extension, several actions may be listed
and each given a priority. When each action completes, it generally moves
-to the next priority (except for some modules which use explicity GOTO's.
+to the next priority (except for some modules which use explicitly GOTO's.
Extensions frequently have data they pass to the executing application
(most frequently a string). There are some reserved application names:
@@ -18,5 +18,5 @@ Also, there are some extensions with important meanings:
And finally, the extension context "default" is used when either a) an
extension context is deleted while an extension is in use, or b) a specific
-starting extension handler has not been defined (unless overrridden by the
+starting extension handler has not been defined (unless overridden by the
low level channel interface).
diff --git a/doc/localchannel.txt b/doc/localchannel.txt
index 3cebac0ba..f96ea15ec 100755
--- a/doc/localchannel.txt
+++ b/doc/localchannel.txt
@@ -11,7 +11,7 @@ Adding "/n" at the end of the string will make the Local channel not do a native
* Purpose:
-The Local channel construct can be used to establish dialling into any part of the dialplan.
+The Local channel construct can be used to establish dialing into any part of the dialplan.
Imagine you have a TE410P in your box. You want to do something for which you must use a Dial statement (for instance when dropping files in /var/spool/outgoing) but you do want to be able to use your dialplans least-cost-routes or other intelligent stuff. What you could do before we had chan_local was create a cross-link between two ports of the TE410P and then Dial out one port and in the other. This way you could control where the call was going.
diff --git a/doc/manager.txt b/doc/manager.txt
index 9c585ce20..cdc8cc213 100755
--- a/doc/manager.txt
+++ b/doc/manager.txt
@@ -12,7 +12,7 @@ receive this class of "event".
Command Syntax
--------------
-Mangement communication consists of tags of the form "header: value",
+Management communication consists of tags of the form "header: value",
terminated with an empty newline (\r\n) in the style of SMTP, HTTP, and
other headers.
diff --git a/doc/model.txt b/doc/model.txt
index 6afb3e04e..10d2d0e05 100755
--- a/doc/model.txt
+++ b/doc/model.txt
@@ -7,9 +7,9 @@ interface. Typically this is done in its own thread. When a RING is
detected, the backend should create a channel structure and then call
ast_pbx_start() on that channel, which will create a thread to monitor
that interface. At this point, the PBX and/or applications it launches
-will manage the interface, and it need not be montored by the
+will manage the interface, and it need not be monitored by the
aforementioned thread. When the applications are finished, the requisite
hangup function will be called, at which the channel can be considered to
-be no longer valid, and the thread that controls it will immenantly be
+be no longer valid, and the thread that controls it will imminently be
terminated.
diff --git a/doc/modules.txt b/doc/modules.txt
index 9f8ae20b5..4f6d4c67b 100755
--- a/doc/modules.txt
+++ b/doc/modules.txt
@@ -3,8 +3,8 @@ All modules must have at least the following functions:
int load_module():
Do what you need to do when you get started. This function
-returns 0 on sucess and non-zero on failure (it is not considered loaded
-if it failes.
+returns 0 on success and non-zero on failure (it is not considered loaded
+if it fails.
int unload_module():
@@ -12,7 +12,7 @@ int unload_module():
features, you should give them a softhangup in an effort to keep the
program from crashing. Generally, unload_module is only called when the
usecount is 0 or less, but the user can force unloading at their
-discression, and thus a module should do its best to comply (although in
+discretion, and thus a module should do its best to comply (although in
some cases there may be no way to avoid a crash). This function should
return 0 on success and non-zero on failure (i.e. it cannot yet be
unloaded).
diff --git a/dsp.c b/dsp.c
index b72063a2e..268842cb6 100755
--- a/dsp.c
+++ b/dsp.c
@@ -56,6 +56,9 @@
/* Number of goertzels for progress detect */
#define GSAMP_SIZE 183
+/* Define if you want the fax detector -- NOT RECOMMENDED IN -STABLE */
+/* #define FAX_DETECT */
+
#define HZ_350 0
#define HZ_440 1
#define HZ_480 2
@@ -130,11 +133,15 @@ typedef struct
goertzel_state_t row_out[4];
goertzel_state_t col_out[4];
+#ifdef FAX_DETECT
goertzel_state_t fax_tone;
+#endif
#ifdef OLD_DSP_ROUTINES
goertzel_state_t row_out2nd[4];
goertzel_state_t col_out2nd[4];
+#ifdef FAX_DETECT
goertzel_state_t fax_tone2nd;
+#endif
int hit1;
int hit2;
int hit3;
@@ -153,7 +160,9 @@ typedef struct
int digit_hits[16];
+#ifdef FAX_DETECT
int fax_hits;
+#endif
} dtmf_detect_state_t;
typedef struct
@@ -176,7 +185,9 @@ typedef struct
int current_digits;
int detected_digits;
int lost_digits;
+#ifdef FAX_DETECT
int fax_hits;
+#endif
} mf_detect_state_t;
static float dtmf_row[] =
@@ -193,7 +204,9 @@ static float mf_tones[] =
700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
};
+#ifdef FAX_DETECT
static float fax_freq = 1100.0;
+#endif
static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
@@ -294,6 +307,7 @@ static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
s->energy = 0.0;
}
+#ifdef FAX_DETECT
/* Same for the fax dector */
goertzel_init (&s->fax_tone, fax_freq, 102);
@@ -301,6 +315,7 @@ static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
/* Same for the fax dector 2nd harmonic */
goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102);
#endif
+#endif /* FAX_DETECT */
s->current_sample = 0;
s->detected_digits = 0;
@@ -348,10 +363,12 @@ static int dtmf_detect (dtmf_detect_state_t *s,
float row_energy[4];
float col_energy[4];
+#ifdef FAX_DETECT
float fax_energy;
#ifdef OLD_DSP_ROUTINES
float fax_energy_2nd;
#endif
+#endif /* FAX_DETECT */
float famp;
float v1;
int i;
@@ -422,11 +439,12 @@ static int dtmf_detect (dtmf_detect_state_t *s,
s->col_out[3].v2 = s->col_out[3].v3;
s->col_out[3].v3 = s->col_out[3].fac*s->col_out[3].v2 - v1 + famp;
+#ifdef FAX_DETECT
/* Update fax tone */
v1 = s->fax_tone.v2;
s->fax_tone.v2 = s->fax_tone.v3;
s->fax_tone.v3 = s->fax_tone.fac*s->fax_tone.v2 - v1 + famp;
-
+#endif /* FAX_DETECT */
#ifdef OLD_DSP_ROUTINES
v1 = s->col_out2nd[0].v2;
s->col_out2nd[0].v2 = s->col_out2nd[0].v3;
@@ -460,9 +478,13 @@ static int dtmf_detect (dtmf_detect_state_t *s,
s->row_out2nd[3].v2 = s->row_out2nd[3].v3;
s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp;
- v1 = s->fax_tone.v2;
+
+#ifdef FAX_DETECT
+ /* Update fax tone */
+ v1 = s->fax_tone.v2;
s->fax_tone2nd.v2 = s->fax_tone2nd.v3;
s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp;
+#endif /* FAX_DETECT */
#endif
}
#endif
@@ -478,8 +500,10 @@ static int dtmf_detect (dtmf_detect_state_t *s,
continue;
}
+#ifdef FAX_DETECT
/* Detect the fax energy, too */
fax_energy = goertzel_result(&s->fax_tone);
+#endif
/* We are at the end of a DTMF detection block */
/* Find the peak row and the peak column */
@@ -582,6 +606,7 @@ static int dtmf_detect (dtmf_detect_state_t *s,
#endif
}
}
+#ifdef FAX_DETECT
#ifdef OLD_DSP_ROUTINES
if (!hit && (fax_energy >= FAX_THRESHOLD) && (fax_energy > s->energy * 21.0)) {
fax_energy_2nd = goertzel_result(&s->fax_tone2nd);
@@ -622,6 +647,7 @@ static int dtmf_detect (dtmf_detect_state_t *s,
}
s->fax_hits = 0;
}
+#endif /* FAX_DETECT */
#ifdef OLD_DSP_ROUTINES
s->hit1 = s->hit2;
s->hit2 = s->hit3;
@@ -641,10 +667,12 @@ static int dtmf_detect (dtmf_detect_state_t *s,
goertzel_reset(&s->col_out2nd[i]);
#endif
}
+#ifdef FAX_DETECT
goertzel_reset (&s->fax_tone);
#ifdef OLD_DSP_ROUTINES
goertzel_reset (&s->fax_tone2nd);
#endif
+#endif
s->energy = 0.0;
s->current_sample = 0;
}
@@ -1633,9 +1661,13 @@ void ast_dsp_digitreset(struct ast_dsp *dsp)
goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
#endif
}
+#ifdef FAX_DETECT
goertzel_reset (&dsp->td.dtmf.fax_tone);
+#endif
#ifdef OLD_DSP_ROUTINES
+#ifdef FAX_DETECT
goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
+#endif
dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
#else
dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0;
diff --git a/enum.c b/enum.c
index cbd007fcf..48531dfe9 100755
--- a/enum.c
+++ b/enum.c
@@ -232,8 +232,10 @@ static int enum_callback(void *context, u_char *answer, int len, u_char *fullans
{
struct enum_context *c = (struct enum_context *)context;
- if (parse_naptr(c->dst, c->dstlen, c->tech, c->techlen, answer, len, c->naptrinput))
+ if (parse_naptr(c->dst, c->dstlen, c->tech, c->techlen, answer, len, c->naptrinput)) {
ast_log(LOG_WARNING, "Failed to parse naptr :(\n");
+ return -1;
+ }
if (strlen(c->dst))
return 1;
diff --git a/file.c b/file.c
index 9869eb325..9cdaec575 100755
--- a/file.c
+++ b/file.c
@@ -274,7 +274,7 @@ static int copy(char *infile, char *outfile)
static char *build_filename(char *filename, char *ext)
{
char *fn;
- char tmp[AST_CONFIG_MAX_PATH];
+ char tmp[AST_CONFIG_MAX_PATH]="";
snprintf(tmp,sizeof(tmp)-1,"%s/%s",(char *)ast_config_AST_VAR_DIR,"sounds");
fn = malloc(strlen(tmp) + strlen(filename) + strlen(ext) + 10);
if (fn) {
@@ -287,6 +287,22 @@ static char *build_filename(char *filename, char *ext)
}
+static int exts_compare(char *exts, char *type)
+{
+ char *stringp = NULL, *ext;
+ char tmp[256];
+
+ strncpy(tmp, exts, sizeof(tmp) - 1);
+ stringp = tmp;
+ while ((ext = strsep(&stringp, "|"))) {
+ if (!strcmp(ext, type)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
#define ACTION_EXISTS 1
#define ACTION_DELETE 2
#define ACTION_RENAME 3
@@ -319,7 +335,7 @@ static int ast_filehelper(char *filename, char *filename2, char *fmt, int action
}
f = formats;
while(f) {
- if (!fmt || !strcasecmp(f->name, fmt)) {
+ if (!fmt || exts_compare(f->exts, fmt)) {
char *stringp=NULL;
exts = strdup(f->exts);
/* Try each kind of extension */
@@ -376,7 +392,7 @@ static int ast_filehelper(char *filename, char *filename2, char *fmt, int action
chan->vstream = s;
} else {
close(ret);
- ast_log(LOG_WARNING, "Unable to open fd on %s\n", filename);
+ ast_log(LOG_WARNING, "Unable to open fd on %s\n", fn);
}
} else
ast_log(LOG_WARNING, "Couldn't open file %s\n", fn);
@@ -748,7 +764,7 @@ struct ast_filestream *ast_readfile(char *filename, char *type, char *comment, i
}
f = formats;
while(f) {
- if (!strcasecmp(f->name, type)) {
+ if (exts_compare(f->exts, type)) {
char *stringp=NULL;
/* XXX Implement check XXX */
ext = strdup(f->exts);
@@ -803,7 +819,7 @@ struct ast_filestream *ast_writefile(char *filename, char *type, char *comment,
f = formats;
while(f) {
- if (!strcasecmp(f->name, type)) {
+ if (exts_compare(f->exts, type)) {
char *stringp=NULL;
/* XXX Implement check XXX */
ext = strdup(f->exts);
diff --git a/formats/format_g723.c b/formats/format_g723.c
index 2431d3dee..1b610f1f0 100755
--- a/formats/format_g723.c
+++ b/formats/format_g723.c
@@ -47,7 +47,7 @@ static int glistcnt = 0;
static char *name = "g723sf";
static char *desc = "G.723.1 Simple Timestamp File Format";
-static char *exts = "g723";
+static char *exts = "g723|g723sf";
static struct ast_filestream *g723_open(int fd)
{
diff --git a/formats/format_vox.c b/formats/format_vox.c
index 4fd7ffd94..20021fb73 100755
--- a/formats/format_vox.c
+++ b/formats/format_vox.c
@@ -33,7 +33,6 @@
#endif
#define BUF_SIZE 80 /* 160 samples */
-#define BUF_SHIFT 5
struct ast_filestream {
void *reserved[AST_RESERVED_POINTERS];
@@ -42,7 +41,7 @@ struct ast_filestream {
struct ast_frame fr; /* Frame information */
char waste[AST_FRIENDLY_OFFSET]; /* Buffer for sending frames, etc */
char empty; /* Empty character */
- unsigned char buf[BUF_SIZE + BUF_SHIFT]; /* Output Buffer */
+ unsigned char buf[BUF_SIZE]; /* Output Buffer */
int lasttimeout;
struct timeval last;
short signal; /* Signal level (file side) */
@@ -59,143 +58,6 @@ static char *name = "vox";
static char *desc = "Dialogic VOX (ADPCM) File Format";
static char *exts = "vox";
-/*
- * Step size index shift table
- */
-
-static short indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
-
-/*
- * Step size table, where stpsz[i]=floor[16*(11/10)^i]
- */
-
-static short stpsz[49] = {
- 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73,
- 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279,
- 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
- 1060, 1166, 1282, 1411, 1552
-};
-
-/*
- * Nibble to bit map
- */
-
-static short nbl2bit[16][4] = {
- {1, 0, 0, 0}, {1, 0, 0, 1}, {1, 0, 1, 0}, {1, 0, 1, 1},
- {1, 1, 0, 0}, {1, 1, 0, 1}, {1, 1, 1, 0}, {1, 1, 1, 1},
- {-1, 0, 0, 0}, {-1, 0, 0, 1}, {-1, 0, 1, 0}, {-1, 0, 1, 1},
- {-1, 1, 0, 0}, {-1, 1, 0, 1}, {-1, 1, 1, 0}, {-1, 1, 1, 1}
-};
-
-/*
- * Decode(encoded)
- * Decodes the encoded nibble from the adpcm file.
- *
- * Results:
- * Returns the encoded difference.
- *
- * Side effects:
- * Sets the index to the step size table for the next encode.
- */
-
-static inline void
-decode (unsigned char encoded, short *ssindex, short *signal, unsigned char *rkey, unsigned char *next)
-{
- short diff, step;
- step = stpsz[*ssindex];
-
- diff = step * nbl2bit[encoded][1] +
- (step >> 1) * nbl2bit[encoded][2] +
- (step >> 2) * nbl2bit[encoded][3] +
- (step >> 3);
- if (nbl2bit[encoded][2] && (step & 0x1))
- diff++;
- diff *= nbl2bit[encoded][0];
-
- if ( *next & 0x1 )
- *signal -= 8;
- else if ( *next & 0x2 )
- *signal += 8;
-
- *signal += diff;
-
- if (*signal > 2047)
- *signal = 2047;
- else if (*signal < -2047)
- *signal = -2047;
-
- *next = 0;
- if( encoded & 0x7 )
- *rkey = 0;
- else if ( ++(*rkey) == 24 ) {
- *rkey = 0;
- if (*signal > 0)
- *next = 0x1;
- else if (*signal < 0)
- *next = 0x2;
- }
-
- *ssindex = *ssindex + indsft[(encoded & 7)];
- if (*ssindex < 0)
- *ssindex = 0;
- else if (*ssindex > 48)
- *ssindex = 48;
-}
-
-/*
- * Adpcm
- * Takes a signed linear signal and encodes it as ADPCM
- * For more information see http://support.dialogic.com/appnotes/adpcm.pdf
- *
- * Results:
- * Foo.
- *
- * Side effects:
- * signal gets updated with each pass.
- */
-
-static inline unsigned char
-adpcm (short csig, short *ssindex, short *signal)
-{
- short diff, step;
- unsigned char encoded;
- unsigned char zero_count, next_flag;
- step = stpsz[*ssindex];
- /*
- * Clip csig if too large or too small
- */
-
- csig >>= 4;
-
- diff = csig - *signal;
-
- if (diff < 0)
- {
- encoded = 8;
- diff = -diff;
- }
- else
- encoded = 0;
- if (diff >= step)
- {
- encoded |= 4;
- diff -= step;
- }
- step >>= 1;
- if (diff >= step)
- {
- encoded |= 2;
- diff -= step;
- }
- step >>= 1;
- if (diff >= step)
- encoded |= 1;
-
- decode (encoded, ssindex, signal, &zero_count, &next_flag);
-
- return (encoded);
-}
-
static struct ast_filestream *vox_open(int fd)
{
/* We don't have any header to read or anything really, but
@@ -263,31 +125,19 @@ static void vox_close(struct ast_filestream *s)
static struct ast_frame *vox_read(struct ast_filestream *s, int *whennext)
{
int res;
- int x;
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass = AST_FORMAT_ADPCM;
s->fr.offset = AST_FRIENDLY_OFFSET;
s->fr.mallocd = 0;
s->fr.data = s->buf;
- if ((res = read(s->fd, s->buf + BUF_SHIFT, BUF_SIZE)) < 1) {
+ if ((res = read(s->fd, s->buf, BUF_SIZE)) < 1) {
if (res)
ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
return NULL;
}
- /* Store index, then signal */
- s->buf[0] = s->ssindex & 0xff;
- s->buf[1] = (s->signal >> 8) & 0xff;
- s->buf[2] = s->signal & 0xff;
- s->buf[3] = s->zero_count;
- s->buf[4] = s->next_flag;
- /* Do the decoder to be sure we get the right stuff in the signal and index fields. */
- for (x=BUF_SHIFT;x<res+BUF_SHIFT;x++) {
- decode (s->buf[x] >> 4, &s->ssindex, &s->signal, &s->zero_count, &s->next_flag);
- decode (s->buf[x] & 0xf, &s->ssindex, &s->signal, &s->zero_count, &s->next_flag);
- }
s->fr.samples = res * 2;
- s->fr.datalen = res + BUF_SHIFT;
+ s->fr.datalen = res;
*whennext = s->fr.samples;
return &s->fr;
}
@@ -303,11 +153,7 @@ static int vox_write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-ADPCM frame (%d)!\n", f->subclass);
return -1;
}
- if (f->datalen < BUF_SHIFT) {
- ast_log(LOG_WARNING, "Invalid frame of data (< %d bytes long) from %s\n", BUF_SHIFT, f->src);
- return -1;
- }
- if ((res = write(fs->fd, f->data + BUF_SHIFT, f->datalen - BUF_SHIFT)) != f->datalen - BUF_SHIFT) {
+ if ((res = write(fs->fd, f->data, f->datalen)) != f->datalen) {
ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
return -1;
}
diff --git a/formats/format_wav_gsm.c b/formats/format_wav_gsm.c
index 5b502ff32..1d33caffb 100755
--- a/formats/format_wav_gsm.c
+++ b/formats/format_wav_gsm.c
@@ -68,7 +68,7 @@ static int glistcnt = 0;
static char *name = "wav49";
static char *desc = "Microsoft WAV format (Proprietary GSM)";
-static char *exts = "WAV";
+static char *exts = "WAV|wav49";
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define htoll(b) (b)
@@ -481,7 +481,7 @@ static int wav_write(struct ast_filestream *fs, struct ast_frame *f)
static int wav_seek(struct ast_filestream *fs, long sample_offset, int whence)
{
off_t offset=0,distance,cur,min,max;
- min = 52;
+ min = 60;
cur = lseek(fs->fd, 0, SEEK_CUR);
max = lseek(fs->fd, 0, SEEK_END);
/* I'm getting sloppy here, I'm only going to go to even splits of the 2
diff --git a/frame.c b/frame.c
index 97fe683d5..3c5fe8caf 100755
--- a/frame.c
+++ b/frame.c
@@ -80,7 +80,7 @@ int ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f)
ast_log(LOG_WARNING, "Out of smoother space\n");
return -1;
}
- if ((f->datalen == s->size) && !s->opt) {
+ if ((f->datalen == s->size) && !s->opt && (f->offset >= AST_MIN_OFFSET)) {
if (!s->len) {
/* Optimize by sending the frame we just got
on the next read, thus eliminating the douple
@@ -418,7 +418,7 @@ char *ast_codec2str(int codec) {
"GSM", /* 1 */
"G.711 u-law", /* 2 */
"G.711 A-law", /* 3 */
- "MPEG-2 layer 3", /* 4 */
+ "G.726", /* 4 */
"ADPCM", /* 5 */
"16 bit Signed Linear PCM", /* 6 */
"LPC10", /* 7 */
diff --git a/include/asterisk/adsi.h b/include/asterisk/adsi.h
index 87b18c31f..33d5a1ae9 100755
--- a/include/asterisk/adsi.h
+++ b/include/asterisk/adsi.h
@@ -96,8 +96,8 @@
#define ADSI_INFO_PAGE 0x0
#define ADSI_COMM_PAGE 0x1
-#define ADSI_KEY_APPS 16 /* 16 to 33 reserved for applications */
-
+#define ADSI_KEY_APPS 20 /* 16 to 33 reserved for applications */
+ /* Changed to 20 by MDH */
/* Justification */
#define ADSI_JUST_LEFT 0x2
#define ADSI_JUST_RIGHT 0x1
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 71043ea7c..24699a7d9 100755
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -843,6 +843,8 @@ static inline int ast_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
c->blocking = -1; \
} }
+extern unsigned int ast_get_group(char *s);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
diff --git a/include/asterisk/config.h b/include/asterisk/config.h
index ff8366042..e98df700f 100755
--- a/include/asterisk/config.h
+++ b/include/asterisk/config.h
@@ -87,6 +87,14 @@ char *ast_variable_retrieve(struct ast_config *config, char *category, char *val
*/
int ast_true(char *val);
+//! Make sure something is false
+/*!
+ * Determine falseness of a boolean value.
+ * This function checks to see whether a string passed to it is an indication of a negatirve value. It checks to see if the string is "no", "false", "n", "f", and "0".
+ * Returns 0 if the value of s is a NULL pointer, 0 on "truth", and -1 on falsehood.
+ */
+int ast_false(char *val);
+
//! Check for category duplicates
/*!
* \param config which config to use
diff --git a/include/asterisk/file.h b/include/asterisk/file.h
index 316e47112..55c0eaa7f 100755
--- a/include/asterisk/file.h
+++ b/include/asterisk/file.h
@@ -142,19 +142,19 @@ char ast_waitstream_full(struct ast_channel *c, char *breakon, int audiofd, int
//! Starts reading from a file
/*!
- * \param filename the name of the file to write to
- * \param type format of file you wish to write out to
+ * \param filename the name of the file to read from
+ * \param type format of file you wish to read from
* \param comment comment to go with
- * \param oflags output file flags
+ * \param flags file flags
* \param check (unimplemented, hence negligible)
* \param mode Open mode
- * Open an incoming file stream. oflags are flags for the open() command, and
- * if check is non-zero, then it will not write a file if there are any files that
+ * Open an incoming file stream. flags are flags for the open() command, and
+ * if check is non-zero, then it will not read a file if there are any files that
* start with that name and have an extension
* Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
* Returns a struct ast_filestream on success, NULL on failure
*/
-struct ast_filestream *ast_readfile(char *filename, char *type, char *comment, int oflags, int check, mode_t mode);
+struct ast_filestream *ast_readfile(char *filename, char *type, char *comment, int flags, int check, mode_t mode);
//! Starts writing a file
/*!
@@ -170,7 +170,7 @@ struct ast_filestream *ast_readfile(char *filename, char *type, char *comment, i
* Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
* Returns a struct ast_filestream on success, NULL on failure
*/
-struct ast_filestream *ast_writefile(char *filename, char *type, char *comment, int oflags, int check, mode_t mode);
+struct ast_filestream *ast_writefile(char *filename, char *type, char *comment, int flags, int check, mode_t mode);
//! Writes a frame to a stream
/*!
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index 95b1f6405..acbc26ca2 100755
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -20,6 +20,8 @@
extern "C" {
#endif
+#include <sys/types.h>
+
/*
* Autodetect system endianess
*/
@@ -52,8 +54,6 @@ extern "C" {
#error Need to know endianess
#endif /* __BYTE_ORDER */
-#include <sys/types.h>
-
//! Data structure associated with a single frame of data
/* A frame of data read used to communicate between
between channels and applications */
@@ -90,10 +90,10 @@ struct ast_frame_chain {
};
#define AST_FRIENDLY_OFFSET 64 /*! It's polite for a a new frame to
- have at least this number of bytes
- of offset before your real frame data
- so that additional headers can be
- added. */
+ have this number of bytes for additional
+ headers. */
+#define AST_MIN_OFFSET 32 /*! Make sure we keep at least this much handy */
+
/*! Need the header be free'd? */
#define AST_MALLOCD_HDR (1 << 0)
/*! Need the data be free'd? */
diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h
index 2b6182eba..aba263c09 100755
--- a/include/asterisk/lock.h
+++ b/include/asterisk/lock.h
@@ -16,12 +16,15 @@
#include <pthread.h>
+#define AST_PTHREADT_NULL (pthread_t) -1
+#define AST_PTHREADT_STOP (pthread_t) -2
+
#ifdef DEBUG_THREADS
+
#ifdef THREAD_CRASH
#define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
#endif
-
#include <errno.h>
#include <string.h>
#include <stdio.h>
@@ -29,12 +32,12 @@
// #define AST_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
// #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-#define AST_MUTEX_INITIALIZER { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, NULL, 0, NULL, 0 }
-#else
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#define AST_MUTEX_INITIALIZER { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, NULL, 0, NULL, 0 }
#else
+#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+#define AST_MUTEX_INITIALIZER { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, NULL, 0, NULL, 0 }
+#else
#define AST_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, NULL, 0, NULL, 0 }
#endif
#endif
@@ -161,7 +164,7 @@ static inline int __ast_pthread_mutex_destroy(char *filename, int lineno, char *
#define pthread_mutex_init use_ast_pthread_mutex_init_instead_of_pthread_mutex_init
#define pthread_mutex_destroy use_ast_pthread_mutex_destroy_instead_of_pthread_mutex_destroy
-#else
+#else /* DEBUG_THREADS */
#define AST_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#ifdef PTHREAD_MUTEX_FAST_NP
@@ -179,7 +182,7 @@ typedef pthread_mutex_t ast_mutex_t;
#define ast_pthread_mutex_init(t,a) pthread_mutex_init(t,a)
#define ast_mutex_destroy(t) pthread_mutex_destroy(t)
-#endif
+#endif /* DEBUG_THREADS */
#endif
diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h
index ac3a2b2dc..26abd9d22 100755
--- a/include/asterisk/manager.h
+++ b/include/asterisk/manager.h
@@ -66,7 +66,7 @@ struct mansession {
int writeperm;
char inbuf[MAX_LEN];
int inlen;
-
+ int send_events;
struct mansession *next;
};
@@ -84,6 +84,8 @@ struct manager_action {
struct manager_action *next;
};
+int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
+
/* External routines may register/unregister manager callbacks this way */
int ast_manager_register( char *action, int authority,
int (*func)(struct mansession *s, struct message *m), char *synopsis);
diff --git a/include/asterisk/options.h b/include/asterisk/options.h
index f9314bb1f..22a84138b 100755
--- a/include/asterisk/options.h
+++ b/include/asterisk/options.h
@@ -29,6 +29,7 @@ extern int fully_booted;
extern char defaultlanguage[];
extern time_t ast_startuptime;
extern time_t ast_lastreloadtime;
+extern int ast_mainpid;
#define VERBOSE_PREFIX_1 " "
#define VERBOSE_PREFIX_2 " == "
diff --git a/include/asterisk/parking.h b/include/asterisk/parking.h
index 785153696..4b9859592 100755
--- a/include/asterisk/parking.h
+++ b/include/asterisk/parking.h
@@ -48,8 +48,6 @@ extern char *ast_pickup_ext(void);
extern int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, int allowredirect_in, int allowredirect_out, int allowdisconnect);
-extern unsigned int ast_get_group(char *s);
-
extern int ast_pickup_call(struct ast_channel *chan);
diff --git a/indications.c b/indications.c
index 55e11ff8b..fefec9153 100755
--- a/indications.c
+++ b/indications.c
@@ -321,6 +321,8 @@ static inline void free_zone(struct tone_zone* zone)
free(zone->tones);
zone->tones = tmp;
}
+ if (zone->ringcadance)
+ free((void*)zone->ringcadance);
free(zone);
}
@@ -395,6 +397,8 @@ int ast_unregister_indication_country(const char *country)
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Unregistered indication country '%s'\n",tz->country);
free_zone(tz);
+ if (tone_zones == tz)
+ tone_zones = tmp;
tz = tmp;
res = 0;
}
diff --git a/loader.c b/loader.c
index 98ce7af19..f16ca45fc 100755
--- a/loader.c
+++ b/loader.c
@@ -136,6 +136,7 @@ int ast_unload_resource(char *resource_name, int force)
module_list = m->next;
dlclose(m->lib);
free(m);
+ break;
}
ml = m;
m = m->next;
diff --git a/logger.c b/logger.c
index a4f2bd355..9218220a1 100755
--- a/logger.c
+++ b/logger.c
@@ -49,6 +49,7 @@ static int syslog_level_map[] = {
static ast_mutex_t msglist_lock = AST_MUTEX_INITIALIZER;
static ast_mutex_t loglock = AST_MUTEX_INITIALIZER;
+static int pending_logger_reload = 0;
static struct msglist {
char *msg;
@@ -228,7 +229,6 @@ int reload_logger(int rotate)
FILE *myf;
int x;
-
ast_mutex_lock(&loglock);
if (eventlog)
fclose(eventlog);
@@ -295,6 +295,7 @@ int reload_logger(int rotate)
} else
ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
init_logger_chain();
+ pending_logger_reload = 0;
return -1;
}
@@ -345,10 +346,8 @@ static struct ast_cli_entry rotate_logger_cli =
logger_rotate_help };
static int handle_SIGXFSZ(int sig) {
- reload_logger(1);
- ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ\n");
- if (option_verbose)
- ast_verbose("Rotated Logs Per SIGXFSZ\n");
+ /* Indicate need to reload */
+ pending_logger_reload = 1;
return 0;
}
@@ -399,7 +398,7 @@ static void ast_log_vsyslog(int level, const char *file, int line, const char *f
levels[level], (long)pthread_self(), file, line, function);
}
vsnprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), fmt, args);
- syslog(syslog_level_map[level], buf);
+ syslog(syslog_level_map[level], "%s", buf);
}
/*
@@ -473,7 +472,7 @@ void ast_log(int level, const char *file, int line, const char *function, const
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- fprintf(chan->fileptr, buf);
+ fputs(buf, chan->fileptr);
fflush(chan->fileptr);
}
chan = chan->next;
@@ -487,12 +486,18 @@ void ast_log(int level, const char *file, int line, const char *function, const
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- fprintf(stdout, buf);
+ fputs(buf, stdout);
}
}
ast_mutex_unlock(&loglock);
/* end critical section */
+ if (pending_logger_reload) {
+ reload_logger(1);
+ ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ\n");
+ if (option_verbose)
+ ast_verbose("Rotated Logs Per SIGXFSZ\n");
+ }
}
extern void ast_verbose(const char *fmt, ...)
diff --git a/manager.c b/manager.c
index fe8d2769b..cbd641c5b 100755
--- a/manager.c
+++ b/manager.c
@@ -43,6 +43,7 @@ static int portno = DEFAULT_MANAGER_PORT;
static int asock = -1;
static pthread_t t;
static ast_mutex_t sessionlock = AST_MUTEX_INITIALIZER;
+static int block_sockets = 0;
static struct permalias {
int num;
@@ -62,6 +63,33 @@ static struct mansession *sessions = NULL;
static struct manager_action *first_action = NULL;
static ast_mutex_t actionlock = AST_MUTEX_INITIALIZER;
+int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
+{
+ /* Try to write string, but wait no more than ms milliseconds
+ before timing out */
+ int res=0;
+ struct timeval tv;
+ fd_set fds;
+ while(len) {
+ res = write(fd, s, len);
+ if ((res < 0) && (errno != EAGAIN)) {
+ return -1;
+ }
+ if (res < 0) res = 0;
+ len -= res;
+ s += res;
+ tv.tv_sec = timeoutms / 1000;
+ tv.tv_usec = timeoutms % 1000;
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ /* Wait until writable again */
+ res = select(fd + 1, NULL, &fds, NULL, &tv);
+ if (res < 1)
+ return -1;
+ }
+ return res;
+}
+
static int handle_showmancmds(int fd, int argc, char *argv[])
{
struct manager_action *cur = first_action;
@@ -199,6 +227,24 @@ static int get_perm(char *instr)
return ret;
}
+static int set_eventmask(struct mansession *s, char *eventmask)
+{
+ if (!eventmask)
+ return -1;
+ if (!strcasecmp(eventmask, "on") || ast_true(eventmask)) {
+ ast_mutex_lock(&s->lock);
+ s->send_events = 1;
+ ast_mutex_unlock(&s->lock);
+ return 1;
+ } else if (!strcasecmp(eventmask, "off") || ast_false(eventmask)) {
+ ast_mutex_lock(&s->lock);
+ s->send_events = 0;
+ ast_mutex_unlock(&s->lock);
+ return 0;
+ }
+ return -1;
+}
+
static int authenticate(struct mansession *s, struct message *m)
{
struct ast_config *cfg;
@@ -207,7 +253,8 @@ static int authenticate(struct mansession *s, struct message *m)
char *pass = astman_get_header(m, "Secret");
char *authtype = astman_get_header(m, "AuthType");
char *key = astman_get_header(m, "Key");
-
+ char *events = astman_get_header(m, "Events");
+
cfg = ast_load("manager.conf");
if (!cfg)
return -1;
@@ -272,6 +319,8 @@ static int authenticate(struct mansession *s, struct message *m)
s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read"));
s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write"));
ast_destroy(cfg);
+ if (events)
+ set_eventmask(s, events);
return 0;
}
ast_log(LOG_NOTICE, "%s tried to authenticate with non-existant user '%s'\n", inet_ntoa(s->sin.sin_addr), user);
@@ -285,6 +334,21 @@ static int action_ping(struct mansession *s, struct message *m)
return 0;
}
+static int action_events(struct mansession *s, struct message *m)
+{
+ char *mask = astman_get_header(m, "EventMask");
+ int res;
+
+ res = set_eventmask(s, mask);
+ if (res > 0)
+ astman_send_response(s, m, "Events On", NULL);
+ else if (res == 0)
+ astman_send_response(s, m, "Events Off", NULL);
+ else
+ astman_send_response(s, m, "EventMask parse error", NULL);
+ return 0;
+}
+
static int action_logoff(struct mansession *s, struct message *m)
{
astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
@@ -458,7 +522,12 @@ static int action_originate(struct mansession *s, struct message *m)
if (strlen(app)) {
res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 0, strlen(callerid) ? callerid : NULL, variable, account);
} else {
- res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 0, strlen(callerid) ? callerid : NULL, variable, account);
+ if (exten && context && pi)
+ res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 0, strlen(callerid) ? callerid : NULL, variable, account);
+ else {
+ astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
+ return 0;
+ }
}
if (!res)
astman_send_ack(s, m, "Originate successfully queued");
@@ -727,6 +796,7 @@ static void *accept_thread(void *ignore)
struct mansession *s;
struct protoent *p;
int arg = 1;
+ int flags;
pthread_attr_t attr;
pthread_attr_init(&attr);
@@ -752,8 +822,15 @@ static void *accept_thread(void *ignore)
}
memset(s, 0, sizeof(struct mansession));
memcpy(&s->sin, &sin, sizeof(sin));
+
+ if(! block_sockets) {
+ /* For safety, make sure socket is non-blocking */
+ flags = fcntl(as, F_GETFL);
+ fcntl(as, F_SETFL, flags | O_NONBLOCK);
+ }
ast_mutex_init(&s->lock);
s->fd = as;
+ s->send_events = 1;
ast_mutex_lock(&sessionlock);
s->next = sessions;
sessions = s;
@@ -774,14 +851,14 @@ int manager_event(int category, char *event, char *fmt, ...)
ast_mutex_lock(&sessionlock);
s = sessions;
while(s) {
- if ((s->readperm & category) == category) {
+ if (((s->readperm & category) == category) && s->send_events) {
ast_mutex_lock(&s->lock);
if (!s->blocking) {
ast_cli(s->fd, "Event: %s\r\n", event);
va_start(ap, fmt);
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
- write(s->fd, tmp, strlen(tmp));
+ ast_carefulwrite(s->fd,tmp,strlen(tmp),100);
ast_cli(s->fd, "\r\n");
}
ast_mutex_unlock(&s->lock);
@@ -867,6 +944,7 @@ int init_manager(void)
if (!registered) {
/* Register default actions */
ast_manager_register( "Ping", 0, action_ping, "Ping" );
+ ast_manager_register( "Events", 0, action_events, "Contol Event Flow" );
ast_manager_register( "Logoff", 0, action_logoff, "Logoff Manager" );
ast_manager_register( "Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel" );
ast_manager_register( "Status", EVENT_FLAG_CALL, action_status, "Status" );
@@ -894,6 +972,10 @@ int init_manager(void)
if (val)
enabled = ast_true(val);
+ val = ast_variable_retrieve(cfg, "general", "block-sockets");
+ if(val)
+ block_sockets = ast_true(val);
+
if ((val = ast_variable_retrieve(cfg, "general", "portno"))) {
if (sscanf(val, "%d", &portno) != 1) {
ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
@@ -911,7 +993,7 @@ int init_manager(void)
memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
}
}
-
+
if ((asock > -1) && ((portno != oldportno) || !enabled)) {
#if 0
/* Can't be done yet */
diff --git a/md5.c b/md5.c
index 543e8c581..cbd9312a9 100755
--- a/md5.c
+++ b/md5.c
@@ -1,6 +1,12 @@
/* MD5 checksum routines used for authentication. Not covered by GPL, but
in the public domain as per the copyright below */
-
+#if defined( __FreeBSD__ ) || defined( __OpenBSD__ )
+# include <sys/endian.h>
+#elif defined( BSD ) && ( BSD >= 199103 )
+# include <machine/endian.h>
+#else
+# include <endian.h>
+#endif
# if __BYTE_ORDER == __BIG_ENDIAN || BYTE_ORDER == BIG_ENDIAN
# define HIGHFIRST 1
# endif
diff --git a/pbx.c b/pbx.c
index 84f601644..a1346257e 100755
--- a/pbx.c
+++ b/pbx.c
@@ -338,8 +338,8 @@ static struct pbx_builtin {
{ "Wait", pbx_builtin_wait,
"Waits for some time",
-" Wait(seconds): Waits for a specified number of seconds, then returns 0.\n" },
-
+" Wait(seconds): Waits for a specified number of seconds, then returns 0.\n"
+"seconds can be passed with fractions of a second. (eg: 1.5 = 1.5 seconds)\n" },
};
/* Lock for the application list */
@@ -751,7 +751,20 @@ static void pbx_substitute_variables_temp(struct ast_channel *c,const char *var,
headp=&c->varshead;
*ret=NULL;
/* Now we have the variable name on cp3 */
- if ((first=strchr(var,':'))) {
+ if (!strncasecmp(var,"LEN(",4)) {
+ int len=strlen(var);
+ int len_len=4;
+ if (strrchr(var,')')) {
+ char cp3[80];
+ strncpy(cp3, var, sizeof(cp3) - 1);
+ cp3[len-len_len-1]='\0';
+ sprintf(workspace,"%d",strlen(cp3));
+ *ret = workspace;
+ } else {
+ /* length is zero */
+ *ret = "0";
+ }
+ } else if ((first=strchr(var,':'))) {
strncpy(tmpvar, var, sizeof(tmpvar) - 1);
first = strchr(tmpvar, ':');
if (!first)
@@ -926,17 +939,6 @@ static void pbx_substitute_variables_temp(struct ast_channel *c,const char *var,
}
}
}
- if (!(*ret) && !strncasecmp(var,"LEN(",4)) {
- int len=strlen(var);
- int len_len=4;
- if (len > (len_len+1) && !strncasecmp(var,"LEN(",len_len) && strchr(var+len_len+2,')')) {
- char cp3[80];
- strncpy(cp3, var, sizeof(cp3) - 1);
- cp3[len-len_len-1]='\0';
- sprintf(workspace,"%d",strlen(cp3));
- *ret = workspace;
- } else ast_log(LOG_NOTICE, "Wrong use of LEN(VARIABLE)\n");
- }
}
}
@@ -2930,12 +2932,12 @@ static void get_timerange(struct ast_include *i, char *times)
#if 1
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);
+ ast_log(LOG_WARNING, "%s isn't a valid start 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);
+ if ((e1 < 0) || (e1 >= 24*30)) {
+ ast_log(LOG_WARNING, "%s isn't a valid end time. Assuming no time.\n", e);
return;
}
/* Go through the time and enable each appropriate bit */
@@ -3303,7 +3305,7 @@ int ast_context_add_switch2(struct ast_context *con, char *value,
/* ... go to last sw and check if context is already swd too... */
i = con->alts;
while (i) {
- if (!strcasecmp(i->name, new_sw->name)) {
+ if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
free(new_sw);
ast_mutex_unlock(&con->lock);
errno = EEXIST;
@@ -3535,12 +3537,13 @@ int ast_async_goto(struct ast_channel *chan, char *context, char *exten, int pri
tmpchan->priority = priority;
else
tmpchan->priority = chan->priority;
- if (needlock)
- ast_mutex_unlock(&chan->lock);
/* Masquerade into temp channel */
ast_channel_masquerade(tmpchan, chan);
+ if (needlock)
+ ast_mutex_unlock(&chan->lock);
+
/* Make the masquerade happen by reading a frame from the tmp channel */
f = ast_read(tmpchan);
if (f)
@@ -3729,9 +3732,9 @@ int ast_add_extension2(struct ast_context *con,
tmp->peer = e;
} else {
/* We're the very first extension altogether */
- tmp->next = con->root;
+ tmp->next = con->root->next;
/* Con->root must always exist or we couldn't get here */
- tmp->peer = con->root->peer;
+ tmp->peer = con->root;
con->root = tmp;
}
ast_mutex_unlock(&con->lock);
@@ -4066,6 +4069,7 @@ void __ast_context_destroy(struct ast_context *con, char *registrar, int lock)
struct ast_include *tmpi, *tmpil= NULL;
struct ast_sw *sw, *swl= NULL;
struct ast_exten *e, *el, *en;
+ struct ast_ignorepat *ipi, *ipl = NULL;
if (lock)
ast_mutex_lock(&conlock);
tmp = contexts;
@@ -4090,9 +4094,15 @@ void __ast_context_destroy(struct ast_context *con, char *registrar, int lock)
tmpil = tmpi;
tmpi = tmpi->next;
free(tmpil);
- tmpil = tmpi;
+ }
+ for (ipi = tmp->ignorepats; ipi; ) {
+ /* Free ignorepats */
+ ipl = ipi;
+ ipi = ipi->next;
+ free(ipl);
}
for (sw = tmp->alts; sw; ) {
+ /* Free switches */
swl = sw;
sw = sw->next;
free(swl);
@@ -4276,8 +4286,8 @@ static int pbx_builtin_wait(struct ast_channel *chan, void *data)
{
int ms;
/* Wait for "n" seconds */
- if (data && atoi((char *)data)) {
- ms = atoi((char *)data) * 1000;
+ if (data && atof((char *)data)) {
+ ms = atof((char *)data) * 1000;
return ast_safe_sleep(chan, ms);
}
return 0;
@@ -4304,7 +4314,7 @@ static int pbx_builtin_background(struct ast_channel *chan, void *data)
static int pbx_builtin_atimeout(struct ast_channel *chan, void *data)
{
int x = atoi((char *) data);
- /* Set the timeout for how long to wait between digits */
+ /* Set the absolute maximum time how long a call can be connected */
ast_channel_setwhentohangup(chan,x);
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Set Absolute Timeout to %d\n", x);
diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c
index e017be79c..be87fff1c 100755
--- a/pbx/pbx_config.c
+++ b/pbx/pbx_config.c
@@ -1576,7 +1576,7 @@ static int pbx_load_module(void)
}
cxt = ast_category_browse(cfg, NULL);
while(cxt) {
- /* All categories but "general" are considered contexts */
+ /* All categories but "general" or "globals" are considered contexts */
if (!strcasecmp(cxt, "general") || !strcasecmp(cxt, "globals")) {
cxt = ast_category_browse(cfg, cxt);
continue;
diff --git a/pbx/pbx_spool.c b/pbx/pbx_spool.c
index d456810bb..d5e2b960f 100755
--- a/pbx/pbx_spool.c
+++ b/pbx/pbx_spool.c
@@ -50,6 +50,8 @@ struct outgoing {
int retrytime;
/* How long to wait for an answer */
int waittime;
+ /* PID which is currently calling */
+ int callingpid;
/* What to connect to outgoing */
char tech[256];
@@ -157,6 +159,14 @@ static int apply_outgoing(struct outgoing *o, char *fn, FILE *f)
}
} else if (!strcasecmp(buf, "retry")) {
o->retries++;
+ } else if (!strcasecmp(buf, "startretry")) {
+ if (sscanf(c, "%d", &o->callingpid) != 1) {
+ ast_log(LOG_WARNING, "Unable to retrieve calling PID!\n");
+ o->callingpid = 0;
+ }
+ } else if (!strcasecmp(buf, "endretry") || !strcasecmp(buf, "abortretry")) {
+ o->callingpid = 0;
+ o->retries++;
} else if (!strcasecmp(buf, "setvar")) { /* JDG variable support */
strncat(o->variable, c, sizeof(o->variable) - strlen(o->variable) - 1);
strncat(o->variable, "|", sizeof(o->variable) - strlen(o->variable) - 1);
@@ -182,6 +192,21 @@ static int apply_outgoing(struct outgoing *o, char *fn, FILE *f)
return 0;
}
+static void safe_append(struct outgoing *o, time_t now, char *s)
+{
+ int fd;
+ FILE *f;
+ fd = open(o->fn, O_WRONLY|O_APPEND);
+ if (fd > -1) {
+ f = fdopen(fd, "a");
+ if (f) {
+ fprintf(f, "%s: %d (%ld) (%ld)\n", s, o->retries, (long)ast_mainpid, (long) now);
+ fclose(f);
+ } else
+ close(fd);
+ }
+}
+
static void *attempt_thread(void *data)
{
struct outgoing *o = data;
@@ -201,6 +226,9 @@ static void *attempt_thread(void *data)
/* Max retries exceeded */
ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt(s)\n", o->tech, o->dest, o->retries - 1);
unlink(o->fn);
+ } else {
+ /* Notate that the call is still active */
+ safe_append(o, time(NULL), "EndRetry");
}
} else {
ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest);
@@ -234,23 +262,32 @@ static int scan_service(char *fn, time_t now, time_t atime)
f = fopen(fn, "r+");
if (f) {
if (!apply_outgoing(o, fn, f)) {
- /* Update the file time */
- tbuf.actime = atime;
- tbuf.modtime = now + o->retrytime;
- if (utime(o->fn, &tbuf))
- ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", fn, strerror(errno));
- /* Increment retries */
- o->retries++;
#if 0
printf("Retries: %d, max: %d\n", o->retries, o->maxretries);
#endif
- if (o->retries <= o->maxretries + 1) {
- /* Add a retry line at the end */
- fseek(f, 0L, SEEK_END);
- fprintf(f, "Retry: %d (%ld)\n", o->retries, (long) now);
- fclose(f);
+ if (o->retries <= o->maxretries) {
+ if (o->callingpid && (o->callingpid == ast_mainpid)) {
+ ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn);
+ } else {
+ /* Increment retries */
+ o->retries++;
+ /* If someone else was calling, they're presumably gone now
+ so abort their retry and continue as we were... */
+ if (o->callingpid)
+ safe_append(o, time(NULL), "AbortRetry");
+
+ /* Add a retry line at the end */
+ fseek(f, 0L, SEEK_END);
+ fprintf(f, "StartRetry: %d %d (%ld)\n", ast_mainpid, o->retries, (long) now);
+ fclose(f);
+ launch_service(o);
+ }
+ /* Update the file time */
+ tbuf.actime = atime;
+ tbuf.modtime = now + o->retrytime;
+ if (utime(o->fn, &tbuf))
+ ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", fn, strerror(errno));
now += o->retrytime;
- launch_service(o);
return now;
} else {
ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt(s)\n", o->tech, o->dest, o->retries - 1);
diff --git a/res/res_indications.c b/res/res_indications.c
index 0983efbca..78eb2a33d 100755
--- a/res/res_indications.c
+++ b/res/res_indications.c
@@ -238,6 +238,7 @@ static int ind_load_module(void)
tones = malloc(sizeof(struct tone_zone));
if (!tones) {
ast_log(LOG_WARNING,"Out of memory\n");
+ ast_destroy(cfg);
return -1;
}
memset(tones,0,sizeof(struct tone_zone));
@@ -261,6 +262,7 @@ static int ind_load_module(void)
tmp = realloc(tones->ringcadance,(tones->nrringcadance+1)*sizeof(int));
if (!tmp) {
ast_log(LOG_WARNING, "Out of memory\n");
+ ast_destroy(cfg);
return -1;
}
tones->ringcadance = tmp;
@@ -277,6 +279,7 @@ static int ind_load_module(void)
struct tone_zone* azone = malloc(sizeof(struct tone_zone));
if (!azone) {
ast_log(LOG_WARNING,"Out of memory\n");
+ ast_destroy(cfg);
return -1;
}
memset(azone,0,sizeof(struct tone_zone));
@@ -303,6 +306,7 @@ static int ind_load_module(void)
ts = malloc(sizeof(struct tone_zone_sound));
if (!ts) {
ast_log(LOG_WARNING, "Out of memory\n");
+ ast_destroy(cfg);
return -1;
}
ts->next = NULL;
diff --git a/res/res_monitor.c b/res/res_monitor.c
index 676cb3258..30fa47ac8 100755
--- a/res/res_monitor.c
+++ b/res/res_monitor.c
@@ -203,7 +203,7 @@ int ast_monitor_stop( struct ast_channel *chan, int need_lock )
}
}
if (chan->monitor->joinfiles && strlen(chan->monitor->filename_base)) {
- char tmp[255];
+ char tmp[1024];
char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format;
char *name = chan->monitor->filename_base;
int directory = strchr(name, '/') ? 1 : 0;
diff --git a/res/res_parking.c b/res/res_parking.c
index 5c8049822..000defe7c 100755
--- a/res/res_parking.c
+++ b/res/res_parking.c
@@ -164,7 +164,6 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
"From: %s\r\n"
"Timeout: %ld\r\n"
"CallerID: %s\r\n"
- "\r\n"
,pu->parkingnum, pu->chan->name, peer->name
,(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL)
,(pu->chan->callerid ? pu->chan->callerid : "")
@@ -749,40 +748,6 @@ int ast_pickup_call(struct ast_channel *chan)
return res;
}
-unsigned int ast_get_group(char *s)
-{
- char *copy;
- char *piece;
- char *c=NULL;
- int start=0, finish=0,x;
- unsigned int group = 0;
- copy = ast_strdupa(s);
- if (!copy) {
- ast_log(LOG_ERROR, "Out of memory\n");
- return 0;
- }
- c = copy;
-
- while((piece = strsep(&c, ","))) {
- if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
- /* Range */
- } else if (sscanf(piece, "%d", &start)) {
- /* Just one */
- finish = start;
- } else {
- ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'. Using '0'\n", s,piece);
- return 0;
- }
- for (x=start;x<=finish;x++) {
- if ((x > 31) || (x < 0)) {
- ast_log(LOG_WARNING, "Ignoring invalid group %d\n", x);
- } else
- group |= (1 << x);
- }
- }
- return group;
-}
-
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
diff --git a/rtp.c b/rtp.c
index 023353e19..5d2b4374e 100755
--- a/rtp.c
+++ b/rtp.c
@@ -75,6 +75,7 @@ struct ast_rtp {
struct sockaddr_in them;
struct timeval rxcore;
struct timeval txcore;
+ struct timeval dtmfmute;
struct ast_smoother *smoother;
int *ioid;
unsigned short seqno;
@@ -163,7 +164,17 @@ void ast_rtp_setnat(struct ast_rtp *rtp, int nat)
static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
{
- ast_log(LOG_DEBUG, "Sending dtmf: %d (%c)\n", rtp->resp, rtp->resp);
+ struct timeval tv;
+ static struct ast_frame null_frame = { AST_FRAME_NULL, };
+ gettimeofday(&tv, NULL);
+ if ((tv.tv_sec < rtp->dtmfmute.tv_sec) ||
+ ((tv.tv_sec == rtp->dtmfmute.tv_sec) && (tv.tv_usec < rtp->dtmfmute.tv_usec))) {
+ ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", inet_ntoa(rtp->them.sin_addr));
+ rtp->resp = 0;
+ rtp->dtmfduration = 0;
+ return &null_frame;
+ }
+ ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, inet_ntoa(rtp->them.sin_addr));
rtp->f.frametype = AST_FRAME_DTMF;
rtp->f.subclass = rtp->resp;
rtp->f.datalen = 0;
@@ -389,6 +400,11 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
ast_log(LOG_DEBUG, "RTP NAT: Using address %s:%d\n", inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
}
}
+ /* Ignore if the other side hasn't been given an address
+ yet. */
+ if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
+ return &null_frame;
+
/* Get fields */
seqno = ntohl(rtpheader[0]);
payloadtype = (seqno & 0x7f0000) >> 16;
@@ -862,6 +878,13 @@ int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
if (!rtp->them.sin_addr.s_addr)
return 0;
+ gettimeofday(&rtp->dtmfmute, NULL);
+ rtp->dtmfmute.tv_usec += (500 * 1000);
+ if (rtp->dtmfmute.tv_usec > 1000000) {
+ rtp->dtmfmute.tv_usec -= 1000000;
+ rtp->dtmfmute.tv_sec += 1;
+ }
+
ms = calc_txstamp(rtp);
/* Default prediction */
pred = rtp->lastts + ms * 8;
@@ -884,8 +907,8 @@ int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
if (x ==0) {
/* Clear marker bit and increment seqno */
rtpheader[0] = htonl((2 << 30) | (101 << 16) | (rtp->seqno++));
- /* Make duration 240 */
- rtpheader[3] |= htonl((240));
+ /* Make duration 800 (100ms) */
+ rtpheader[3] |= htonl((800));
/* Set the End bit for the last 3 */
rtpheader[3] |= htonl((1 << 23));
}
@@ -1200,7 +1223,7 @@ int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, st
codec0 = pr0->get_codec(c0);
codec1 = pr1->get_codec(c1);
/* Hey, we can't do reinvite if both parties speak diffrent codecs */
- if (codec0 != codec1) {
+ if (!(codec0 & codec1)) {
ast_log(LOG_WARNING, "codec0 = %d is not codec1 = %d, cannot native bridge.\n",codec0,codec1);
ast_mutex_unlock(&c0->lock);
ast_mutex_unlock(&c1->lock);
diff --git a/sample.call b/sample.call
index 47e105c2b..50b9fa88c 100755
--- a/sample.call
+++ b/sample.call
@@ -42,3 +42,8 @@ Priority: 1
#SetVar: file1=/tmp/to
#SetVar: file2=/tmp/msg
#SetVar: timestamp=20021023104500
+
+#
+# You may specify an account to be passed to CDRs
+#
+#Account: markster
diff --git a/say.c b/say.c
index 52fc5b90c..2ca660500 100755
--- a/say.c
+++ b/say.c
@@ -94,8 +94,11 @@ int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *lan
if (0) {
/* XXX Only works for english XXX */
} else {
- /* Use english numbers */
- language = "en";
+ /* Use english numbers if a given language is supported. */
+ /* As a special case, Norwegian has the same numerical grammar
+ as English */
+ if (strcasecmp(language, "no"))
+ language = "en";
while(!res && (num || playh)) {
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
diff --git a/srv.c b/srv.c
index c49abbf14..299d3eed3 100755
--- a/srv.c
+++ b/srv.c
@@ -79,8 +79,10 @@ static int srv_callback(void *context, u_char *answer, int len, u_char *fullansw
{
struct srv_context *c = (struct srv_context *)context;
- if (parse_srv(c->host, c->hostlen, c->port, answer, len, fullanswer))
+ if (parse_srv(c->host, c->hostlen, c->port, answer, len, fullanswer)) {
ast_log(LOG_WARNING, "Failed to parse srv\n");
+ return -1;
+ }
if (strlen(c->host))
return 1;
diff --git a/translate.c b/translate.c
index 0514bb984..c537d5973 100755
--- a/translate.c
+++ b/translate.c
@@ -29,13 +29,6 @@
#include <string.h>
#include <stdio.h>
-/* Uncomment the EXPERIMENTAL_TRANSLATION to enable a more complicated, but probably more
- correct way of handling full duplex translation */
-
-/*
-#define EXPERIMENTAL_TRANSLATION
-*/
-
/* This could all be done more efficiently *IF* we chained packets together
by default, but it would also complicate virtually every application. */
@@ -77,10 +70,11 @@ static int powerof(int d)
void ast_translator_free_path(struct ast_trans_pvt *p)
{
- struct ast_trans_pvt *pl;
- while(p) {
- pl = p;
- p = p->next;
+ struct ast_trans_pvt *pl, *pn;
+ pn = p;
+ while(pn) {
+ pl = pn;
+ pn = pn->next;
if (pl->state && pl->step->destroy)
pl->step->destroy(pl->state);
free(pl);
@@ -264,17 +258,16 @@ static int show_translation(int fd, int argc, char *argv[])
for (x=-1;x<SHOW_TRANS; x++) {
strcpy(line, " ");
for (y=-1;y<SHOW_TRANS;y++) {
- /* Skip MP3 (y = 4) as Destination format */
- if (y != 4 && x >= 0 && y >= 0 && tr_matrix[x][y].step)
- snprintf(line + strlen(line), sizeof(line) - strlen(line), " %6d", tr_matrix[x][y].cost);
+ if (x >= 0 && y >= 0 && tr_matrix[x][y].step)
+ snprintf(line + strlen(line), sizeof(line) - strlen(line), " %5d", tr_matrix[x][y].cost >= 99999 ? tr_matrix[x][y].cost-99999 : tr_matrix[x][y].cost);
else
- if ((y != 4) && ((x == -1 && y >= 0) || (y == -1 && x >= 0))) {
+ if (((x == -1 && y >= 0) || (y == -1 && x >= 0))) {
snprintf(line + strlen(line), sizeof(line) - strlen(line),
- " %6s", ast_getformatname(1<<(x+y+1)) );
- } else if (x != -1 && y != -1 && y != 4) {
- snprintf(line + strlen(line), sizeof(line) - strlen(line), " -");
- } else if (y != 4) {
- snprintf(line + strlen(line), sizeof(line) - strlen(line), " ");
+ " %5s", ast_getformatname(1<<(x+y+1)) );
+ } else if (x != -1 && y != -1 ) {
+ snprintf(line + strlen(line), sizeof(line) - strlen(line), " -");
+ } else {
+ snprintf(line + strlen(line), sizeof(line) - strlen(line), " ");
}
}
snprintf(line + strlen(line), sizeof(line) - strlen(line), "\n");
diff --git a/utils/astman.c b/utils/astman.c
index f7ce241ac..5ed355265 100755
--- a/utils/astman.c
+++ b/utils/astman.c
@@ -170,6 +170,7 @@ static struct event {
{ "Status", event_status },
{ "Link", event_ignore },
{ "Unlink", event_ignore },
+ { "StatusComplete", event_ignore }
};
static int process_message(struct ast_mansession *s, struct message *m)