diff options
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 |
commit | d46468f42c6762ce7646e773c7d0919ed1f626d4 (patch) | |
tree | 5d62a34385385b3485137835b2629174ca0464cf /channels | |
parent | f38bc8131c9eda8d0b0eabaafbaa53f4247989c4 (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-x | channels/Makefile | 16 | ||||
-rwxr-xr-x | channels/chan_agent.c | 17 | ||||
-rwxr-xr-x | channels/chan_alsa.c | 43 | ||||
-rwxr-xr-x | channels/chan_h323.c | 10 | ||||
-rwxr-xr-x | channels/chan_iax.c | 10 | ||||
-rwxr-xr-x | channels/chan_iax2.c | 277 | ||||
-rwxr-xr-x | channels/chan_mgcp.c | 10 | ||||
-rwxr-xr-x | channels/chan_modem.c | 10 | ||||
-rwxr-xr-x | channels/chan_nbs.c | 4 | ||||
-rwxr-xr-x | channels/chan_phone.c | 10 | ||||
-rwxr-xr-x | channels/chan_sip.c | 151 | ||||
-rwxr-xr-x | channels/chan_skinny.c | 10 | ||||
-rwxr-xr-x | channels/chan_vofr.c | 8 | ||||
-rwxr-xr-x | channels/chan_zap.c | 78 | ||||
-rwxr-xr-x | channels/iax2-parser.c | 6 |
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); |