Index: channels/chan_agent.c =================================================================== --- channels/chan_agent.c (revision 170835) +++ channels/chan_agent.c (working copy) @@ -201,6 +201,7 @@ struct ast_channel *owner; /**< Agent */ char loginchan[80]; /**< channel they logged in from */ char logincallerid[80]; /**< Caller ID they had when they logged in */ + char origchan[80]; /*!< Channel they logged in from */ struct ast_channel *chan; /**< Channel we use */ AST_LIST_ENTRY(agent_pvt) list; /**< Next Agent in the linked list. */ }; @@ -288,7 +289,6 @@ { int res, i; struct agent_pvt *p; - char basename[AST_CHANNEL_NAME], *tmp; /* Skip Agent status */ if (!strncasecmp(dev, "Agent/", 6)) { @@ -307,12 +307,13 @@ 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 (!ast_strlen_zero(p->origchan)) { + if (strcasecmp(p->origchan, dev) == 0) { + p->inherited_devicestate = state; + ast_device_state_changed("Agent/%s", p->agent); } - if (strcasecmp(p->chan->name, dev) == 0 || strcasecmp(basename, dev) == 0) { + } else if (p->chan && !ast_strlen_zero(p->loginchan)) { + if (strcasecmp(p->chan->name, dev) == 0) { p->inherited_devicestate = state; ast_device_state_changed("Agent/%s", p->agent); } @@ -916,6 +917,7 @@ if (!p->loginstart) { p->loginchan[0] = '\0'; p->logincallerid[0] = '\0'; + p->origchan[0] = '\0'; if (persistent_agents) dump_agents(); } else { @@ -1638,6 +1640,7 @@ ast_queue_log("NONE", ast_strlen_zero(uniqueid) ? "NONE" : uniqueid, agent, "AGENTCALLBACKLOGOFF", "%s|%ld|%s", loginchan, logintime, tmp); set_agentbycallerid(p->logincallerid, NULL); p->loginchan[0] ='\0'; + p->origchan[0] = '\0'; p->logincallerid[0] = '\0'; p->inherited_devicestate = -1; ast_device_state_changed("Agent/%s", p->agent); @@ -2140,12 +2143,22 @@ if (ast_strlen_zero(p->loginchan)) { login_state = 2; filename = "agent-loggedoff"; + p->origchan[0] = '\0'; } else { if (chan->cid.cid_num) { ast_copy_string(p->logincallerid, chan->cid.cid_num, sizeof(p->logincallerid)); set_agentbycallerid(p->logincallerid, p->agent); } else p->logincallerid[0] = '\0'; + if (strncasecmp(chan->name, "Local/", 6) != 0) { + char *dashptr; + ast_copy_string(p->origchan, chan->name, sizeof(basename)); + if ((dashptr = strrchr(p->origchan, '-'))) { + *dashptr = '\0'; + } + } else { + ast_log(LOG_WARNING, "AgentCallbackLogin called with Local channel. Devicestate will be much less accurate.\n"); + } } if(update_cdr && chan->cdr) @@ -2155,6 +2168,7 @@ } else { p->loginchan[0] = '\0'; p->logincallerid[0] = '\0'; + p->origchan[0] = '\0'; p->acknowledged = 0; } ast_mutex_unlock(&p->lock); @@ -2432,6 +2446,7 @@ const char *agent = astman_get_header(m, "Agent"); const char *exten = astman_get_header(m, "Exten"); const char *context = astman_get_header(m, "Context"); + const char *channel = astman_get_header(m, "Channel"); const char *wrapuptime_s = astman_get_header(m, "WrapupTime"); const char *ackcall_s = astman_get_header(m, "AckCall"); struct agent_pvt *p; @@ -2444,7 +2459,9 @@ return 0; } - if (ast_strlen_zero(exten)) { + /* Intentionally NOT "!ast_strlen_zero()". Zero-length (but not NULL) + * is how we logout. */ + if (exten == NULL) { astman_send_error(s, m, "No extension specified"); return 0; } @@ -2460,11 +2477,17 @@ ast_mutex_lock(&p->lock); login_state = 1; /* Successful Login */ - if (ast_strlen_zero(context)) + if (ast_strlen_zero(context) || ast_strlen_zero(exten)) ast_copy_string(p->loginchan, exten, sizeof(p->loginchan)); else snprintf(p->loginchan, sizeof(p->loginchan), "%s@%s", exten, context); + if (!ast_strlen_zero(p->loginchan) && !ast_strlen_zero(channel)) { + ast_copy_string(p->origchan, channel, sizeof(p->origchan)); + } else if (ast_strlen_zero(p->loginchan)) { + p->origchan[0] = '\0'; + } + if (!ast_strlen_zero(wrapuptime_s)) { p->wrapuptime = atoi(wrapuptime_s); if (p->wrapuptime < 0)