[asterisk-commits] russell: branch group/res_config_ldap r78030 - in /team/group/res_config_ldap...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 2 21:09:36 CDT 2007


Author: russell
Date: Thu Aug  2 21:09:35 2007
New Revision: 78030

URL: http://svn.digium.com/view/asterisk?view=rev&rev=78030
Log:
resolve conflict, get up to date

Added:
    team/group/res_config_ldap/funcs/func_lock.c
      - copied unchanged from r78029, trunk/funcs/func_lock.c
Modified:
    team/group/res_config_ldap/   (props changed)
    team/group/res_config_ldap/CHANGES
    team/group/res_config_ldap/UPGRADE.txt
    team/group/res_config_ldap/apps/app_dial.c
    team/group/res_config_ldap/apps/app_macro.c
    team/group/res_config_ldap/apps/app_meetme.c
    team/group/res_config_ldap/apps/app_osplookup.c
    team/group/res_config_ldap/apps/app_queue.c
    team/group/res_config_ldap/apps/app_senddtmf.c
    team/group/res_config_ldap/apps/app_voicemail.c
    team/group/res_config_ldap/apps/app_zapras.c
    team/group/res_config_ldap/build_tools/cflags.xml
    team/group/res_config_ldap/channels/chan_iax2.c
    team/group/res_config_ldap/channels/chan_local.c
    team/group/res_config_ldap/channels/chan_mgcp.c
    team/group/res_config_ldap/channels/chan_sip.c
    team/group/res_config_ldap/channels/chan_skinny.c
    team/group/res_config_ldap/channels/chan_vpb.cc
    team/group/res_config_ldap/configs/skinny.conf.sample
    team/group/res_config_ldap/configure
    team/group/res_config_ldap/configure.ac
    team/group/res_config_ldap/contrib/scripts/ast_grab_core
    team/group/res_config_ldap/doc/tex/queuelog.tex
    team/group/res_config_ldap/include/asterisk/autoconfig.h.in
    team/group/res_config_ldap/include/asterisk/speech.h
    team/group/res_config_ldap/include/asterisk/threadstorage.h
    team/group/res_config_ldap/main/autoservice.c
    team/group/res_config_ldap/main/cli.c
    team/group/res_config_ldap/main/fskmodem.c
    team/group/res_config_ldap/main/pbx.c
    team/group/res_config_ldap/main/utils.c
    team/group/res_config_ldap/pbx/pbx_dundi.c
    team/group/res_config_ldap/res/res_agi.c
    team/group/res_config_ldap/res/res_features.c
    team/group/res_config_ldap/res/res_speech.c
    team/group/res_config_ldap/utils/smsq.c

Propchange: team/group/res_config_ldap/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/group/res_config_ldap/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/group/res_config_ldap/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Aug  2 21:09:35 2007
@@ -1,1 +1,1 @@
-/trunk:1-77812
+/trunk:1-78029

Modified: team/group/res_config_ldap/CHANGES
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/CHANGES?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/CHANGES (original)
+++ team/group/res_config_ldap/CHANGES Thu Aug  2 21:09:35 2007
@@ -33,6 +33,10 @@
   * MailboxExists converted to dialplan function
   * A new option to Dial() for telling IP phones not to count the call
     as "missed" when dial times out and cancels.
+  * Added LOCK(), TRYLOCK(), and UNLOCK(), which provide a single level dialplan
+    mutex.  No deadlocks are possible, as LOCK() only allows a single lock to be
+    held for any given channel.  Also, locks are automatically freed when a
+    channel is hung up.
 
 CLI Changes
 -----------

Modified: team/group/res_config_ldap/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/UPGRADE.txt?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/UPGRADE.txt (original)
+++ team/group/res_config_ldap/UPGRADE.txt Thu Aug  2 21:09:35 2007
@@ -71,6 +71,11 @@
 * DISA()'s fifth argument is now an options argument.  If you have previously
   used 'NOANSWER' in this argument, you'll need to convert that to the new
   option 'n'.
+* Macro() is now deprecated.  If you need subroutines, you should use the
+  Gosub()/Return() applications.  To replace MacroExclusive(), we have
+  introduced dialplan functions LOCK(), TRYLOCK(), and UNLOCK().  You may use
+  these functions in any location where you desire to ensure that only one
+  channel is executing that path at any one time.
 
 CDR:
 

Modified: team/group/res_config_ldap/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/apps/app_dial.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/apps/app_dial.c (original)
+++ team/group/res_config_ldap/apps/app_dial.c Thu Aug  2 21:09:35 2007
@@ -1789,7 +1789,7 @@
 			ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);  /* set it back the way it was */
 		}
 		if (res != AST_PBX_NO_HANGUP_PEER) {
-			if (!chan->_softhangup)
+			if (!ast_check_hangup(chan))
 				chan->hangupcause = peer->hangupcause;
 			ast_hangup(peer);
 		}
@@ -1808,7 +1808,7 @@
 	senddialendevent(chan, pa.status);
 	ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
 	
-	if ((ast_test_flag64(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
+	if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE)) {
 		if (calldurationlimit)
 			chan->whentohangup = 0;
 		res = 0;

Modified: team/group/res_config_ldap/apps/app_macro.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/apps/app_macro.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/apps/app_macro.c (original)
+++ team/group/res_config_ldap/apps/app_macro.c Thu Aug  2 21:09:35 2007
@@ -385,7 +385,7 @@
 		}
 
 		/* don't stop executing extensions when we're in "h" */
-		if (chan->_softhangup && !inhangup) {
+		if (ast_check_hangup(chan) && !inhangup) {
 			ast_debug(1, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", chan->exten, chan->macroexten, chan->priority);
 			goto out;
 		}
@@ -434,7 +434,7 @@
   		/* If we're leaving the macro normally, restore original information */
 		chan->priority = oldpriority;
 		ast_copy_string(chan->context, oldcontext, sizeof(chan->context));
-		if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) {
+		if (!(ast_check_hangup(chan) & AST_SOFTHANGUP_ASYNCGOTO)) {
 			/* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
 			const char *offsets;
 			ast_copy_string(chan->exten, oldexten, sizeof(chan->exten));

Modified: team/group/res_config_ldap/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/apps/app_meetme.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/apps/app_meetme.c (original)
+++ team/group/res_config_ldap/apps/app_meetme.c Thu Aug  2 21:09:35 2007
@@ -718,7 +718,7 @@
 	int len;
 	int res = -1;
 
-	if (!chan->_softhangup)
+	if (!ast_check_hangup(chan))
 		res = ast_autoservice_start(chan);
 
 	AST_LIST_LOCK(&confs);

Modified: team/group/res_config_ldap/apps/app_osplookup.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/apps/app_osplookup.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/apps/app_osplookup.c (original)
+++ team/group/res_config_ldap/apps/app_osplookup.c Thu Aug  2 21:09:35 2007
@@ -1734,7 +1734,7 @@
 	ast_debug(1, "OSPFinish: connect '%ld'\n", connect);
 	ast_debug(1, "OSPFinish: end '%ld'\n", end);
 
-	release = chan->_softhangup ? 0 : 1;
+	release = ast_check_hangup(chan) ? 0 : 1;
 
 	if (osp_finish(outhandle, recorded, cause, start, connect, end, release) <= 0) {
 		ast_debug(1, "OSPFinish: Unable to report usage for outbound call\n");

Modified: team/group/res_config_ldap/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/apps/app_queue.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/apps/app_queue.c (original)
+++ team/group/res_config_ldap/apps/app_queue.c Thu Aug  2 21:09:35 2007
@@ -1256,6 +1256,56 @@
 		AST_LIST_UNLOCK(&queues);
 	}
 	return q;
+}
+
+static void update_realtime_members(struct call_queue *q)
+{
+	struct ast_config *member_config = NULL;
+	struct member *m, *prev_m, *next_m;
+	char *interface = NULL;
+
+	member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL);
+	if (!member_config) {
+		/*This queue doesn't have realtime members*/
+		ast_debug(3, "Queue %s has no realtime members defined. No need for update\n", q->name);
+		return;
+	}
+
+	ast_mutex_lock(&q->lock);
+	
+	/* Temporarily set non-dynamic members dead so we can detect deleted ones.*/ 
+	for (m = q->members; m; m = m->next) {
+		if (!m->dynamic)
+			m->dead = 1;
+	}
+
+	while ((interface = ast_category_browse(member_config, interface))) {
+		rt_handle_member_record(q, interface,
+			S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
+			ast_variable_retrieve(member_config, interface, "penalty"),
+			ast_variable_retrieve(member_config, interface, "paused"));
+	}
+
+	/* Delete all realtime members that have been deleted in DB. */
+	m = q->members;
+	prev_m = NULL;
+	while (m) {
+		next_m = m->next;
+		if (m->dead) {
+			if (prev_m) {
+				prev_m->next = next_m;
+			} else {
+				q->members = next_m;
+			}
+			remove_from_interfaces(m->interface);
+			q->membercount--;
+			free(m);
+		} else {
+			prev_m = m;
+		}
+		m = next_m;
+	}
+	ast_mutex_unlock(&q->lock);
 }
 
 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
@@ -2410,7 +2460,7 @@
 {
 	struct member *cur;
 	struct callattempt *outgoing = NULL; /* the list of calls we are building */
-	int to;
+	int to, orig;
 	char oldexten[AST_MAX_EXTENSION]="";
 	char oldcontext[AST_MAX_CONTEXT]="";
 	char queuename[256]="";
@@ -2444,6 +2494,7 @@
 	char vars[2048];
 	int forwardsallowed = 1;
 	int callcompletedinsl;
+	int noption = 0;
 
 	memset(&bridge_config, 0, sizeof(bridge_config));
 	time(&now);
@@ -2476,11 +2527,15 @@
 				(*go_on)++;
 			else
 				*go_on = qe->parent->membercount;
+			noption = 1;
 			break;
 		case 'i':
 			forwardsallowed = 0;
 			break;
 		}
+
+	if(!noption)
+		*go_on = -1;
 
 	/* Hold the lock while we setup the outgoing calls */
 	if (use_weight)
@@ -2528,6 +2583,7 @@
 		to = (qe->expire - now) * 1000;
 	else
 		to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
+	orig = to;
 	ring_one(qe, outgoing, &numbusies);
 	ast_mutex_unlock(&qe->parent->lock);
 	if (use_weight)
@@ -2596,7 +2652,7 @@
 				}
 			}
 			res2 |= ast_autoservice_stop(qe->chan);
-			if (peer->_softhangup) {
+			if (ast_check_hangup(peer)) {
 				/* Agent must have hung up */
 				ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
 				ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
@@ -2863,7 +2919,8 @@
 			} else
 				ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
 		}
-		ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s", (long) time(NULL) - qe->start, peer->uniqueid);
+		ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s|%ld", (long) time(NULL) - qe->start, peer->uniqueid,
+													(long)(orig - to > 0 ? (orig - to) / 1000 : 0));
 		if (qe->parent->eventwhencalled)
 			manager_event(EVENT_FLAG_AGENT, "AgentConnect",
 					"Queue: %s\r\n"
@@ -2873,9 +2930,10 @@
 					"MemberName: %s\r\n"
 					"Holdtime: %ld\r\n"
 					"BridgedChannel: %s\r\n"
+					"Ringtime: %ld\r\n"
 					"%s",
 					queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
-					(long) time(NULL) - qe->start, peer->uniqueid,
+					(long) time(NULL) - qe->start, peer->uniqueid, (long)(orig - to > 0 ? (orig - to) / 1000 : 0),
 					qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
 		ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
 		ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
@@ -2888,7 +2946,7 @@
 				qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
 				(long) (time(NULL) - callstart));
 			send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
-		} else if (qe->chan->_softhangup) {
+		} else if (ast_check_hangup(qe->chan)) {
 			ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETECALLER", "%ld|%ld|%d",
 				(long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
 			send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), CALLER);
@@ -3623,6 +3681,9 @@
 				ast_queue_log(qe.parent->name, qe.chan->uniqueid,"NONE", "EXITWITHTIMEOUT", "%d|%d|%ld", qe.pos, qe.opos, (long) time(NULL) - qe.start);
 				break;
 			}
+
+			/* If using dynamic realtime members, we should regenerate the member list for this queue */
+			update_realtime_members(qe.parent);
 
 			/* OK, we didn't get anybody; wait for 'retry' seconds; may get a digit to exit with */
 			res = wait_a_bit(&qe);

Modified: team/group/res_config_ldap/apps/app_senddtmf.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/apps/app_senddtmf.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/apps/app_senddtmf.c (original)
+++ team/group/res_config_ldap/apps/app_senddtmf.c Thu Aug  2 21:09:35 2007
@@ -66,7 +66,7 @@
 		AST_APP_ARG(timeout);
 	);
 
-	if (ast_strlen_zero(data)) {
+	if (ast_strlen_zero(vdata)) {
 		ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#aAbBcCdD)\n");
 		return 0;
 	}

Modified: team/group/res_config_ldap/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/apps/app_voicemail.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/apps/app_voicemail.c (original)
+++ team/group/res_config_ldap/apps/app_voicemail.c Thu Aug  2 21:09:35 2007
@@ -1790,6 +1790,7 @@
 
 #endif
 
+#ifndef ODBC_STORAGE
 static int vm_delete(char *file)
 {
 	char *txt;
@@ -1807,6 +1808,7 @@
 	unlink(txt);
 	return ast_filedelete(file, NULL);
 }
+#endif
 
 static int inbuf(struct baseio *bio, FILE *fi)
 {
@@ -2082,7 +2084,7 @@
 		fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
 	else
 		fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
-	fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, getpid(), host);
+	fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
 	if(imap) {
 		/* additional information needed for IMAP searching */
 		fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
@@ -2108,7 +2110,7 @@
 	fprintf(p, "MIME-Version: 1.0" ENDL);
 	if (attach_user_voicemail) {
 		/* Something unique. */
-		snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, getpid(), (unsigned int)ast_random());
+		snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
 
 		fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
 		fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);

Modified: team/group/res_config_ldap/apps/app_zapras.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/apps/app_zapras.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/apps/app_zapras.c (original)
+++ team/group/res_config_ldap/apps/app_zapras.c Thu Aug  2 21:09:35 2007
@@ -161,7 +161,7 @@
 			res = wait4(pid, &status, WNOHANG, NULL);
 			if (!res) {
 				/* Check for hangup */
-				if (chan->_softhangup && !signalled) {
+				if (ast_check_hangup(chan) && !signalled) {
 					ast_debug(1, "Channel '%s' hungup.  Signalling RAS at %d to die...\n", chan->name, pid);
 					kill(pid, SIGTERM);
 					signalled=1;

Modified: team/group/res_config_ldap/build_tools/cflags.xml
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/build_tools/cflags.xml?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/build_tools/cflags.xml (original)
+++ team/group/res_config_ldap/build_tools/cflags.xml Thu Aug  2 21:09:35 2007
@@ -8,6 +8,7 @@
 		<member name="DEBUG_THREADLOCALS" displayname="Enable Thread-Local-Storage Debugging">
 		</member>
 		<member name="DETECT_DEADLOCKS" displayname="Detect Deadlocks">
+			<depend>DEBUG_THREADS</depend>
 		</member>
 		<member name="DO_CRASH" displayname="Crash on fatal errors">
 		</member>

Modified: team/group/res_config_ldap/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/channels/chan_iax2.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/channels/chan_iax2.c (original)
+++ team/group/res_config_ldap/channels/chan_iax2.c Thu Aug  2 21:09:35 2007
@@ -745,6 +745,7 @@
 	time_t checktime;
 	ast_mutex_t lock;
 	ast_cond_t cond;
+	unsigned int ready_for_signal:1;
 	/*! if this thread is processing a full frame,
 	  some information about that frame will be stored
 	  here, so we can avoid dispatching any more full
@@ -1013,8 +1014,10 @@
 	AST_LIST_UNLOCK(&idle_list);
 
 	/* If we popped a thread off the idle list, just return it */
-	if (thread)
+	if (thread) {
+		memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
 		return thread;
+	}
 
 	/* Pop the head of the dynamic list off */
 	AST_LIST_LOCK(&dynamic_list);
@@ -1022,8 +1025,10 @@
 	AST_LIST_UNLOCK(&dynamic_list);
 
 	/* If we popped a thread off the dynamic list, just return it */
-	if (thread)
+	if (thread) {
+		memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
 		return thread;
+	}
 
 	/* If we can't create a new dynamic thread for any reason, return no thread at all */
 	if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
@@ -1042,13 +1047,16 @@
 		ast_cond_destroy(&thread->cond);
 		ast_mutex_destroy(&thread->lock);
 		ast_free(thread);
-		thread = NULL;
+		return NULL;
 	}
 
 	/* this thread is not processing a full frame (since it is idle),
 	   so ensure that the field for the full frame call number is empty */
-	if (thread)
-		memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
+	memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
+
+	/* Wait for the thread to be ready before returning it to the caller */
+	while (!thread->ready_for_signal)
+		usleep(1);
 
 	return thread;
 }
@@ -1511,7 +1519,7 @@
 {
 	/* Close firmware */
 	if (cur->fwh) {
-		munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
+		munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
 	}
 	close(cur->fd);
 	ast_free(cur);
@@ -1607,7 +1615,7 @@
 		close(fd);
 		return -1;
 	}
-	fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
+	fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
 	if (fwh == (void *) -1) {
 		ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
 		close(fd);
@@ -1618,7 +1626,7 @@
 	MD5Final(sum, &md5);
 	if (memcmp(sum, fwh->chksum, sizeof(sum))) {
 		ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
-		munmap(fwh, stbuf.st_size);
+		munmap((void*)fwh, stbuf.st_size);
 		close(fd);
 		return -1;
 	}
@@ -1631,7 +1639,7 @@
 				break;
 			/* This version is no newer than what we have.  Don't worry about it.
 			   We'll consider it a proper load anyhow though */
-			munmap(fwh, stbuf.st_size);
+			munmap((void*)fwh, stbuf.st_size);
 			close(fd);
 			return 0;
 		}
@@ -1644,7 +1652,7 @@
 	
 	if (cur) {
 		if (cur->fwh)
-			munmap(cur->fwh, cur->mmaplen);
+			munmap((void*)cur->fwh, cur->mmaplen);
 		if (cur->fd > -1)
 			close(cur->fd);
 		cur->fwh = fwh;
@@ -6262,7 +6270,8 @@
 	AST_LIST_TRAVERSE(&frame_queue, f, list) {
 		/* Send a copy immediately */
 		if ((f->callno == callno) && iaxs[f->callno] &&
-			((unsigned char ) (f->oseqno - last) < 128)) {
+			((unsigned char ) (f->oseqno - last) < 128) &&
+			(f->retries >= 0)) {
 			send_packet(f);
 		}
 	}
@@ -8369,22 +8378,42 @@
 		/* Wait for something to signal us to be awake */
 		ast_mutex_lock(&thread->lock);
 
+		/* Flag that we're ready to accept signals */
+		thread->ready_for_signal = 1;
+		
 		/* Put into idle list if applicable */
 		if (put_into_idle)
 			insert_idle_thread(thread);
 
 		if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
+			struct iax2_thread *t = NULL;
 			/* Wait to be signalled or time out */
 			tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
 			ts.tv_sec = tv.tv_sec;
 			ts.tv_nsec = tv.tv_usec * 1000;
 			if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
-				ast_mutex_unlock(&thread->lock);
+				/* This thread was never put back into the available dynamic
+				 * thread list, so just go away. */
+				if (!put_into_idle) {
+					ast_mutex_unlock(&thread->lock);
+					break;
+				}
 				AST_LIST_LOCK(&dynamic_list);
-				AST_LIST_REMOVE(&dynamic_list, thread, list);
+				/* Account for the case where this thread is acquired *right* after a timeout */
+				if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
+					ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
 				AST_LIST_UNLOCK(&dynamic_list);
-				ast_atomic_dec_and_test(&iaxdynamicthreadcount);
-				break;		/* exiting the main loop */
+				if (t) {
+					/* This dynamic thread timed out waiting for a task and was
+					 * not acquired immediately after the timeout, 
+					 * so it's time to go away. */
+					ast_mutex_unlock(&thread->lock);
+					break;
+				}
+				/* Someone grabbed our thread *right* after we timed out.
+				 * Wait for them to set us up with something to do and signal
+				 * us to continue. */
+				ast_cond_wait(&thread->cond, &thread->lock);
 			}
 		} else {
 			ast_cond_wait(&thread->cond, &thread->lock);

Modified: team/group/res_config_ldap/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/channels/chan_local.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/channels/chan_local.c (original)
+++ team/group/res_config_ldap/channels/chan_local.c Thu Aug  2 21:09:35 2007
@@ -246,9 +246,9 @@
 		   we can't get everything.  Remember, we'll get another
 		   chance in just a little bit */
 		if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) {
-			if (!p->chan->_bridge->_softhangup) {
+			if (!ast_check_hangup(p->chan->_bridge)) {
 				if (!ast_mutex_trylock(&p->owner->lock)) {
-					if (!p->owner->_softhangup) {
+					if (!ast_check_hangup(p->owner)) {
 						ast_channel_masquerade(p->owner, p->chan->_bridge);
 						ast_set_flag(p, LOCAL_ALREADY_MASQED);
 					}
@@ -265,9 +265,9 @@
 	} else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
 		/* Masquerade bridged channel into chan */
 		if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
-			if (!p->owner->_bridge->_softhangup) {
+			if (!ast_check_hangup(p->owner->_bridge)) {
 				if (!ast_mutex_trylock(&p->chan->lock)) {
-					if (!p->chan->_softhangup) {
+					if (!ast_check_hangup(p->chan)) {
 						ast_channel_masquerade(p->chan, p->owner->_bridge);
 						ast_set_flag(p, LOCAL_ALREADY_MASQED);
 					}

Modified: team/group/res_config_ldap/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/channels/chan_mgcp.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/channels/chan_mgcp.c (original)
+++ team/group/res_config_ldap/channels/chan_mgcp.c Thu Aug  2 21:09:35 2007
@@ -2061,7 +2061,7 @@
 		ast_verbose("We're at %s port %d\n", ast_inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));
 	}
 	snprintf(v, sizeof(v), "v=0\r\n");
-	snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), ast_inet_ntoa(dest.sin_addr));
+	snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", (int)getpid(), (int)getpid(), ast_inet_ntoa(dest.sin_addr));
 	snprintf(s, sizeof(s), "s=session\r\n");
 	snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
 	snprintf(t, sizeof(t), "t=0 0\r\n");

Modified: team/group/res_config_ldap/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/channels/chan_sip.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/channels/chan_sip.c (original)
+++ team/group/res_config_ldap/channels/chan_sip.c Thu Aug  2 21:09:35 2007
@@ -1136,6 +1136,7 @@
 /*! \brief Protect the SIP dialog list (of sip_pvt's) */
 AST_MUTEX_DEFINE_STATIC(dialoglock);
 
+#ifndef DETECT_DEADLOCKS
 /*! \brief hide the way the list is locked/unlocked */
 static void dialoglist_lock(void)
 {
@@ -1146,6 +1147,12 @@
 {
 	ast_mutex_unlock(&dialoglock);
 }
+#else
+/* we don't want to HIDE the information about where the lock was requested if trying to debug 
+ * deadlocks!  So, just make these macros! */
+#define dialoglist_lock(x) ast_mutex_lock(&dialoglock)
+#define dialoglist_unlock(x) ast_mutex_unlock(&dialoglock)
+#endif
 
 /*!
  * when we create or delete references, make sure to use these
@@ -1841,24 +1848,8 @@
 	get_codec: sip_get_codec,
 };
 
-#ifndef DETECT_DEADLOCKS
-/*! \brief Helper function to lock, hiding the underlying locking mechanism.  */
-static void sip_pvt_lock(struct sip_pvt *pvt)
-{
-	ast_mutex_lock(&pvt->pvt_lock);
-}
-
-/*! \brief Helper function to unlock pvt, hiding the underlying locking mechanism. */
-static void sip_pvt_unlock(struct sip_pvt *pvt)
-{
-	ast_mutex_unlock(&pvt->pvt_lock);
-}
-#else
-/* we don't want to HIDE the information about where the lock was requested if trying to debug 
- * deadlocks!  So, just make these macros! */
 #define sip_pvt_lock(x) ast_mutex_lock(&x->pvt_lock)
 #define sip_pvt_unlock(x) ast_mutex_unlock(&x->pvt_lock)
-#endif
 
 /*!
  * helper functions to unreference various types of objects.
@@ -14736,6 +14727,8 @@
 		case AST_STATE_UP:
 			ast_debug(2, "%s: This call is UP.... \n", c->name);
 
+			transmit_response(p, "100 Trying", req);
+
 			if (p->t38.state == T38_PEER_REINVITE) {
 				struct ast_channel *bridgepeer = NULL;
 				struct sip_pvt *bridgepvt = NULL;
@@ -18654,11 +18647,11 @@
 		return AST_MODULE_LOAD_DECLINE;
 
 	/* Prepare the version that does not require DTMF BEGIN frames.
-	 * We need to use tricks such as memcopy and casts because the variable
+	 * We need to use tricks such as memcpy and casts because the variable
 	 * has const fields.
 	 */
 	memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
-	*((void **)&sip_tech_info.send_digit_begin) = NULL;
+	memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
 
 	/* Make sure we can register our sip channel type */
 	if (ast_channel_register(&sip_tech)) {

Modified: team/group/res_config_ldap/channels/chan_skinny.c
URL: http://svn.digium.com/view/asterisk/team/group/res_config_ldap/channels/chan_skinny.c?view=diff&rev=78030&r1=78029&r2=78030
==============================================================================
--- team/group/res_config_ldap/channels/chan_skinny.c (original)
+++ team/group/res_config_ldap/channels/chan_skinny.c Thu Aug  2 21:09:35 2007
@@ -196,7 +196,7 @@
 struct stimulus_message {
 	uint32_t stimulus;
 	uint32_t stimulusInstance;
-	uint32_t unknown1;
+	uint32_t callreference;
 };
 
 #define OFFHOOK_MESSAGE 0x0006
@@ -263,7 +263,7 @@
 struct soft_key_event_message {
 	uint32_t softKeyEvent;
 	uint32_t instance;
-	uint32_t reference;
+	uint32_t callreference;
 };
 
 #define UNREGISTER_MESSAGE 0x0027
@@ -283,12 +283,15 @@
 #define START_TONE_MESSAGE 0x0082
 struct start_tone_message {
 	uint32_t tone;
-	uint32_t space[3];
+	uint32_t space;
+	uint32_t instance;
+	uint32_t reference;
 };
 
 #define STOP_TONE_MESSAGE 0x0083
 struct stop_tone_message {
-	uint32_t space[2];
+	uint32_t instance;
+	uint32_t reference;
 };
 
 #define SET_RINGER_MESSAGE 0x0085
@@ -742,6 +745,7 @@
 	struct clear_prompt_message clearpromptstatus;
 	struct definetimedate_message definetimedate;
 	struct start_tone_message starttone;
+	struct stop_tone_message stoptone;
 	struct speed_dial_stat_res_message speeddial;
 	struct line_state_req_message line;
 	struct line_stat_res_message linestat;
@@ -1625,48 +1629,6 @@
 	transmit_response(s, req);
 }
 */
-static void transmit_callstate(struct skinnysession *s, int instance, int state, unsigned callid)
-{
-	struct skinny_req *req;
-
-	if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
-		return;
-
-	if (state == SKINNY_ONHOOK) {
-		transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
-	}
-	req->data.callstate.callState = htolel(state);
-	req->data.callstate.lineInstance = htolel(instance);
-	req->data.callstate.callReference = htolel(callid);
-	transmit_response(s, req);
-	if (state == SKINNY_OFFHOOK) {
-		if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
-			return;
-
-		req->data.activatecallplane.lineInstance = htolel(instance);
-		transmit_response(s, req);
-	} else if (state == SKINNY_ONHOOK) {
-		if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
-			return;
-
-		req->data.activatecallplane.lineInstance = htolel(instance);
-		transmit_response(s, req);
-
-		if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
-			return;
-
-		req->data.closereceivechannel.conferenceId = 0;
-		req->data.closereceivechannel.partyId = htolel(callid);
-		transmit_response(s, req);
-
-		if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
-			return;
-
-		req->data.stopmedia.conferenceId = 0;
-		req->data.stopmedia.passThruPartyId = htolel(callid);
-		transmit_response(s, req);
-	}
-}
 
 static void transmit_callinfo(struct skinnysession *s, const char *fromname, const char *fromnum, const char *toname, const char *tonum, int instance, int callid, int calltype)
 {
@@ -1707,7 +1669,7 @@
 
 	fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
 
-	req->data.openreceivechannel.conferenceId = htolel(0);
+	req->data.openreceivechannel.conferenceId = htolel(sub->callid);
 	req->data.openreceivechannel.partyId = htolel(sub->callid);
 	req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
 	req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
@@ -1716,7 +1678,7 @@
 	transmit_response(s, req);
 }
 
-static void transmit_tone(struct skinnysession *s, int tone)
+static void transmit_tone(struct skinnysession *s, int tone, int instance, int reference)
 {
 	struct skinny_req *req;
 
@@ -1728,9 +1690,14 @@
 	if (tone > 0) {
 		if (!(req = req_alloc(sizeof(struct start_tone_message), START_TONE_MESSAGE)))
 			return;
+		req->data.starttone.tone = htolel(tone);
+		req->data.starttone.instance = htolel(instance);
+		req->data.starttone.reference = htolel(reference);
 	} else {
 		if (!(req = req_alloc(sizeof(struct stop_tone_message), STOP_TONE_MESSAGE)))
 			return;
+		req->data.stoptone.instance = htolel(instance);
+		req->data.stoptone.reference = htolel(reference);
 	}
 
 	if (tone > 0) {
@@ -1791,13 +1758,16 @@
 	transmit_response(s, req);
 }
 
-static void transmit_displaymessage(struct skinnysession *s, const char *text)
+static void transmit_displaymessage(struct skinnysession *s, const char *text, int instance, int reference)
 {
 	struct skinny_req *req;
 
 	if (text == 0) {
 		if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE)))
 			return;
+
+		req->data.clearpromptstatus.lineInstance = instance;
+		req->data.clearpromptstatus.callReference = reference;
 
 		if (skinnydebug)
 			ast_verbose("Clearing Display\n");
@@ -1870,6 +1840,51 @@
 	req->data.dialednumber.callReference = htolel(callid);
 
 	transmit_response(s, req);
+}
+
+static void transmit_callstate(struct skinnysession *s, int instance, int state, unsigned callid)
+{
+	struct skinny_req *req;
+
+	if (state == SKINNY_ONHOOK) {
+		if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
+			return;
+
+		req->data.closereceivechannel.conferenceId = htolel(callid);
+		req->data.closereceivechannel.partyId = htolel(callid);
+		transmit_response(s, req);
+
+		if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
+			return;
+
+		req->data.stopmedia.conferenceId = htolel(callid);
+		req->data.stopmedia.passThruPartyId = htolel(callid);
+		transmit_response(s, req);
+
+		transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+
+		transmit_displaypromptstatus(s, NULL, 0, instance, callid);
+	}
+
+	if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
+		return;
+
+	req->data.callstate.callState = htolel(state);
+	req->data.callstate.lineInstance = htolel(instance);
+	req->data.callstate.callReference = htolel(callid);
+	transmit_response(s, req);
+
+	if (state == SKINNY_ONHOOK) {
+		transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+	}
+
+	if (state == SKINNY_OFFHOOK || state == SKINNY_ONHOOK) {
+		if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
+			return;
+
+		req->data.activatecallplane.lineInstance = htolel(instance);
+		transmit_response(s, req);
+	}
 }
 
 static int skinny_extensionstate_cb(char *context, char *exten, int state, void *data)
@@ -2515,7 +2530,7 @@
 	res = ast_pbx_run(c);
 	if (res) {
 		ast_log(LOG_WARNING, "PBX exited non-zero\n");
-		transmit_tone(s, SKINNY_REORDER);
+		transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
 	}
 	return NULL;
 }
@@ -2553,7 +2568,7 @@
 		len = strlen(d->exten);
 
 		if (!ast_ignore_pattern(c->context, d->exten)) {
-			transmit_tone(s, SKINNY_SILENCE);
+			transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
 		}
 		if (ast_exists_extension(c, c->context, d->exten, 1, l->cid_num)) {
 			if (!res || !ast_matchmore_extension(c, c->context, d->exten, 1, l->cid_num)) {
@@ -2562,7 +2577,7 @@
 					ast_copy_string(l->call_forward, d->exten, sizeof(l->call_forward));
 					ast_verb(3, "Setting call forward to '%s' on channel %s\n",
 							l->call_forward, c->name);
-					transmit_tone(s, SKINNY_DIALTONE);
+					transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
 					if (res) {
 						break;
 					}
@@ -2570,7 +2585,7 @@
 					ast_indicate(c, -1);
  					ast_safe_sleep(c, 1000);
 					memset(d->exten, 0, sizeof(d->exten));
-					transmit_tone(s, SKINNY_DIALTONE);
+					transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
 					len = 0;
 					getforward = 0;
 				} else {
@@ -2588,7 +2603,7 @@
 		} else if (res == 0) {
 			ast_debug(1, "Not enough digits (%s) (and no ambiguous match)...\n", d->exten);
 			memset(d->exten, 0, sizeof(d->exten));
-			transmit_tone(s, SKINNY_REORDER);
+			transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
 			if (sub->owner && sub->owner->_state != AST_STATE_UP) {
 				ast_indicate(c, -1);
 				ast_hangup(c);
@@ -2598,7 +2613,7 @@
 			   ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) {
 			ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten, c->cid.cid_num ? c->cid.cid_num : "<Unknown Caller>", c->context);
 			memset(d->exten, 0, sizeof(d->exten));
-			transmit_tone(s, SKINNY_REORDER);
+			transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
 			/* hang out for 3 seconds to let congestion play */
 			ast_safe_sleep(c, 3000);
 			break;
@@ -2694,10 +2709,9 @@
 			transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
 			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
 		} else if ((l->type = TYPE_LINE) && (l->hookstate == SKINNY_ONHOOK)) {
+			transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
 			transmit_callstate(s, l->instance, SKINNY_ONHOOK, sub->callid);
-			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
 			transmit_ringer_mode(s, SKINNY_RING_OFF);
-			transmit_tone(s, SKINNY_SILENCE);
 			transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
 			do_housekeeping(s);
 		}
@@ -2722,6 +2736,9 @@
 	struct skinny_line *l = sub->parent;
 	struct skinny_device *d = l->parent;
 	struct skinnysession *s = d->session;
+	char exten[AST_MAX_EXTENSION] = "";
+
+	ast_copy_string(exten, S_OR(ast->macroexten, ast->exten), sizeof(exten));
 
 	sub->cxmode = SKINNY_CX_SENDRECV;
 	if (!sub->rtp) {
@@ -2733,11 +2750,11 @@
 		ast_setstate(ast, AST_STATE_UP);
 	}
 
-	transmit_tone(s, SKINNY_SILENCE);
+	transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
 	/* order matters here...
 	   for some reason, transmit_callinfo must be before transmit_callstate,
 	   or you won't get keypad messages in some situations. */
-	transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, ast->exten, ast->exten, l->instance, sub->callid, 2);
+	transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2);
 	transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
 	transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
 	transmit_displaypromptstatus(s, "Connected", 0, l->instance, sub->callid);
@@ -2856,7 +2873,7 @@
 	int tmp;
 	/* not right */
 	sprintf(tmp, "%d", digit);
-	transmit_tone(d->session, digit);
+	transmit_tone(d->session, digit, l->instance, sub->callid);
 #endif
 	return -1; /* Stop inband indications */
 }
@@ -2916,6 +2933,14 @@
 	struct skinny_line *l = sub->parent;
 	struct skinny_device *d = l->parent;
 	struct skinnysession *s = d->session;
+	char exten[AST_MAX_EXTENSION] = "";
+
+	if (!s) {
+		ast_log(LOG_NOTICE, "Asked to indicate '%s' condition on channel %s, but session does not exist.\n", control2str(ind), ast->name);
+		return -1;
+	}
+
+	ast_copy_string(exten, S_OR(ast->macroexten, ast->exten), sizeof(exten));
 
 	if (skinnydebug)
 		ast_verb(3, "Asked to indicate '%s' condition on channel %s\n", control2str(ind), ast->name);
@@ -2923,11 +2948,11 @@
 	case AST_CONTROL_RINGING:
 		if (ast->_state != AST_STATE_UP) {
 			if (!sub->progress) {
-				transmit_tone(s, SKINNY_ALERT);
+				transmit_tone(s, SKINNY_ALERT, l->instance, sub->callid);
 				transmit_callstate(s, l->instance, SKINNY_RINGOUT, sub->callid);
-				transmit_dialednumber(s, ast->exten, l->instance, sub->callid);
+				transmit_dialednumber(s, exten, l->instance, sub->callid);
 				transmit_displaypromptstatus(s, "Ring Out", 0, l->instance, sub->callid);
-				transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, ast->exten, ast->exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
+				transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
 				sub->ringing = 1;
 				break;
 			}
@@ -2935,7 +2960,7 @@
 		return -1;
 	case AST_CONTROL_BUSY:

[... 1497 lines stripped ...]



More information about the asterisk-commits mailing list