[asterisk-commits] jpeeler: branch jpeeler/chan_dahdi14 r119798 - in /team/jpeeler/chan_dahdi14:...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jun 2 10:50:46 CDT 2008


Author: jpeeler
Date: Mon Jun  2 10:50:46 2008
New Revision: 119798

URL: http://svn.digium.com/view/asterisk?view=rev&rev=119798
Log:
sync with trunk

Modified:
    team/jpeeler/chan_dahdi14/   (props changed)
    team/jpeeler/chan_dahdi14/apps/app_dial.c
    team/jpeeler/chan_dahdi14/apps/app_queue.c
    team/jpeeler/chan_dahdi14/channels/chan_gtalk.c
    team/jpeeler/chan_dahdi14/channels/chan_iax2.c
    team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c
    team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.h
    team/jpeeler/chan_dahdi14/contrib/init.d/rc.debian.asterisk
    team/jpeeler/chan_dahdi14/contrib/init.d/rc.gentoo.asterisk
    team/jpeeler/chan_dahdi14/contrib/init.d/rc.mandrake.asterisk
    team/jpeeler/chan_dahdi14/contrib/init.d/rc.redhat.asterisk
    team/jpeeler/chan_dahdi14/contrib/init.d/rc.slackware.asterisk
    team/jpeeler/chan_dahdi14/contrib/init.d/rc.suse.asterisk
    team/jpeeler/chan_dahdi14/contrib/scripts/safe_asterisk
    team/jpeeler/chan_dahdi14/main/autoservice.c
    team/jpeeler/chan_dahdi14/main/manager.c
    team/jpeeler/chan_dahdi14/res/res_jabber.c

Propchange: team/jpeeler/chan_dahdi14/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.

Propchange: team/jpeeler/chan_dahdi14/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Jun  2 10:50:46 2008
@@ -1,1 +1,1 @@
-/branches/1.4:1-119094
+/branches/1.4:1-119797

Modified: team/jpeeler/chan_dahdi14/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/apps/app_dial.c?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/apps/app_dial.c (original)
+++ team/jpeeler/chan_dahdi14/apps/app_dial.c Mon Jun  2 10:50:46 2008
@@ -210,7 +210,7 @@
 "  RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
 "place a call using the normal Dial application. If no channel can be reached,\n"
 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
-"seconds before retying the call. After 'retires' number of attempts, the\n"
+"seconds before retrying the call. After 'retries' number of attempts, the\n"
 "calling channel will continue at the next priority in the dialplan. If the\n"
 "'retries' setting is set to 0, this application will retry endlessly.\n"
 "  While waiting to retry a call, a 1 digit extension may be dialed. If that\n"

Modified: team/jpeeler/chan_dahdi14/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/apps/app_queue.c?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/apps/app_queue.c (original)
+++ team/jpeeler/chan_dahdi14/apps/app_queue.c Mon Jun  2 10:50:46 2008
@@ -1422,7 +1422,7 @@
 	stat = get_member_status(q, qe->max_penalty);
 	if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
 		*reason = QUEUE_JOINEMPTY;
-	else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
+	else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_MEMBERS))
 		*reason = QUEUE_JOINUNAVAIL;
 	else if (q->maxlen && (q->count >= q->maxlen))
 		*reason = QUEUE_FULL;

Modified: team/jpeeler/chan_dahdi14/channels/chan_gtalk.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/channels/chan_gtalk.c?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/channels/chan_gtalk.c (original)
+++ team/jpeeler/chan_dahdi14/channels/chan_gtalk.c Mon Jun  2 10:50:46 2008
@@ -276,17 +276,12 @@
 	if (!gtalk && strchr(name, '@'))
 		gtalk = ASTOBJ_CONTAINER_FIND_FULL(&gtalk_list, name, user,,, strcasecmp);
 
-	if (!gtalk) {				/* guest call */
+	if (!gtalk) {
+		/* guest call */
 		ASTOBJ_CONTAINER_TRAVERSE(&gtalk_list, 1, {
 			ASTOBJ_RDLOCK(iterator);
 			if (!strcasecmp(iterator->name, "guest")) {
-				if (!strcasecmp(iterator->connection->jid->partial, connection)) {
-					gtalk = iterator;
-				} else if (!strcasecmp(iterator->connection->name, connection)) {
-					gtalk = iterator;
-				} else if (iterator->connection->component && !strcasecmp(iterator->connection->user,domain)) {
-					gtalk = iterator;
-				}
+				gtalk = iterator;
 			}
 			ASTOBJ_UNLOCK(iterator);
 
@@ -1165,6 +1160,16 @@
 		tmp = tmp->next;
 	}
 
+ 	if (!strcasecmp(client->name, "guest")){
+ 		/* the guest account is not tied to any configured XMPP client,
+ 		   let's set it now */
+ 		client->connection = ast_aji_get_client(from);
+ 		if (!client->connection) {
+ 			ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", from);
+ 			return -1;
+ 		}
+ 	}
+
 	p = gtalk_alloc(client, from, pak->from->full, iks_find_attrib(pak->query, "id"));
 	if (!p) {
 		ast_log(LOG_WARNING, "Unable to allocate gtalk structure!\n");
@@ -1627,11 +1632,22 @@
 			}
 		}
 	}
+
 	client = find_gtalk(to, sender);
 	if (!client) {
 		ast_log(LOG_WARNING, "Could not find recipient.\n");
 		return NULL;
 	}
+	if (!strcasecmp(client->name, "guest")){
+		/* the guest account is not tied to any configured XMPP client,
+		   let's set it now */
+		client->connection = ast_aji_get_client(sender);
+		if (!client->connection) {
+			ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", sender);
+			return NULL;
+		}
+	}
+
 	ASTOBJ_WRLOCK(client);
 	p = gtalk_alloc(client, strchr(sender, '@') ? sender : client->connection->jid->full, strchr(to, '@') ? to : client->user, NULL);
 	if (p)
@@ -1931,13 +1947,13 @@
 					ASTOBJ_CONTAINER_TRAVERSE(clients, 1, {
 						ASTOBJ_WRLOCK(iterator);
 						ASTOBJ_WRLOCK(member);
-						member->connection = iterator;
+						member->connection = NULL;
 						iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://www.google.com/session", IKS_RULE_DONE);
 						iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://jabber.org/protocol/gtalk", IKS_RULE_DONE);
 						ASTOBJ_UNLOCK(member);
-						ASTOBJ_CONTAINER_LINK(&gtalk_list, member);
 						ASTOBJ_UNLOCK(iterator);
 					});
+					ASTOBJ_CONTAINER_LINK(&gtalk_list, member);
 				} else {
 					ASTOBJ_UNLOCK(member);
 					ASTOBJ_UNREF(member, gtalk_member_destroy);

Modified: team/jpeeler/chan_dahdi14/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/channels/chan_iax2.c?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/channels/chan_iax2.c (original)
+++ team/jpeeler/chan_dahdi14/channels/chan_iax2.c Mon Jun  2 10:50:46 2008
@@ -993,12 +993,18 @@
 
 static void __send_ping(const void *data)
 {
-	int callno = (long)data;
+	int callno = (long) data;
+
 	ast_mutex_lock(&iaxsl[callno]);
-	if (iaxs[callno] && iaxs[callno]->pingid != -1) {
-		send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
+
+	while (iaxs[callno] && iaxs[callno]->pingid != -1) {
+		if (iaxs[callno]->peercallno) {
+			send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
+		}
 		iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
-	}
+		break;
+	}
+
 	ast_mutex_unlock(&iaxsl[callno]);
 }
 
@@ -1027,13 +1033,18 @@
 
 static void __send_lagrq(const void *data)
 {
-	int callno = (long)data;
-	/* Ping only if it's real not if it's bridged */
+	int callno = (long) data;
+
 	ast_mutex_lock(&iaxsl[callno]);
-	if (iaxs[callno] && iaxs[callno]->lagid > -1) {
-		send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
+
+	while (iaxs[callno] && iaxs[callno]->lagid > -1) {
+		if (iaxs[callno]->peercallno) {
+			send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
+		}
 		iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
-	}
+		break;
+	}
+
 	ast_mutex_unlock(&iaxsl[callno]);
 }
 
@@ -1277,7 +1288,8 @@
 
 	if (owner) {
 		if (ast_mutex_trylock(&owner->lock)) {
-			ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
+			if (option_debug > 2)
+				ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
 			DEADLOCK_AVOIDANCE(&iaxsl[callno]);
 			goto retry;
 		}
@@ -7128,8 +7140,25 @@
 	}
 
 	if (!fr->callno) {
-		fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, 
-			(ntohs(mh->callno) & IAX_FLAG_FULL) && f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK);
+		int check_dcallno = 0;
+
+		/*
+		 * We enforce accurate destination call numbers for all full frames except
+		 * LAGRQ and PING commands.  This is because older versions of Asterisk
+		 * schedule these commands to get sent very quickly, and they will sometimes
+		 * be sent before they receive the first frame from the other side.  When
+		 * that happens, it doesn't contain the destination call number.  However,
+		 * not checking it for these frames is safe.
+		 * 
+		 * Discussed in the following thread:
+		 *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
+		 */
+
+		if (ntohs(mh->callno) & IAX_FLAG_FULL) {
+			check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
+		}
+
+		fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
 	}
 
 	if (fr->callno > 0)

Modified: team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c (original)
+++ team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c Mon Jun  2 10:50:46 2008
@@ -13,6 +13,7 @@
 
 
 #include <syslog.h>
+#include <sys/time.h>
 #include <mISDNuser/isdn_debug.h>
 
 #include "isdn_lib_intern.h"
@@ -700,6 +701,8 @@
 	
 	bc->te_choose_channel = 0;
 	bc->channel_found= 0;
+
+	gettimeofday(&bc->last_used, NULL);
 }
 
 
@@ -1565,7 +1568,17 @@
 					break;
 				}
 
-				cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n");
+				if (!bc->channel)
+					cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n");
+				else 
+					cb_log(0, stack->port, "Requested Channel Already in Use releasing this call with cause 34!!!!\n");
+
+				/* when the channel is already in use, we can't
+				 * simply clear it, we need to make sure that 
+				 * it will still be marked as in_use in the 
+				 * available channels list.*/
+				bc->channel=0;
+
 				misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
 				return -1;
 			}
@@ -3092,6 +3105,20 @@
 
 
 
+static int test_inuse(struct misdn_bchannel *bc)
+{
+	struct timeval now;
+	gettimeofday(&now, NULL);
+	if (!bc->in_use) {
+		if (bc->last_used.tv_sec < now.tv_sec) {
+			cb_log(0,bc->port, "channel with stid:%x for one second still in use!\n", bc->b_stid);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
 static void prepare_bc(struct misdn_bchannel*bc, int channel)
 {
 	bc->channel = channel;
@@ -3122,6 +3149,8 @@
 		return NULL;
 	}
 
+	usleep(1000);
+
 	for (stack=glob_mgr->stack_list; stack; stack=stack->next) {
     
 		if (stack->port == port) {
@@ -3134,7 +3163,7 @@
 			if (channel > 0) {
 				if (channel <= stack->b_num) {
 					for (i = 0; i < stack->b_num; i++) {
-						if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
+						if ( test_inuse(&stack->bc[i]) && stack->bc[i].channel == channel) {
 							cb_log(0,port,"Requested channel:%d on port:%d is already in use\n",channel, port);
 							return NULL;
 						}
@@ -3149,7 +3178,7 @@
 
 			if (dec) {
 				for (i = maxnum-1; i>=0; i--) {
-					if (!stack->bc[i].in_use) {
+					if (test_inuse(&stack->bc[i])) {
 						/* 3. channel on bri means CW*/
 						if (!stack->pri && i==stack->b_num)
 							stack->bc[i].cw=1;
@@ -3161,7 +3190,7 @@
 				}
 			} else {
 				for (i = 0; i <maxnum; i++) {
-					if (!stack->bc[i].in_use) {
+					if (test_inuse(&stack->bc[i])) {
 						/* 3. channel on bri means CW*/
 						if (!stack->pri && i==stack->b_num)
 							stack->bc[i].cw=1;
@@ -3581,9 +3610,19 @@
 	}
 
 	if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
+		static int unhandled_bmsg_count=1000;
 		if (handle_bchan(msg)) {
 			return 0 ;
 		}
+			
+		if (unhandled_bmsg_count==1000) {
+			cb_log(0, 0, "received 1k Unhandled Bchannel Messages: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);		
+			unhandled_bmsg_count=0;
+		}
+
+		unhandled_bmsg_count++;
+		free_msg(msg);
+		return 0;
 	}	
 
 #ifdef RECV_FRM_SYSLOG_DEBUG

Modified: team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.h
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.h?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.h (original)
+++ team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.h Mon Jun  2 10:50:46 2008
@@ -230,6 +230,7 @@
 	int channel_preselected;
 	
 	int in_use;
+	struct timeval last_used;
 	int cw;
 	int addr;
 

Modified: team/jpeeler/chan_dahdi14/contrib/init.d/rc.debian.asterisk
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/contrib/init.d/rc.debian.asterisk?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/contrib/init.d/rc.debian.asterisk (original)
+++ team/jpeeler/chan_dahdi14/contrib/init.d/rc.debian.asterisk Mon Jun  2 10:50:46 2008
@@ -55,7 +55,7 @@
 	# Check if Asterisk is already running.  If it is, then bug out, because
 	# starting up Asterisk when Asterisk is already running is very bad.
 	VERSION=`${DAEMON} -rx 'core show version' || ${TRUE}`
-	if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
+	if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
 		echo "Asterisk is already running.  $0 will exit now."
 		exit 1
 	fi

Modified: team/jpeeler/chan_dahdi14/contrib/init.d/rc.gentoo.asterisk
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/contrib/init.d/rc.gentoo.asterisk?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/contrib/init.d/rc.gentoo.asterisk (original)
+++ team/jpeeler/chan_dahdi14/contrib/init.d/rc.gentoo.asterisk Mon Jun  2 10:50:46 2008
@@ -9,7 +9,7 @@
 	# Check if Asterisk is already running.  If it is, then bug out, because
 	# starting safe_asterisk when Asterisk is running is very bad.
 	VERSION=`${ASTSBINDIR}/asterisk -rx 'core show version'`
-	if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
+	if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
 		echo "Asterisk is already running.  $0 will exit now."
 		exit 1
 	fi

Modified: team/jpeeler/chan_dahdi14/contrib/init.d/rc.mandrake.asterisk
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/contrib/init.d/rc.mandrake.asterisk?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/contrib/init.d/rc.mandrake.asterisk (original)
+++ team/jpeeler/chan_dahdi14/contrib/init.d/rc.mandrake.asterisk Mon Jun  2 10:50:46 2008
@@ -122,7 +122,7 @@
 		# Check if Asterisk is already running.  If it is, then bug out, because
 		# starting Asterisk when Asterisk is already running is very bad.
 		VERSION=`${ASTSBINDIR}/asterisk -rx 'core show version'`
-		if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
+		if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
 			echo "Asterisk is already running.  $0 will exit now."
 			exit 1
 		fi

Modified: team/jpeeler/chan_dahdi14/contrib/init.d/rc.redhat.asterisk
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/contrib/init.d/rc.redhat.asterisk?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/contrib/init.d/rc.redhat.asterisk (original)
+++ team/jpeeler/chan_dahdi14/contrib/init.d/rc.redhat.asterisk Mon Jun  2 10:50:46 2008
@@ -71,7 +71,7 @@
 	# Check if Asterisk is already running.  If it is, then bug out, because
 	# starting safe_asterisk when Asterisk is running is very bad.
 	VERSION=`${AST_SBIN}/asterisk -rx 'core show version'`
-	if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
+	if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
 		echo "Asterisk is already running."
 		exit 1
 	fi

Modified: team/jpeeler/chan_dahdi14/contrib/init.d/rc.slackware.asterisk
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/contrib/init.d/rc.slackware.asterisk?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/contrib/init.d/rc.slackware.asterisk (original)
+++ team/jpeeler/chan_dahdi14/contrib/init.d/rc.slackware.asterisk Mon Jun  2 10:50:46 2008
@@ -13,7 +13,7 @@
       # Check if Asterisk is already running.  If it is, then bug out, because
       # starting safe_asterisk when Asterisk is running is very bad.
       VERSION=`/usr/sbin/asterisk -rx 'core show version'`
-      if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
+	  if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
          echo "Asterisk is already running.  $0 will exit now."
          exit 1
       fi

Modified: team/jpeeler/chan_dahdi14/contrib/init.d/rc.suse.asterisk
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/contrib/init.d/rc.suse.asterisk?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/contrib/init.d/rc.suse.asterisk (original)
+++ team/jpeeler/chan_dahdi14/contrib/init.d/rc.suse.asterisk Mon Jun  2 10:50:46 2008
@@ -67,7 +67,7 @@
 	# Check if Asterisk is already running.  If it is, then bug out, because
 	# starting Asterisk when Asterisk is already running is very bad.
 	VERSION=`/usr/sbin/asterisk -rx 'core show version'`
-	if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
+	if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
 		echo "Asterisk is already running.  $0 will exit now."
 		exit 1
 	fi

Modified: team/jpeeler/chan_dahdi14/contrib/scripts/safe_asterisk
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/contrib/scripts/safe_asterisk?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/contrib/scripts/safe_asterisk (original)
+++ team/jpeeler/chan_dahdi14/contrib/scripts/safe_asterisk Mon Jun  2 10:50:46 2008
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 # vim:textwidth=80:tabstop=4:shiftwidth=4:smartindent:autoindent
 
 CLIARGS="$*"				# Grab any args passed to safe_asterisk
@@ -29,7 +29,7 @@
 # Check if Asterisk is already running.  If it is, then bug out, because
 # starting safe_asterisk when Asterisk is running is very bad.
 VERSION=`${ASTSBINDIR}/asterisk -rx 'core show version'`
-if [ "${VERSION:0:8}" = "Asterisk" ]; then # otherwise "Unable t"
+if [ "`echo $VERSION | cut -c 1-8`" = "Asterisk" ]; then
 	echo "Asterisk is already running.  $0 will exit now."
 	exit 1
 fi

Modified: team/jpeeler/chan_dahdi14/main/autoservice.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/main/autoservice.c?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/main/autoservice.c (original)
+++ team/jpeeler/chan_dahdi14/main/autoservice.c Mon Jun  2 10:50:46 2008
@@ -61,7 +61,7 @@
 	 *  it gets stopped for the last time. */
 	unsigned int use_count;
 	unsigned int orig_end_dtmf_flag:1;
-	AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
+	AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
 	AST_LIST_ENTRY(asent) list;
 };
 
@@ -71,29 +71,17 @@
 static pthread_t asthread = AST_PTHREADT_NULL;
 
 static int as_chan_list_state;
-
-static void defer_frame(struct ast_channel *chan, struct ast_frame *f)
-{
-	struct ast_frame *dup_f;
-	struct asent *as;
-
-	AST_LIST_LOCK(&aslist);
-	AST_LIST_TRAVERSE(&aslist, as, list) {
-		if (as->chan != chan)
-			continue;
-		if ((dup_f = ast_frdup(f)))
-			AST_LIST_INSERT_TAIL(&as->dtmf_frames, dup_f, frame_list);
-	}
-	AST_LIST_UNLOCK(&aslist);
-}
 
 static void *autoservice_run(void *ign)
 {
 	for (;;) {
 		struct ast_channel *mons[MAX_AUTOMONS];
+		struct asent *ents[MAX_AUTOMONS];
 		struct ast_channel *chan;
 		struct asent *as;
-		int x = 0, ms = 50;
+		int i, x = 0, ms = 50;
+		struct ast_frame *f = NULL;
+		struct ast_frame *defer_frame = NULL;
 
 		AST_LIST_LOCK(&aslist);
 
@@ -101,43 +89,48 @@
 		 * to get used again. */
 		as_chan_list_state++;
 
-		if (AST_LIST_EMPTY(&aslist))
+		if (AST_LIST_EMPTY(&aslist)) {
 			ast_cond_wait(&as_cond, &aslist.lock);
+		}
 
 		AST_LIST_TRAVERSE(&aslist, as, list) {
 			if (!as->chan->_softhangup) {
-				if (x < MAX_AUTOMONS)
+				if (x < MAX_AUTOMONS) {
+					ents[x] = as;
 					mons[x++] = as->chan;
-				else
+				} else {
 					ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events.  Fix autoservice.c\n");
+				}
 			}
 		}
 
 		AST_LIST_UNLOCK(&aslist);
 
 		chan = ast_waitfor_n(mons, x, &ms);
-		if (chan) {
-			struct ast_frame *f = ast_read(chan);
+		if (!chan) {
+			continue;
+		}
+
+		f = ast_read(chan);
 	
-			if (!f) {
-				struct ast_frame hangup_frame = { 0, };
-				/* No frame means the channel has been hung up.
-				 * A hangup frame needs to be queued here as ast_waitfor() may
-				 * never return again for the condition to be detected outside
-				 * of autoservice.  So, we'll leave a HANGUP queued up so the
-				 * thread in charge of this channel will know. */
-
-				hangup_frame.frametype = AST_FRAME_CONTROL;
-				hangup_frame.subclass = AST_CONTROL_HANGUP;
-
-				defer_frame(chan, &hangup_frame);
-
-				continue;
-			}
-			
+		if (!f) {
+			struct ast_frame hangup_frame = { 0, };
+			/* No frame means the channel has been hung up.
+			 * A hangup frame needs to be queued here as ast_waitfor() may
+			 * never return again for the condition to be detected outside
+			 * of autoservice.  So, we'll leave a HANGUP queued up so the
+			 * thread in charge of this channel will know. */
+
+			hangup_frame.frametype = AST_FRAME_CONTROL;
+			hangup_frame.subclass = AST_CONTROL_HANGUP;
+
+			defer_frame = &hangup_frame;
+		} else {
+
 			/* Do not add a default entry in this switch statement.  Each new
 			 * frame type should be addressed directly as to whether it should
 			 * be queued up or not. */
+
 			switch (f->frametype) {
 			/* Save these frames */
 			case AST_FRAME_DTMF_END:
@@ -145,7 +138,7 @@
 			case AST_FRAME_TEXT:
 			case AST_FRAME_IMAGE:
 			case AST_FRAME_HTML:
-				defer_frame(chan, f);
+				defer_frame = f;
 				break;
 
 			/* Throw these frames away */
@@ -158,12 +151,35 @@
 			case AST_FRAME_MODEM:
 				break;
 			}
-
-			if (f)
+		}
+
+		if (!defer_frame) {
+			if (f) {
 				ast_frfree(f);
-		}
-	}
+			}
+			continue;
+		}
+
+		if (f) {
+			for (i = 0; i < x; i++) {
+				struct ast_frame *dup_f;
+				
+				if (mons[i] != chan) {
+					continue;
+				}
+				
+				if ((dup_f = ast_frdup(f))) {
+					AST_LIST_INSERT_TAIL(&ents[i]->deferred_frames, dup_f, frame_list);
+				}
+				
+				break;
+			}
+			ast_frfree(f);
+		}
+	}
+
 	asthread = AST_PTHREADT_NULL;
+
 	return NULL;
 }
 
@@ -230,14 +246,9 @@
 int ast_autoservice_stop(struct ast_channel *chan)
 {
 	int res = -1;
-	struct asent *as;
-	AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
+	struct asent *as, *removed = NULL;
 	struct ast_frame *f;
-	int removed = 0;
-	int orig_end_dtmf_flag = 0;
 	int chan_list_state;
-
-	AST_LIST_HEAD_INIT_NOLOCK(&dtmf_frames);
 
 	AST_LIST_LOCK(&aslist);
 
@@ -247,41 +258,52 @@
 	 * it after its gone! */
 	chan_list_state = as_chan_list_state;
 
+	/* Find the entry, but do not free it because it still can be in the
+	   autoservice thread array */
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) {	
 		if (as->chan == chan) {
 			as->use_count--;
-			if (as->use_count)
-				break;
-			AST_LIST_REMOVE_CURRENT(&aslist, list);
-			AST_LIST_APPEND_LIST(&dtmf_frames, &as->dtmf_frames, frame_list);
-			orig_end_dtmf_flag = as->orig_end_dtmf_flag;
-			free(as);
-			removed = 1;
-			if (!chan->_softhangup)
-				res = 0;
+			if (as->use_count < 1) {
+				AST_LIST_REMOVE_CURRENT(&aslist, list);
+				removed = as;
+			}
 			break;
 		}
 	}
 	AST_LIST_TRAVERSE_SAFE_END
 
-	if (removed && asthread != AST_PTHREADT_NULL) 
+	if (removed && asthread != AST_PTHREADT_NULL) {
 		pthread_kill(asthread, SIGURG);
+	}
 
 	AST_LIST_UNLOCK(&aslist);
 
-	if (!removed)
+	if (!removed) {
 		return 0;
-
-	if (!orig_end_dtmf_flag)
+	}
+
+	/* Wait while autoservice thread rebuilds its list. */
+	while (chan_list_state == as_chan_list_state) {
+		usleep(1000);
+	}
+
+	/* Now autoservice thread should have no references to our entry
+	   and we can safely destroy it */
+
+	if (!chan->_softhangup) {
+		res = 0;
+	}
+
+	if (!as->orig_end_dtmf_flag) {
 		ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
-
-	while ((f = AST_LIST_REMOVE_HEAD(&dtmf_frames, frame_list))) {
+	}
+
+	while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
 		ast_queue_frame(chan, f);
 		ast_frfree(f);
 	}
 
-	while (chan_list_state == as_chan_list_state)
-		usleep(1000);
+	free(as);
 
 	return res;
 }

Modified: team/jpeeler/chan_dahdi14/main/manager.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/main/manager.c?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/main/manager.c (original)
+++ team/jpeeler/chan_dahdi14/main/manager.c Mon Jun  2 10:50:46 2008
@@ -130,9 +130,12 @@
 	{ 0, "none" },
 };
 
-static const char *command_blacklist[] = {
-	"module load",
-	"module unload",
+#define MAX_BLACKLIST_CMD_LEN 2
+static struct {
+	char *words[AST_MAX_CMD_LEN];
+} command_blacklist[] = {
+	{{ "module", "load", NULL }},
+	{{ "module", "unload", NULL }},
 };
 
 struct mansession {
@@ -1681,6 +1684,41 @@
 	return 0;
 }
 
+static int check_blacklist(const char *cmd)
+{
+	char *cmd_copy, *cur_cmd;
+	char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, };
+	int i;
+
+	cmd_copy = ast_strdupa(cmd);
+	for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
+		cur_cmd = ast_strip(cur_cmd);
+		if (ast_strlen_zero(cur_cmd)) {
+			i--;
+			continue;
+		}
+
+		cmd_words[i] = cur_cmd;
+	}
+
+	for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
+		int j, match = 1;
+
+		for (j = 0; command_blacklist[i].words[j]; j++) {
+			if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
+				match = 0;
+				break;
+			}
+		}
+
+		if (match) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 static char mandescr_command[] = 
 "Description: Run a CLI command.\n"
 "Variables: (Names marked with * are required)\n"
@@ -1694,14 +1732,17 @@
 	const char *id = astman_get_header(m, "ActionID");
 	char *buf, *final_buf;
 	char template[] = "/tmp/ast-ami-XXXXXX";	/* template for temporary file */
-	int fd = mkstemp(template), i = 0;
+	int fd = mkstemp(template);
 	off_t l;
 
-	for (i = 0; i < sizeof(command_blacklist) / sizeof(command_blacklist[0]); i++) {
-		if (!strncmp(cmd, command_blacklist[i], strlen(command_blacklist[i]))) {
-			astman_send_error(s, m, "Command blacklisted");
-			return 0;
-		}
+	if (ast_strlen_zero(cmd)) {
+		astman_send_error(s, m, "No command provided");
+		return 0;
+	}
+
+	if (check_blacklist(cmd)) {
+		astman_send_error(s, m, "Command blacklisted");
+		return 0;
 	}
 
 	astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");

Modified: team/jpeeler/chan_dahdi14/res/res_jabber.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/res/res_jabber.c?view=diff&rev=119798&r1=119797&r2=119798
==============================================================================
--- team/jpeeler/chan_dahdi14/res/res_jabber.c (original)
+++ team/jpeeler/chan_dahdi14/res/res_jabber.c Mon Jun  2 10:50:46 2008
@@ -2359,17 +2359,30 @@
 }
 
 /*!
- * \brief grab a aji_client structure by label name.
- * \param void. 
- * \return 1.
+  * \brief grab a aji_client structure by label name or JID 
+  * (without the resource string)
+  * \param name label or JID 
+  * \return aji_client.
  */
 struct aji_client *ast_aji_get_client(const char *name)
 {
 	struct aji_client *client = NULL;
+	char *aux = NULL;
 
 	client = ASTOBJ_CONTAINER_FIND(&clients, name);
-	if (!client && !strchr(name, '@'))
-		client = ASTOBJ_CONTAINER_FIND_FULL(&clients, name, user,,, strcasecmp);
+ 	if (!client && strchr(name, '@')) {
+ 		ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
+ 			aux = ast_strdupa(iterator->user);
+ 			if (strchr(aux, '/')) {
+ 				/* strip resource for comparison */
+ 				aux = strsep(&aux, "/");
+ 			}
+ 			if (!strcasecmp(aux, name)) {
+ 				client = iterator;
+ 			}				
+ 		});
+ 	}
+ 
 	return client;
 }
 




More information about the asterisk-commits mailing list