aboutsummaryrefslogtreecommitdiffstats
path: root/channels
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 /channels
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
Diffstat (limited to 'channels')
-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
15 files changed, 408 insertions, 252 deletions
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);