[svn-commits] nadi: branch group/trunk-cm-csel-hash r48386 - in /team/group/trunk-cm-csel-h...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Mon Dec 11 03:47:36 MST 2006


Author: nadi
Date: Mon Dec 11 04:47:35 2006
New Revision: 48386

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48386
Log:
Merged revisions 48351,48358-48360,48364-48365,48373,48376,48378,48380,48383-48384 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r48351 | rizzo | 2006-12-07 17:42:29 +0100 (Do, 07 Dez 2006) | 19 lines

- Generalize the function ssl_setup() so that the certificate info
  are passed as an argument.

- Update the code in main/http.c to use the new interface
  (the diff is large but mostly mechanical, due to the name change of
  several variables);

- And since now it is trivial, implement "AMI over TLS", and document
  the possible options in manager.conf

- And since the test client (openssl s_client -connect host:port )
  does not generate \r\n as a line terminator, make get_input()
  also accept just a \n as a line terminator (Mac users: do you
  also need the \r-only version ?)
 
The option parsing in manager.conf is not very efficient, and needs
to be cleaned up and made similar to what we have in http.conf


................
r48358 | russell | 2006-12-07 19:21:21 +0100 (Do, 07 Dez 2006) | 19 lines

Merged revisions 48357 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

................
r48357 | russell | 2006-12-07 13:17:28 -0500 (Thu, 07 Dec 2006) | 11 lines

Merged revisions 48356 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r48356 | russell | 2006-12-07 13:14:13 -0500 (Thu, 07 Dec 2006) | 3 lines

Ensure that the file position is not incremented beyond the total number of
files available for playback.  (issue #8539, ulogic)

........

................

................
r48359 | russell | 2006-12-09 06:04:38 +0100 (Sa, 09 Dez 2006) | 6 lines

- Fix a few spelling mistakes
- Use sizeof() to pass an array size to a function
- Use a single bit for a variable in the chan_iax2_pvt stuct since that is all
  it needs.
- Add some comments about the iaxs, iaxl, and lastused arrays.

................
r48360 | russell | 2006-12-09 08:10:55 +0100 (Sa, 09 Dez 2006) | 11 lines

chan_iax2 has an extremely large function, socket_process(), to handle incoming
frames.  The function, before this commit, was roughly 1400 lines long.  So, I
am working on breaking this up into functions so that the code is easier to
follow and debug.  Also, I will be committing these changes in chunks as I do
them to ease tracking down any potentially introduced problems.

Break out roughly 150 lines from socket_process() and introduce a new function, 
socket_process_meta() which handles the parsing of an incoming meta frame.
Also, restructure some of this code a bit to reduce the deep nesting that was
in this code.

................
r48364 | russell | 2006-12-09 17:04:06 +0100 (Sa, 09 Dez 2006) | 16 lines

Merged revisions 48363 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r48363 | russell | 2006-12-09 10:59:42 -0500 (Sat, 09 Dec 2006) | 8 lines

Use locking when accessing the registrations list.  This list is not actually
used very often, so the likelihood of there being a problem is pretty small,
but still possible.  For example, if the CLI command to list the registrations
was called at the same time that a reload was occurring and the registrations
list was getting destroyed and rebuilt, a crash could occur.

In passing, go ahead and convert this list to use the linked list macros.

........

................
r48365 | russell | 2006-12-09 17:44:41 +0100 (Sa, 09 Dez 2006) | 2 lines

convert the thread IO state and type to use enums.

................
r48373 | murf | 2006-12-10 04:14:27 +0100 (So, 10 Dez 2006) | 17 lines

Merged revisions 48372 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

................
r48372 | murf | 2006-12-09 20:04:18 -0700 (Sat, 09 Dec 2006) | 9 lines

Merged revisions 48371 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r48371 | murf | 2006-12-09 19:14:13 -0700 (Sat, 09 Dec 2006) | 1 line

This version applies the patch suggested by stevens in bug 7836 (make inbound channel RINGING state consistent with other channels).
........

................

................
r48376 | tilghman | 2006-12-11 01:52:19 +0100 (Mo, 11 Dez 2006) | 21 lines

Merged revisions 48375 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

................
r48375 | tilghman | 2006-12-10 18:47:21 -0600 (Sun, 10 Dec 2006) | 13 lines

Merged revisions 48374 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r48374 | tilghman | 2006-12-10 18:33:59 -0600 (Sun, 10 Dec 2006) | 5 lines

When doing a fork() and exec(), two problems existed (Issue 8086):
1) Ignored signals stayed ignored after the exec().
2) Signals could possibly fire between the fork() and exec(), causing Asterisk
signal handlers within the child to execute, which caused nasty race conditions.

........

................

................
r48378 | file | 2006-12-11 06:01:37 +0100 (Mo, 11 Dez 2006) | 10 lines

Merged revisions 48377 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r48377 | file | 2006-12-10 23:57:38 -0500 (Sun, 10 Dec 2006) | 2 lines

Don't access the conference structure after it has been freed.

........

................
r48380 | file | 2006-12-11 06:34:53 +0100 (Mo, 11 Dez 2006) | 10 lines

Merged revisions 48379 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r48379 | file | 2006-12-11 00:30:01 -0500 (Mon, 11 Dec 2006) | 2 lines

Use the correct API call to say a device state changed. (Yes, I'm a nub.)

........

................
r48383 | file | 2006-12-11 06:38:57 +0100 (Mo, 11 Dez 2006) | 10 lines

Merged revisions 48381 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r48381 | file | 2006-12-11 00:36:45 -0500 (Mon, 11 Dec 2006) | 2 lines

Merge in my latest RTP changes. Break out RTP and RTCP callback functions so they no longer share a common one.

........

................
r48384 | tilghman | 2006-12-11 06:40:38 +0100 (Mo, 11 Dez 2006) | 10 lines

Merged revisions 48382 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r48382 | tilghman | 2006-12-10 23:37:09 -0600 (Sun, 10 Dec 2006) | 2 lines

STRFTIME() does not actually require an argument (issue 8540)

........

................

Modified:
    team/group/trunk-cm-csel-hash/   (props changed)
    team/group/trunk-cm-csel-hash/apps/app_externalivr.c
    team/group/trunk-cm-csel-hash/apps/app_festival.c
    team/group/trunk-cm-csel-hash/apps/app_ices.c
    team/group/trunk-cm-csel-hash/apps/app_meetme.c
    team/group/trunk-cm-csel-hash/apps/app_mp3.c
    team/group/trunk-cm-csel-hash/apps/app_nbscat.c
    team/group/trunk-cm-csel-hash/apps/app_zapras.c
    team/group/trunk-cm-csel-hash/channels/chan_iax2.c
    team/group/trunk-cm-csel-hash/channels/chan_zap.c
    team/group/trunk-cm-csel-hash/configs/manager.conf.sample
    team/group/trunk-cm-csel-hash/funcs/func_strings.c
    team/group/trunk-cm-csel-hash/include/asterisk/http.h
    team/group/trunk-cm-csel-hash/main/http.c
    team/group/trunk-cm-csel-hash/main/manager.c
    team/group/trunk-cm-csel-hash/main/rtp.c
    team/group/trunk-cm-csel-hash/res/res_agi.c
    team/group/trunk-cm-csel-hash/res/res_musiconhold.c

Propchange: team/group/trunk-cm-csel-hash/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/group/trunk-cm-csel-hash/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Dec 11 04:47:35 2006
@@ -1,1 +1,1 @@
-/trunk:1-48350
+/trunk:1-48384

Modified: team/group/trunk-cm-csel-hash/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/apps/app_externalivr.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/apps/app_externalivr.c (original)
+++ team/group/trunk-cm-csel-hash/apps/app_externalivr.c Mon Dec 11 04:47:35 2006
@@ -40,6 +40,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
+#include <signal.h>
 
 #include "asterisk/lock.h"
 #include "asterisk/file.h"
@@ -262,9 +263,13 @@
 		.finishlist = AST_LIST_HEAD_INIT_VALUE,
 	};
 	struct ivr_localuser *u = &foo;
+	sigset_t fullset, oldset;
 
 	lu = ast_module_user_add(chan);
-	
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+
 	u->abort_current_sound = 0;
 	u->chan = chan;
 	
@@ -312,6 +317,9 @@
 	if (!pid) {
 		/* child process */
 		int i;
+
+		signal(SIGPIPE, SIG_DFL);
+		pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
 
 		if (ast_opt_high_priority)
 			ast_set_priority(0);
@@ -335,6 +343,8 @@
 		int ready_fd;
 		int waitfds[2] = { child_errors_fd, child_commands_fd };
 		struct ast_channel *rchan;
+
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 
 		close(child_stdin[0]);
 		child_stdin[0] = 0;

Modified: team/group/trunk-cm-csel-hash/apps/app_festival.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/apps/app_festival.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/apps/app_festival.c (original)
+++ team/group/trunk-cm-csel-hash/apps/app_festival.c Mon Dec 11 04:47:35 2006
@@ -130,19 +130,26 @@
 #ifdef __PPC__ 
 	char c;
 #endif
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
 
         res = fork();
         if (res < 0)
                 ast_log(LOG_WARNING, "Fork failed\n");
-        if (res)
+        if (res) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
                 return res;
+	}
         for (x=0;x<256;x++) {
                 if (x != fd)
                         close(x);
         }
 	if (ast_opt_high_priority)
 		ast_set_priority(0);
-
+	signal(SIGPIPE, SIG_DFL);
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
 /*IAS */
 #ifdef __PPC__  
 	for( x=0; x<length; x+=2)

Modified: team/group/trunk-cm-csel-hash/apps/app_ices.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/apps/app_ices.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/apps/app_ices.c (original)
+++ team/group/trunk-cm-csel-hash/apps/app_ices.c Mon Dec 11 04:47:35 2006
@@ -65,15 +65,27 @@
 {
 	int res;
 	int x;
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+
 	res = fork();
 	if (res < 0) 
 		ast_log(LOG_WARNING, "Fork failed\n");
-	if (res)
+	if (res) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 		return res;
+	}
+
+	/* Stop ignoring PIPE */
+	signal(SIGPIPE, SIG_DFL);
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
+
 	if (ast_opt_high_priority)
 		ast_set_priority(0);
 	dup2(fd, STDIN_FILENO);
-	for (x=STDERR_FILENO + 1;x<256;x++) {
+	for (x=STDERR_FILENO + 1;x<1024;x++) {
 		if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
 			close(x);
 	}
@@ -84,7 +96,7 @@
 	/* As a last-ditch effort, try to use PATH */
 	execlp("ices", "ices", filename, (char *)NULL);
 	ast_log(LOG_WARNING, "Execute of ices failed\n");
-	return -1;
+	_exit(0);
 }
 
 static int ices_exec(struct ast_channel *chan, void *data)

Modified: team/group/trunk-cm-csel-hash/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/apps/app_meetme.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/apps/app_meetme.c (original)
+++ team/group/trunk-cm-csel-hash/apps/app_meetme.c Mon Dec 11 04:47:35 2006
@@ -1945,6 +1945,13 @@
 			conf->markedusers--;
 		/* Remove ourselves from the list */
 		AST_LIST_REMOVE(&conf->userlist, user, list);
+
+		/* Change any states */
+		if (!conf->users)
+			ast_device_state_changed("meetme:%s", conf->confno);
+		if (confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))
+			ast_device_state_changed("SLA:%s", conf->confno + 4);
+
 		if (AST_LIST_EMPTY(&conf->userlist)) {
 			/* close this one when no more users and no references*/
 			if (!conf->refcount)
@@ -1953,12 +1960,6 @@
 		/* Return the number of seconds the user was in the conf */
 		snprintf(meetmesecs, sizeof(meetmesecs), "%d", (int) (time(NULL) - user->jointime));
 		pbx_builtin_setvar_helper(chan, "MEETMESECS", meetmesecs);
-
-		/* This device changed state now */
-		if (!conf->users)	/* If there are no more members */
-			ast_device_state_changed("meetme:%s", conf->confno);
-		if (confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))
-			ast_device_state_changed("SLA:%s", conf->confno + 4);
 	}
 	free(user);
 	AST_LIST_UNLOCK(&confs);

Modified: team/group/trunk-cm-csel-hash/apps/app_mp3.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/apps/app_mp3.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/apps/app_mp3.c (original)
+++ team/group/trunk-cm-csel-hash/apps/app_mp3.c Mon Dec 11 04:47:35 2006
@@ -64,15 +64,25 @@
 {
 	int res;
 	int x;
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+
 	res = fork();
 	if (res < 0) 
 		ast_log(LOG_WARNING, "Fork failed\n");
-	if (res)
+	if (res) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 		return res;
+	}
 	if (ast_opt_high_priority)
 		ast_set_priority(0);
+	signal(SIGPIPE, SIG_DFL);
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
+
 	dup2(fd, STDOUT_FILENO);
-	for (x=0;x<256;x++) {
+	for (x=STDERR_FILENO + 1;x<256;x++) {
 		if (x != STDOUT_FILENO)
 			close(x);
 	}
@@ -94,7 +104,7 @@
 	    execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
 	}
 	ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
-	return -1;
+	_exit(0);
 }
 
 static int timed_read(int fd, void *data, int datalen, int timeout)

Modified: team/group/trunk-cm-csel-hash/apps/app_nbscat.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/apps/app_nbscat.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/apps/app_nbscat.c (original)
+++ team/group/trunk-cm-csel-hash/apps/app_nbscat.c Mon Dec 11 04:47:35 2006
@@ -68,16 +68,26 @@
 {
 	int res;
 	int x;
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
+
 	res = fork();
 	if (res < 0) 
 		ast_log(LOG_WARNING, "Fork failed\n");
-	if (res)
+	if (res) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 		return res;
+	}
+	signal(SIGPIPE, SIG_DFL);
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
+
 	if (ast_opt_high_priority)
 		ast_set_priority(0);
 
 	dup2(fd, STDOUT_FILENO);
-	for (x=0;x<256;x++) {
+	for (x = STDERR_FILENO + 1; x < 1024; x++) {
 		if (x != STDOUT_FILENO)
 			close(x);
 	}
@@ -85,7 +95,7 @@
 	execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
 	execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
 	ast_log(LOG_WARNING, "Execute of nbscat8k failed\n");
-	return -1;
+	_exit(0);
 }
 
 static int timed_read(int fd, void *data, int datalen)

Modified: team/group/trunk-cm-csel-hash/apps/app_zapras.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/apps/app_zapras.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/apps/app_zapras.c (original)
+++ team/group/trunk-cm-csel-hash/apps/app_zapras.c Mon Dec 11 04:47:35 2006
@@ -82,11 +82,23 @@
 	char *argv[PPP_MAX_ARGS];
 	int argc = 0;
 	char *stringp=NULL;
+	sigset_t fullset, oldset;
+
+	sigfillset(&fullset);
+	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
 
 	/* Start by forking */
 	pid = fork();
-	if (pid)
+	if (pid) {
+		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 		return pid;
+	}
+
+	/* Restore original signal handlers */
+	for (x=0;x<NSIG;x++)
+		signal(x, SIG_DFL);
+
+	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
 
 	/* Execute RAS on File handles */
 	dup2(chan->fds[0], STDIN_FILENO);
@@ -98,10 +110,6 @@
 	/* Close other file descriptors */
 	for (x=STDERR_FILENO + 1;x<1024;x++) 
 		close(x);
-
-	/* Restore original signal handlers */
-	for (x=0;x<NSIG;x++)
-		signal(x, SIG_DFL);
 
 	/* Reset all arguments */
 	memset(argv, 0, sizeof(argv));

Modified: team/group/trunk-cm-csel-hash/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/channels/chan_iax2.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/chan_iax2.c (original)
+++ team/group/trunk-cm-csel-hash/channels/chan_iax2.c Mon Dec 11 04:47:35 2006
@@ -141,7 +141,7 @@
 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
 
 
-/*! \brief Maximum transimission unit for the UDP packet in the trunk not to be
+/*! \brief Maximum transmission unit for the UDP packet in the trunk not to be
     fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240 */
 #define MAX_TRUNK_MTU 1240 
 
@@ -433,11 +433,11 @@
 	int messages;				/*!< Message count, low 8 bits = new, high 8 bits = old */
 	int callno;				/*!< Associated call number if applicable */
 	struct sockaddr_in us;			/*!< Who the server thinks we are */
-	struct iax2_registry *next;
 	struct ast_dnsmgr_entry *dnsmgr;	/*!< DNS refresh manager */
+	AST_LIST_ENTRY(iax2_registry) entry;
 };
 
-static struct iax2_registry *registrations;
+static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
 
 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
 #define MIN_RETRY_TIME		100
@@ -488,7 +488,7 @@
 	/*! Next outgoing timestamp if everything is good */
 	unsigned int nextpred;
 	/*! True if the last voice we transmitted was not silence/CNG */
-	int notsilenttx;
+	unsigned int notsilenttx:1;
 	/*! Ping time */
 	unsigned int pingtime;
 	/*! Max time for initial response */
@@ -593,7 +593,7 @@
 	enum iax_transfer_state transferring;
 	/*! Transfer identifier */
 	int transferid;
-	/*! Who we are IAX transfering to */
+	/*! Who we are IAX transferring to */
 	struct sockaddr_in transfer;
 	/*! What's the new call number for the transfer */
 	unsigned short transfercallno;
@@ -678,18 +678,22 @@
 static void destroy_peer(struct iax2_peer *peer);
 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
 
-#define IAX_IOSTATE_IDLE		0
-#define IAX_IOSTATE_READY		1
-#define IAX_IOSTATE_PROCESSING	2
-#define IAX_IOSTATE_SCHEDREADY	3
-
-#define IAX_TYPE_POOL    1
-#define IAX_TYPE_DYNAMIC 2
+enum iax2_thread_iostate {
+	IAX_IOSTATE_IDLE,
+	IAX_IOSTATE_READY,
+	IAX_IOSTATE_PROCESSING,
+	IAX_IOSTATE_SCHEDREADY,
+};
+
+enum iax2_thread_type {
+	IAX_THREAD_TYPE_POOL,
+	IAX_THREAD_TYPE_DYNAMIC,
+};
 
 struct iax2_thread {
 	AST_LIST_ENTRY(iax2_thread) list;
-	int type;
-	int iostate;
+	enum iax2_thread_type type;
+	enum iax2_thread_iostate iostate;
 #ifdef SCHED_MULTITHREADED
 	void (*schedfunc)(void *);
 	void *scheddata;
@@ -740,7 +744,7 @@
 	char buf[1024];
 
 	va_start(args, fmt);
-	vsnprintf(buf, 1024, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
 	ast_log(LOG_ERROR, buf);
@@ -752,7 +756,7 @@
 	char buf[1024];
 
 	va_start(args, fmt);
-	vsnprintf(buf, 1024, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
 	ast_log(LOG_WARNING, buf);
@@ -764,15 +768,48 @@
 	char buf[1024];
 
 	va_start(args, fmt);
-	vsnprintf(buf, 1024, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
 	ast_verbose(buf);
 }
 
-/* XXX We probably should use a mutex when working with this XXX */
+/*!
+ * \brief an array of iax2 pvt structures
+ *
+ * The container for active chan_iax2_pvt structures is implemented as an
+ * array for extremely quick direct access to the correct pvt structure
+ * based on the local call number.  The local call number is used as the
+ * index into the array where the associated pvt structure is stored.
+ */
 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
+/*!
+ * \brief chan_iax2_pvt structure locks
+ *
+ * These locks are used when accessing a pvt structure in the iaxs array.
+ * The index used here is the same as used in the iaxs array.  It is the
+ * local call number for the associated pvt struct.
+ */
 static ast_mutex_t iaxsl[IAX_MAX_CALLS];
+/*!
+ * \brief The last time a call number was used
+ *
+ * It is important to know the last time that a call number was used locally so
+ * that it is not used again too soon.  The reason for this is the same as the
+ * reason that the TCP protocol state machine requires a "TIME WAIT" state.
+ *
+ * For example, say that a call is up.  Then, the remote side sends a HANGUP,
+ * which we respond to with an ACK.  However, there is no way to know whether
+ * the ACK made it there successfully.  If it were to get lost, the remote
+ * side may retransmit the HANGUP.  If in the meantime, this call number has
+ * been reused locally, given the right set of circumstances, this retransmitted
+ * HANGUP could potentially improperly hang up the new session.  So, to avoid
+ * this potential issue, we must wait a specified timeout period before reusing
+ * a local call number.
+ *
+ * The specified time that we must wait before reusing a local call number is
+ * defined as MIN_REUSE_TIME, with a default of 60 seconds.
+ */
 static struct timeval lastused[IAX_MAX_CALLS];
 
 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
@@ -856,7 +893,7 @@
 			thread = ast_calloc(1, sizeof(*thread));
 			if (thread != NULL) {
 				thread->threadnum = iaxdynamicthreadcount;
-				thread->type = IAX_TYPE_DYNAMIC;
+				thread->type = IAX_THREAD_TYPE_DYNAMIC;
 				ast_mutex_init(&thread->lock);
 				ast_cond_init(&thread->cond, NULL);
 				if (ast_pthread_create(&thread->threadid, NULL, iax2_process_thread, thread)) {
@@ -1054,10 +1091,6 @@
 	}
 		
 	tmp->prefs = prefs;
-	tmp->callno = 0;
-	tmp->peercallno = 0;
-	tmp->transfercallno = 0;
-	tmp->bridgecallno = 0;
 	tmp->pingid = -1;
 	tmp->lagid = -1;
 	tmp->autoid = -1;
@@ -1580,7 +1613,7 @@
 
 static int handle_error(void)
 {
-	/* XXX Ideally we should figure out why an error occured and then abort those
+	/* XXX Ideally we should figure out why an error occurred and then abort those
 	   rather than continuing to try.  Unfortunately, the published interface does
 	   not seem to work XXX */
 #if 0
@@ -3840,7 +3873,7 @@
 
 	/* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
 	 * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
-	 * increment the "predicted timestamps" for voice, if we're predecting */
+	 * increment the "predicted timestamps" for voice, if we're predicting */
 	if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
 	    return 0;
 
@@ -4192,7 +4225,7 @@
 	ast_cli(fd, "Active Threads:\n");
 	AST_LIST_LOCK(&active_list);
 	AST_LIST_TRAVERSE(&active_list, thread, list) {
-		if (thread->type == IAX_TYPE_DYNAMIC)
+		if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
 			type = 'D';
 		else
 			type = 'P';
@@ -4300,9 +4333,9 @@
 	char perceived[80];
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
-	AST_LIST_LOCK(&peers);
 	ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
-	for (reg = registrations;reg;reg = reg->next) {
+	AST_LIST_LOCK(&registrations);
+	AST_LIST_TRAVERSE(&registrations, reg, entry) {
 		snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
 		if (reg->us.sin_addr.s_addr) 
 			snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
@@ -4312,7 +4345,7 @@
 					(reg->dnsmgr) ? "Y" : "N", 
 					reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
 	}
-	AST_LIST_UNLOCK(&peers);
+	AST_LIST_UNLOCK(&registrations);
 	return RESULT_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
@@ -5459,9 +5492,9 @@
 	reg->refresh = IAX_DEFAULT_REG_EXPIRE;
 	reg->addr.sin_family = AF_INET;
 	reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
-	reg->next = registrations;
-	reg->callno = 0;
-	registrations = reg;
+	AST_LIST_LOCK(&registrations);
+	AST_LIST_INSERT_HEAD(&registrations, reg, entry);
+	AST_LIST_UNLOCK(&registrations);
 	
 	return 0;
 }
@@ -6247,36 +6280,156 @@
 	return 1;
 }
 
+static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
+	struct iax_frame *fr)
+{
+	unsigned char metatype;
+	struct ast_iax2_meta_trunk_mini *mtm;
+	struct ast_iax2_meta_trunk_hdr *mth;
+	struct ast_iax2_meta_trunk_entry *mte;
+	struct iax2_trunk_peer *tpeer;
+	unsigned int ts;
+	void *ptr;
+	struct timeval rxtrunktime;
+	struct ast_frame f = { 0, };
+
+	if (packet_len < sizeof(*meta)) {
+		ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 
+			ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+		return 1;
+	}
+
+	if (meta->metacmd != IAX_META_TRUNK)
+		return 1;
+
+	if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
+		ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", packet_len,
+			sizeof(*meta) + sizeof(*mth));
+		return 1;
+	}
+	mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
+	ts = ntohl(mth->ts);
+	metatype = meta->cmddata;
+	packet_len -= (sizeof(*meta) + sizeof(*mth));
+	ptr = mth->data;
+	tpeer = find_tpeer(sin, sockfd);
+	if (!tpeer) {
+		ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 
+			ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+		return 1;
+	}
+	tpeer->trunkact = ast_tvnow();
+	if (!ts || ast_tvzero(tpeer->rxtrunktime))
+		tpeer->rxtrunktime = tpeer->trunkact;
+	rxtrunktime = tpeer->rxtrunktime;
+	ast_mutex_unlock(&tpeer->lock);
+	while (packet_len >= sizeof(*mte)) {
+		/* Process channels */
+		unsigned short callno, trunked_ts, len;
+
+		if (metatype == IAX_META_TRUNK_MINI) {
+			mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
+			ptr += sizeof(*mtm);
+			packet_len -= sizeof(*mtm);
+			len = ntohs(mtm->len);
+			callno = ntohs(mtm->mini.callno);
+			trunked_ts = ntohs(mtm->mini.ts);
+		} else if (metatype == IAX_META_TRUNK_SUPERMINI) {
+			mte = (struct ast_iax2_meta_trunk_entry *)ptr;
+			ptr += sizeof(*mte);
+			packet_len -= sizeof(*mte);
+			len = ntohs(mte->len);
+			callno = ntohs(mte->callno);
+			trunked_ts = 0;
+		} else {
+			ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+			break;
+		}
+		/* Stop if we don't have enough data */
+		if (len > packet_len)
+			break;
+		fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, 1, sockfd);
+		if (!fr->callno)
+			continue;
+
+		ast_mutex_lock(&iaxsl[fr->callno]);
+
+		/* If it's a valid call, deliver the contents.  If not, we
+		   drop it, since we don't have a scallno to use for an INVAL */
+		/* Process as a mini frame */
+		f.frametype = AST_FRAME_VOICE;
+		if (!iaxs[fr->callno]) {
+			/* drop it */
+		} else if (iaxs[fr->callno]->voiceformat == 0) {
+			ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
+			iax2_vnak(fr->callno);
+		} else {
+			f.subclass = iaxs[fr->callno]->voiceformat;
+			f.datalen = len;
+			if (f.datalen >= 0) {
+				if (f.datalen)
+					f.data = ptr;
+				else
+					f.data = NULL;
+				if (trunked_ts)
+					fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
+				else
+					fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
+				/* Don't pass any packets until we're started */
+				if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
+					struct iax_frame *duped_fr;
+
+					/* Common things */
+					f.src = "IAX2";
+					f.mallocd = 0;
+					f.offset = 0;
+					if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
+						f.samples = ast_codec_get_samples(&f);
+					else
+						f.samples = 0;
+					fr->outoforder = 0;
+					iax_frame_wrap(fr, &f);
+					duped_fr = iaxfrdup2(fr);
+					if (duped_fr)
+						schedule_delivery(duped_fr, 1, 1, &fr->ts);
+					if (iaxs[fr->callno]->last < fr->ts)
+						iaxs[fr->callno]->last = fr->ts;
+				}
+			} else {
+				ast_log(LOG_WARNING, "Datalen < 0?\n");
+			}
+		}
+		ast_mutex_unlock(&iaxsl[fr->callno]);
+		ptr += len;
+		packet_len -= len;
+	}
+
+	return 1;
+}
+
 static int socket_process(struct iax2_thread *thread)
 {
 	struct sockaddr_in sin;
 	int res;
 	int updatehistory=1;
 	int new = NEW_PREVENT;
-	void *ptr;
 	int dcallno = 0;
 	struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
 	struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
 	struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
 	struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
-	struct ast_iax2_meta_trunk_hdr *mth;
-	struct ast_iax2_meta_trunk_entry *mte;
-	struct ast_iax2_meta_trunk_mini *mtm;
 	struct iax_frame *fr;
 	struct iax_frame *cur;
 	struct ast_frame f;
 	struct ast_channel *c;
 	struct iax2_dpcache *dp;
 	struct iax2_peer *peer;
-	struct iax2_trunk_peer *tpeer;
-	struct timeval rxtrunktime;
 	struct iax_ies ies;
 	struct iax_ie_data ied0, ied1;
 	int format;
 	int fd;
 	int exists;
 	int minivid = 0;
-	unsigned int ts;
 	char empty[32]="";		/* Safety measure */
 	struct iax_frame *duped_fr;
 	char host_pref_buf[128];
@@ -6306,123 +6459,8 @@
 		/* This is a video frame, get call number */
 		fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd);
 		minivid = 1;
-	} else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
-		unsigned char metatype;
-
-		if (res < sizeof(*meta)) {
-			ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
-			return 1;
-		}
-
-		/* This is a meta header */
-		switch(meta->metacmd) {
-		case IAX_META_TRUNK:
-			if (res < (sizeof(*meta) + sizeof(*mth))) {
-				ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
-					sizeof(*meta) + sizeof(*mth));
-				return 1;
-			}
-			mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
-			ts = ntohl(mth->ts);
-			metatype = meta->cmddata;
-			res -= (sizeof(*meta) + sizeof(*mth));
-			ptr = mth->data;
-			tpeer = find_tpeer(&sin, fd);
-			if (!tpeer) {
-				ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
-				return 1;
-			}
-			tpeer->trunkact = ast_tvnow();
-			if (!ts || ast_tvzero(tpeer->rxtrunktime))
-				tpeer->rxtrunktime = tpeer->trunkact;
-			rxtrunktime = tpeer->rxtrunktime;
-			ast_mutex_unlock(&tpeer->lock);
-			while(res >= sizeof(*mte)) {
-				/* Process channels */
-				unsigned short callno, trunked_ts, len;
-
-				if (metatype == IAX_META_TRUNK_MINI) {
-					mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
-					ptr += sizeof(*mtm);
-					res -= sizeof(*mtm);
-					len = ntohs(mtm->len);
-					callno = ntohs(mtm->mini.callno);
-					trunked_ts = ntohs(mtm->mini.ts);
-				} else if (metatype == IAX_META_TRUNK_SUPERMINI) {
-					mte = (struct ast_iax2_meta_trunk_entry *)ptr;
-					ptr += sizeof(*mte);
-					res -= sizeof(*mte);
-					len = ntohs(mte->len);
-					callno = ntohs(mte->callno);
-					trunked_ts = 0;
-				} else {
-					ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
-					break;
-				}
-				/* Stop if we don't have enough data */
-				if (len > res)
-					break;
-				fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd);
-				if (fr->callno) {
-					ast_mutex_lock(&iaxsl[fr->callno]);
-					/* If it's a valid call, deliver the contents.  If not, we
-					   drop it, since we don't have a scallno to use for an INVAL */
-					/* Process as a mini frame */
-					f.frametype = AST_FRAME_VOICE;
-					if (iaxs[fr->callno]) {
-						if (iaxs[fr->callno]->voiceformat > 0) {
-							f.subclass = iaxs[fr->callno]->voiceformat;
-							f.datalen = len;
-							if (f.datalen >= 0) {
-								if (f.datalen)
-									f.data = ptr;
-								else
-									f.data = NULL;
-								if(trunked_ts) {
-									fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
-								} else
-									fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
-								/* Don't pass any packets until we're started */
-								if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
-									/* Common things */
-									f.src = "IAX2";
-									f.mallocd = 0;
-									f.offset = 0;
-									if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
-										f.samples = ast_codec_get_samples(&f);
-									else
-										f.samples = 0;
-									fr->outoforder = 0;
-									iax_frame_wrap(fr, &f);
-									duped_fr = iaxfrdup2(fr);
-									if (duped_fr) {
-										schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
-									}
-									if (iaxs[fr->callno]->last < fr->ts) {
-										iaxs[fr->callno]->last = fr->ts;
-#if 1
-										if (option_debug && iaxdebug)
-											ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
-#endif
-									}
-								}
-							} else {
-								ast_log(LOG_WARNING, "Datalen < 0?\n");
-							}
-						} else {
-							ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
-							iax2_vnak(fr->callno);
-						}
-					}
-					ast_mutex_unlock(&iaxsl[fr->callno]);
-				}
-				ptr += len;
-				res -= len;
-			}
-			
-		}
-		return 1;
-	}
+	} else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
+		return socket_process_meta(res, meta, &sin, fd, fr);
 
 #ifdef DEBUG_SUPPORT
 	if (iaxdebug && (res >= sizeof(*fh)))
@@ -7624,7 +7662,7 @@
 	for(;;) {
 		/* Wait for something to signal us to be awake */
 		ast_mutex_lock(&thread->lock);
-		if (thread->type == IAX_TYPE_DYNAMIC) {
+		if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
 			/* Wait to be signalled or time out */
 			tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
 			ts.tv_sec = tv.tv_sec;
@@ -7660,6 +7698,7 @@
 #ifdef SCHED_MULTITHREADED
 			thread->schedfunc(thread->scheddata);
 #endif		
+		default:
 			break;
 		}
 		time(&thread->checktime);
@@ -7674,7 +7713,7 @@
 		AST_LIST_UNLOCK(&active_list);
 
 		/* Go back into our respective list */
-		if (thread->type == IAX_TYPE_DYNAMIC) {
+		if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
 			AST_LIST_LOCK(&dynamic_list);
 			AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
 			AST_LIST_UNLOCK(&dynamic_list);
@@ -8123,7 +8162,7 @@
 	for (x = 0; x < iaxthreadcount; x++) {
 		struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
 		if (thread) {
-			thread->type = IAX_TYPE_POOL;
+			thread->type = IAX_THREAD_TYPE_POOL;
 			thread->threadnum = ++threadcount;
 			ast_mutex_init(&thread->lock);
 			ast_cond_init(&thread->cond, NULL);
@@ -8666,35 +8705,32 @@
 
 static void delete_users(void)
 {
-	struct iax2_user *user = NULL;
-	struct iax2_peer *peer = NULL;
-	struct iax2_registry *reg, *regl;
+	struct iax2_user *user;
+	struct iax2_peer *peer;
+	struct iax2_registry *reg;
 
 	AST_LIST_LOCK(&users);
 	AST_LIST_TRAVERSE(&users, user, entry)
 		ast_set_flag(user, IAX_DELME);
 	AST_LIST_UNLOCK(&users);
 
-	for (reg = registrations;reg;) {
-		regl = reg;
-		reg = reg->next;
-		if (regl->expire > -1) {
-			ast_sched_del(sched, regl->expire);
-		}
-		if (regl->callno) {
-			/* XXX Is this a potential lock?  I don't think so, but you never know */
-			ast_mutex_lock(&iaxsl[regl->callno]);
-			if (iaxs[regl->callno]) {
-				iaxs[regl->callno]->reg = NULL;
-				iax2_destroy(regl->callno);
+	AST_LIST_LOCK(&registrations);
+	while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
+		if (reg->expire > -1)
+			ast_sched_del(sched, reg->expire);
+		if (reg->callno) {
+			ast_mutex_lock(&iaxsl[reg->callno]);
+			if (iaxs[reg->callno]) {
+				iaxs[reg->callno]->reg = NULL;
+				iax2_destroy(reg->callno);
 			}
-			ast_mutex_unlock(&iaxsl[regl->callno]);
-		}
-		if (regl->dnsmgr)
-			ast_dnsmgr_release(regl->dnsmgr);
-		free(regl);
-	}
-	registrations = NULL;
+			ast_mutex_unlock(&iaxsl[reg->callno]);
+		}
+		if (reg->dnsmgr)
+			ast_dnsmgr_release(reg->dnsmgr);
+		free(reg);
+	}
+	AST_LIST_UNLOCK(&registrations);
 
 	AST_LIST_LOCK(&peers);
 	AST_LIST_TRAVERSE(&peers, peer, entry)
@@ -9142,7 +9178,7 @@
 {
 	char *config = "iax.conf";
 	struct iax2_registry *reg;
-	struct iax2_peer *peer = NULL;
+	struct iax2_peer *peer;
 
 	strcpy(accountcode, "");
 	strcpy(language, "");
@@ -9156,14 +9192,17 @@
 	ast_clear_flag((&globalflags), IAX_USEJITTERBUF);	
 	ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);	
 	delete_users();
-	set_config(config,1);
+	set_config(config, 1);
 	prune_peers();
 	prune_users();
 	trunk_timed = trunk_untimed = 0; 
 	trunk_nmaxmtu = trunk_maxmtu = 0; 
 
-	for (reg = registrations; reg; reg = reg->next)
+	AST_LIST_LOCK(&registrations);
+	AST_LIST_TRAVERSE(&registrations, reg, entry)
 		iax2_do_register(reg);
+	AST_LIST_UNLOCK(&registrations);
+
 	/* Qualify hosts, too */
 	AST_LIST_LOCK(&peers);
 	AST_LIST_TRAVERSE(&peers, peer, entry)
@@ -10009,9 +10048,11 @@
 	} else if (option_verbose > 1)
 		ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
 
-	for (reg = registrations; reg; reg = reg->next)
+	AST_LIST_LOCK(&registrations);
+	AST_LIST_TRAVERSE(&registrations, reg, entry)
 		iax2_do_register(reg);
-
+	AST_LIST_UNLOCK(&registrations);	
+	
 	AST_LIST_LOCK(&peers);
 	AST_LIST_TRAVERSE(&peers, peer, entry) {
 		if (peer->sockfd < 0)

Modified: team/group/trunk-cm-csel-hash/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/channels/chan_zap.c?view=diff&rev=48386&r1=48385&r2=48386
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/chan_zap.c (original)
+++ team/group/trunk-cm-csel-hash/channels/chan_zap.c Mon Dec 11 04:47:35 2006
@@ -3749,8 +3749,11 @@
 		   stop if now if appropriate */
 		if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
 			ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
-		if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
+		if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
 			ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
+		}
+		if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
+			tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
 		}
 		if (p->subs[SUB_REAL].owner->cdr) {
 			/* Move CDR from second channel to current one */
@@ -3774,8 +3777,12 @@
 		unalloc_sub(p, SUB_THREEWAY);
 	} else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
 		ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
-		if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)
+		if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
 			ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
+		}
+		if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
+			tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
+		}
 		if (p->subs[SUB_THREEWAY].owner->cdr) {
 			/* Move CDR from second channel to current one */

[... 676 lines stripped ...]


More information about the svn-commits mailing list