Merged revisions 189203 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r189203 | dvossel | 2009-04-17 20:27:19 -0500 (Fri, 17 Apr 2009) | 12 lines
  
  Fixed autologoff in agents.conf not working when agent logs in via AgentLogin app
  
  An agent logs in by calling an extension that calls the AgentLogin app.  In agents.conf ackcall=always is set, so when they get a call they have the choice to either acknowledge it or ignore it.  autologoff=10 is set as well, so if the agent ignores the call over 10sec one may assume that the agent should be logged out (and in this case hungup on as well), but this was not happening.
  
  (closes issue #14091)
  Reported by: evandro
  Patches:
        autologoff.diff uploaded by dvossel (license 671)
  
  Review: http://reviewboard.digium.com/r/225/
........


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@189204 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
David Vossel
2009-04-18 01:28:45 +00:00
parent 13af9ed74c
commit 437eec8423

View File

@@ -318,6 +318,7 @@ static void set_agentbycallerid(const char *callerid, const char *agent);
static char *complete_agent_logoff_cmd(const char *line, const char *word, int pos, int state); static char *complete_agent_logoff_cmd(const char *line, const char *word, int pos, int state);
static struct ast_channel* agent_get_base_channel(struct ast_channel *chan); static struct ast_channel* agent_get_base_channel(struct ast_channel *chan);
static int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base); static int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base);
static int agent_logoff(const char *agent, int soft);
/*! \brief Channel interface description for PBX integration */ /*! \brief Channel interface description for PBX integration */
static const struct ast_channel_tech agent_tech = { static const struct ast_channel_tech agent_tech = {
@@ -520,8 +521,12 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
struct ast_frame *f = NULL; struct ast_frame *f = NULL;
static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
const char *status; const char *status;
int cur_time = time(NULL);
ast_mutex_lock(&p->lock); ast_mutex_lock(&p->lock);
CHECK_FORMATS(ast, p); CHECK_FORMATS(ast, p);
if (!p->start) {
p->start = cur_time;
}
if (p->chan) { if (p->chan) {
ast_copy_flags(p->chan, ast, AST_FLAG_EXCEPTION); ast_copy_flags(p->chan, ast, AST_FLAG_EXCEPTION);
p->chan->fdno = (ast->fdno == AST_AGENT_FD) ? AST_TIMING_FD : ast->fdno; p->chan->fdno = (ast->fdno == AST_AGENT_FD) ? AST_TIMING_FD : ast->fdno;
@@ -538,19 +543,16 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
if (p->chan) if (p->chan)
ast_debug(1, "Bridge on '%s' being cleared (2)\n", p->chan->name); ast_debug(1, "Bridge on '%s' being cleared (2)\n", p->chan->name);
if (p->owner->_state != AST_STATE_UP) { if (p->owner->_state != AST_STATE_UP) {
int howlong = time(NULL) - p->start; int howlong = cur_time - p->start;
if (p->autologoff && howlong > p->autologoff) { if (p->autologoff && howlong >= p->autologoff) {
long logintime = time(NULL) - p->loginstart;
p->loginstart = 0; p->loginstart = 0;
ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong); ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Autologoff"); agent_logoff_maintenance(p, p->loginchan, (cur_time = p->loginstart), ast->uniqueid, "Autologoff");
if (persistent_agents)
dump_agents();
} }
} }
status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS"); status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS");
if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) { if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) {
long logintime = time(NULL) - p->loginstart; long logintime = cur_time - p->loginstart;
p->loginstart = 0; p->loginstart = 0;
ast_log(LOG_NOTICE, "Agent read: '%s' is not available now, auto logoff\n", p->name); ast_log(LOG_NOTICE, "Agent read: '%s' is not available now, auto logoff\n", p->name);
agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Chanunavail"); agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Chanunavail");
@@ -566,8 +568,18 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
} else { } else {
/* if acknowledgement is not required, and the channel is up, we may have missed /* if acknowledgement is not required, and the channel is up, we may have missed
an AST_CONTROL_ANSWER (if there was one), so mark the call acknowledged anyway */ an AST_CONTROL_ANSWER (if there was one), so mark the call acknowledged anyway */
if (!p->ackcall && !p->acknowledged && p->chan && (p->chan->_state == AST_STATE_UP)) if (!p->ackcall && !p->acknowledged && p->chan && (p->chan->_state == AST_STATE_UP)) {
p->acknowledged = 1; p->acknowledged = 1;
}
if (!p->acknowledged) {
int howlong = cur_time - p->start;
if (p->autologoff && (howlong >= p->autologoff)) {
ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
agent_logoff_maintenance(p, p->loginchan, (cur_time - p->loginstart), ast->uniqueid, "Autologoff");
agent_logoff(p->agent, 0);
}
}
switch (f->frametype) { switch (f->frametype) {
case AST_FRAME_CONTROL: case AST_FRAME_CONTROL:
if (f->subclass == AST_CONTROL_ANSWER) { if (f->subclass == AST_CONTROL_ANSWER) {