[svn-commits] tilghman: branch 1.6.0 r130127 - in /branches/1.6.0: ./ channels/chan_agent.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jul 11 12:30:08 CDT 2008


Author: tilghman
Date: Fri Jul 11 12:30:07 2008
New Revision: 130127

URL: http://svn.digium.com/view/asterisk?view=rev&rev=130127
Log:
Merged revisions 130126 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r130126 | tilghman | 2008-07-11 12:29:24 -0500 (Fri, 11 Jul 2008) | 17 lines

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

........
r130102 | tilghman | 2008-07-11 11:50:42 -0500 (Fri, 11 Jul 2008) | 9 lines

Pass the devicestate from an underlying channel up through the Agent channel.
This should make the Agent always report the correct device state, even when
the underlying channel is used for other purposes.
(closes issue #12773)
 Reported by: davidw
 Patches: 
       20080710__bug12773.diff.txt uploaded by Corydon76 (license 14)
 Tested by: davidw

........

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

Modified:
    branches/1.6.0/   (props changed)
    branches/1.6.0/channels/chan_agent.c

Propchange: branches/1.6.0/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.0/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/branches/1.6.0/channels/chan_agent.c?view=diff&rev=130127&r1=130126&r2=130127
==============================================================================
--- branches/1.6.0/channels/chan_agent.c (original)
+++ branches/1.6.0/channels/chan_agent.c Fri Jul 11 12:30:07 2008
@@ -67,6 +67,7 @@
 #include "asterisk/devicestate.h"
 #include "asterisk/monitor.h"
 #include "asterisk/stringfields.h"
+#include "asterisk/event.h"
 
 static const char tdesc[] = "Call Agent Proxy Channel";
 static const char config[] = "agents.conf";
@@ -142,6 +143,7 @@
 static char savecallsin[AST_MAX_BUF] = "";
 static int updatecdr = 0;
 static char beep[AST_MAX_BUF] = "beep";
+struct ast_event_sub *agent_devicestate_sub = NULL;
 
 #define GETAGENTBYCALLERID	"AGENTBYCALLERID"
 
@@ -164,6 +166,7 @@
 	char agent[AST_MAX_AGENT];     /*!< Agent ID */
 	char password[AST_MAX_AGENT];  /*!< Password for Agent login */
 	char name[AST_MAX_AGENT];
+	int inherited_devicestate;     /*!< Does the underlying channel have a devicestate to pass? */
 	ast_mutex_t app_lock;          /**< Synchronization between owning applications */
 	volatile pthread_t owning_app; /**< Owning application thread id */
 	volatile int app_sleep_cond;   /**< Sleep condition for the login app */
@@ -254,6 +257,48 @@
 	.set_base_channel = agent_set_base_channel,
 };
 
+static void agent_devicestate_cb(const struct ast_event *event, void *unused)
+{
+	int res, i;
+	struct agent_pvt *p;
+	char basename[AST_CHANNEL_NAME], *tmp;
+	const char *device;
+	enum ast_device_state state;
+
+	/* Try to be safe, but don't deadlock */
+	for (i = 0; i < 10; i++) {
+		if ((res = AST_LIST_TRYLOCK(&agents)) == 0) {
+			break;
+		}
+	}
+	if (res) {
+		return;
+	}
+
+	state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
+	device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
+
+	if (ast_strlen_zero(device)) {
+		return;
+	}
+
+	AST_LIST_TRAVERSE(&agents, p, list) {
+		ast_mutex_lock(&p->lock);
+		if (p->chan) {
+			ast_copy_string(basename, p->chan->name, sizeof(basename));
+			if ((tmp = strrchr(basename, '-'))) {
+				*tmp = '\0';
+			}
+			if (strcasecmp(p->chan->name, device) == 0 || strcasecmp(basename, device) == 0) {
+				p->inherited_devicestate = state;
+				ast_device_state_changed("Agent/%s", p->agent);
+			}
+		}
+		ast_mutex_unlock(&p->lock);
+	}
+	AST_LIST_UNLOCK(&agents);
+}
+
 /*!
  * Adds an agent to the global list of agents.
  *
@@ -316,6 +361,7 @@
 		p->app_sleep_cond = 1;
 		p->group = group;
 		p->pending = pending;
+		p->inherited_devicestate = -1;
 		AST_LIST_INSERT_TAIL(&agents, p, list);
 	}
 	
@@ -457,6 +503,7 @@
 					p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
 			}
 			p->chan = NULL;
+			p->inherited_devicestate = -1;
 			p->acknowledged = 0;
 		}
  	} else {
@@ -671,6 +718,7 @@
 	} else {
 		/* Agent hung-up */
 		p->chan = NULL;
+		p->inherited_devicestate = -1;
 	}
 
 	if (!res) {
@@ -791,6 +839,7 @@
 				/* Recognize the hangup and pass it along immediately */
 				ast_hangup(p->chan);
 				p->chan = NULL;
+				p->inherited_devicestate = -1;
 			}
 			ast_debug(1, "Hungup, howlong is %d, autologoff is %d\n", howlong, p->autologoff);
 			if ((p->deferlogoff) || (howlong && p->autologoff && (howlong > p->autologoff))) {
@@ -1509,6 +1558,7 @@
 	set_agentbycallerid(p->logincallerid, NULL);
 	p->loginchan[0] ='\0';
 	p->logincallerid[0] = '\0';
+	p->inherited_devicestate = -1;
 	ast_device_state_changed("Agent/%s", p->agent);
 	if (persistent_agents)
 		dump_agents();	
@@ -2054,8 +2104,10 @@
 						if (res && p->owner) 
 							ast_log(LOG_WARNING, "Huh?  We broke out when there was still an owner?\n");
 						/* Log us off if appropriate */
-						if (p->chan == chan)
+						if (p->chan == chan) {
 							p->chan = NULL;
+							p->inherited_devicestate = -1;
+						}
 						p->acknowledged = 0;
 						logintime = time(NULL) - p->loginstart;
 						p->loginstart = 0;
@@ -2268,6 +2320,8 @@
 			if (p->owner) {
 				if (res != AST_DEVICE_INUSE)
 					res = AST_DEVICE_BUSY;
+			} else if (p->inherited_devicestate > -1) {
+				res = p->inherited_devicestate;
 			} else {
 				if (res == AST_DEVICE_BUSY)
 					res = AST_DEVICE_INUSE;
@@ -2409,6 +2463,8 @@
 	/* Dialplan Functions */
 	ast_custom_function_register(&agent_function);
 
+	agent_devicestate_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, agent_devicestate_cb, NULL);
+
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
@@ -2426,6 +2482,8 @@
 	struct agent_pvt *p;
 	/* First, take us out of the channel loop */
 	ast_channel_unregister(&agent_tech);
+	/* Delete devicestate subscription */
+	agent_devicestate_sub = ast_event_unsubscribe(agent_devicestate_sub);
 	/* Unregister dialplan functions */
 	ast_custom_function_unregister(&agent_function);	
 	/* Unregister CLI commands */




More information about the svn-commits mailing list