aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-25 17:19:39 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-25 17:19:39 +0000
commit1c852c16ad8f394f8e6b8793286ca199630a1a88 (patch)
tree2cd3fa538b72b1c5dff3ed9c8a14dbc083d6637b
parent958638e4ee206b2b2b18d79d939518bc3c0336a2 (diff)
Fix some errant device states by making the devicestate API more strict in
terms of the device argument (only without the unique identifier appended). (closes issue #12771) Reported by: davidw Patches: 20080717__bug12771.diff.txt uploaded by Corydon76 (license 14) Tested by: davidw, jvandal, murf git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@133649 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_agent.c8
-rw-r--r--main/channel.c13
-rw-r--r--main/devicestate.c29
3 files changed, 22 insertions, 28 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index cd431a642..45232f336 100644
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -289,6 +289,11 @@ static int agent_devicestate_cb(const char *dev, int state, void *data)
struct agent_pvt *p;
char basename[AST_CHANNEL_NAME], *tmp;
+ /* Skip Agent status */
+ if (!strncasecmp(dev, "Agent/", 6)) {
+ return 0;
+ }
+
/* Try to be safe, but don't deadlock */
for (i = 0; i < 10; i++) {
if ((res = AST_LIST_TRYLOCK(&agents)) == 0) {
@@ -522,6 +527,7 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
}
p->chan = NULL;
p->inherited_devicestate = -1;
+ ast_device_state_changed("Agent/%s", p->agent);
p->acknowledged = 0;
}
} else {
@@ -744,6 +750,7 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
/* Agent hung-up */
p->chan = NULL;
p->inherited_devicestate = -1;
+ ast_device_state_changed("Agent/%s", p->agent);
}
if (!res) {
@@ -867,6 +874,7 @@ static int agent_hangup(struct ast_channel *ast)
ast_hangup(p->chan);
p->chan = NULL;
p->inherited_devicestate = -1;
+ ast_device_state_changed("Agent/%s", p->agent);
}
ast_log(LOG_DEBUG, "Hungup, howlong is %d, autologoff is %d\n", howlong, p->autologoff);
if ((p->deferlogoff) || (howlong && p->autologoff && (howlong > p->autologoff))) {
diff --git a/main/channel.c b/main/channel.c
index 9a5d70125..1383feb0f 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1201,7 +1201,7 @@ void ast_channel_free(struct ast_channel *chan)
struct ast_frame *f;
struct varshead *headp;
struct ast_datastore *datastore = NULL;
- char name[AST_CHANNEL_NAME];
+ char name[AST_CHANNEL_NAME], *dashptr;
headp=&chan->varshead;
@@ -1234,6 +1234,9 @@ void ast_channel_free(struct ast_channel *chan)
sched_context_destroy(chan->sched);
ast_copy_string(name, chan->name, sizeof(name));
+ if ((dashptr = strrchr(name, '-'))) {
+ *dashptr = '\0';
+ }
/* Stop monitoring */
if (chan->monitor)
@@ -3669,13 +3672,19 @@ void ast_set_callerid(struct ast_channel *chan, const char *callerid, const char
int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
{
+ char name[AST_CHANNEL_NAME], *dashptr;
int oldstate = chan->_state;
if (oldstate == state)
return 0;
+ ast_copy_string(name, chan->name, sizeof(name));
+ if ((dashptr = strrchr(name, '-'))) {
+ *dashptr = '\0';
+ }
+
chan->_state = state;
- ast_device_state_changed_literal(chan->name);
+ ast_device_state_changed_literal(name);
/* setstate used to conditionally report Newchannel; this is no more */
manager_event(EVENT_FLAG_CALL,
"Newstate",
diff --git a/main/devicestate.c b/main/devicestate.c
index cc647a823..f84c87df7 100644
--- a/main/devicestate.c
+++ b/main/devicestate.c
@@ -294,17 +294,13 @@ static void do_state_change(const char *device)
ast_hint_state_changed(device);
}
-static int __ast_device_state_changed_literal(char *buf, int norecurse)
+int ast_device_state_changed_literal(const char *device)
{
- char *device;
struct state_change *change;
- char *tmp = NULL;
if (option_debug > 2)
- ast_log(LOG_DEBUG, "Notification of state change to be queued on device/channel %s\n", buf);
+ ast_log(LOG_DEBUG, "Notification of state change to be queued on device/channel %s\n", device);
- device = buf;
-
if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) {
/* we could not allocate a change struct, or */
/* there is no background thread, so process the change now */
@@ -320,28 +316,9 @@ static int __ast_device_state_changed_literal(char *buf, int norecurse)
AST_LIST_UNLOCK(&state_changes);
}
- /* The problem with this API is that a device may be called with the unique
- * identifier appended or not, but it's separated from the channel name
- * with a '-', which is also a legitimate character in a channel name. So,
- * we have to force both names to get their names checked for state changes
- * to ensure that the right one gets notified. Not a huge performance hit,
- * but it might could be fixed by an enterprising programmer in trunk.
- */
- if (!norecurse && (tmp = strrchr(device, '-'))) {
- *tmp = '\0';
- __ast_device_state_changed_literal(device, 1);
- }
-
return 1;
}
-int ast_device_state_changed_literal(const char *dev)
-{
- char *buf;
- buf = ast_strdupa(dev);
- return __ast_device_state_changed_literal(buf, 0);
-}
-
/*! \brief Accept change notification, add it to change queue */
int ast_device_state_changed(const char *fmt, ...)
{
@@ -351,7 +328,7 @@ int ast_device_state_changed(const char *fmt, ...)
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- return __ast_device_state_changed_literal(buf, 0);
+ return ast_device_state_changed_literal(buf);
}
/*! \brief Go through the dev state change queue and update changes in the dev state thread */