From 1874f21ff8dee7d4a2cc8941b31c88af494602d6 Mon Sep 17 00:00:00 2001 From: BJ Weschke Date: Fri, 13 Jan 2006 18:23:30 +0000 Subject: Implement the autologoffunavail option in chan_agent (#6038 with some minor mods) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@8063 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_agent.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ channels/chan_local.c | 4 ++++ configs/agents.conf.sample | 7 +++++++ doc/manager.txt | 1 + doc/queuelog.txt | 3 ++- 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/channels/chan_agent.c b/channels/chan_agent.c index 768e15984..534b0ee75 100644 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -158,6 +158,7 @@ static int autologoff; static int wrapuptime; static int ackcall; static int multiplelogin = 1; +static int autologoffunavail = 0; static int maxlogintries = 3; static char agentgoodbye[AST_MAX_FILENAME_LEN] = "vm-goodbye"; @@ -255,6 +256,7 @@ static int agent_sendtext(struct ast_channel *ast, const char *text); static int agent_indicate(struct ast_channel *ast, int condition); static int agent_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge); +static void set_agentbycallerid(const char *callerid, const char *agent); static const struct ast_channel_tech agent_tech = { .type = channeltype, @@ -464,6 +466,7 @@ static struct ast_frame *agent_read(struct ast_channel *ast) struct ast_frame *f = NULL; static struct ast_frame null_frame = { AST_FRAME_NULL, }; static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; + const char *status; ast_mutex_lock(&p->lock); CHECK_FORMATS(ast, p); if (p->chan) { @@ -484,6 +487,26 @@ static struct ast_frame *agent_read(struct ast_channel *ast) if (!ast_strlen_zero(p->loginchan)) { if (p->chan) ast_log(LOG_DEBUG, "Bridge on '%s' being cleared (2)\n", p->chan->name); + + status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS"); + if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) { + char agent[AST_MAX_AGENT] = ""; + long logintime = time(NULL) - p->loginstart; + p->loginstart = 0; + ast_log(LOG_NOTICE, "Agent read: '%s' is not available now, auto logoff\n", p->name); + manager_event(EVENT_FLAG_AGENT, "Agentcallbacklogoff", + "Agent: %s\r\n" + "Loginchan: %s\r\n" + "Logintime: %ld\r\n" + "Reason: Chanunavail\r\n" + "Uniqueid: %s\r\n", + p->agent, p->loginchan, logintime, ast->uniqueid); + snprintf(agent, sizeof(agent), "Agent/%s", p->agent); + ast_queue_log("NONE", ast->uniqueid, agent, "AGENTCALLBACKLOGOFF", "%s|%ld|%s", p->loginchan, logintime, "Chanunavail"); + set_agentbycallerid(p->logincallerid, NULL); + p->loginchan[0] = '\0'; + p->logincallerid[0] = '\0'; + } ast_hangup(p->chan); if (p->wrapuptime && p->acknowledged) p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000)); @@ -732,6 +755,7 @@ static int agent_hangup(struct ast_channel *ast) { struct agent_pvt *p = ast->tech_pvt; int howlong = 0; + const char *status; ast_mutex_lock(&p->lock); p->owner = NULL; ast->tech_pvt = NULL; @@ -767,6 +791,25 @@ static int agent_hangup(struct ast_channel *ast) else p->lastdisc = ast_tv(0,0); if (p->chan) { + status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS"); + if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) { + char agent[AST_MAX_AGENT] = ""; + long logintime = time(NULL) - p->loginstart; + p->loginstart = 0; + ast_log(LOG_NOTICE, "Agent hangup: '%s' is not available now, auto logoff\n", p->name); + manager_event(EVENT_FLAG_AGENT, "Agentcallbacklogoff", + "Agent: %s\r\n" + "Loginchan: %s\r\n" + "Logintime: %ld\r\n" + "Reason: Chanunavail\r\n" + "Uniqueid: %s\r\n", + p->agent, p->loginchan, logintime, ast->uniqueid); + snprintf(agent, sizeof(agent), "Agent/%s", p->agent); + ast_queue_log("NONE", ast->uniqueid, agent, "AGENTCALLBACKLOGOFF", "%s|%ld|%s", p->loginchan, logintime, "Chanunavail"); + set_agentbycallerid(p->logincallerid, NULL); + p->loginchan[0] = '\0'; + p->logincallerid[0] = '\0'; + } /* Recognize the hangup and pass it along immediately */ ast_hangup(p->chan); p->chan = NULL; @@ -1086,6 +1129,11 @@ static int read_agent_config(void) updatecdr = 1; else updatecdr = 0; + } else if (!strcasecmp(v->name, "autologoffunavail")) { + if (ast_true(v->value)) + autologoffunavail = 1; + else + autologoffunavail = 0; } else if (!strcasecmp(v->name, "recordagentcalls")) { recordagentcalls = ast_true(v->value); } else if (!strcasecmp(v->name, "recordformat")) { diff --git a/channels/chan_local.c b/channels/chan_local.c index 44103de50..612e28c8b 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -390,10 +390,14 @@ static int local_hangup(struct ast_channel *ast) struct local_pvt *cur, *prev=NULL; struct ast_channel *ochan = NULL; int glaredetect; + char *status; ast_mutex_lock(&p->lock); isoutbound = IS_OUTBOUND(ast, p); if (isoutbound) { + status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS"); + if(status) + pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status); p->chan = NULL; p->launchedpbx = 0; } else diff --git a/configs/agents.conf.sample b/configs/agents.conf.sample index fd631b431..5d9761cda 100644 --- a/configs/agents.conf.sample +++ b/configs/agents.conf.sample @@ -22,6 +22,13 @@ persistentagents=yes ; ;autologoff=15 ; +; Define autologoffunavail to have agents automatically logged +; out when the extension that they are at returns a CHANUNAVAIL +; status when a call is attempted to be sent there. +; Default is "no". +; +;autologoffunavail=yes +; ; Define ackcall to require an acknowledgement by '#' when ; an agent logs in using agentcallbacklogin. Default is "no". ; diff --git a/doc/manager.txt b/doc/manager.txt index bd5df8077..065d70a21 100644 --- a/doc/manager.txt +++ b/doc/manager.txt @@ -252,6 +252,7 @@ Some standard AMI headers: Position: -- Position in Queue Queue: -- Queue name Reason: -- "Autologoff" + Reason: -- "Chanunavail" Response: -- response code, like "200 OK" "Success", "Error", "Follows" Restart: -- "True", "False" diff --git a/doc/queuelog.txt b/doc/queuelog.txt index a11812eef..374b7a488 100644 --- a/doc/queuelog.txt +++ b/doc/queuelog.txt @@ -32,7 +32,8 @@ the agent was logged in. AGENTCALLBACKLOGOFF(exten@context|logintime|reason) The callback agent logged off. The last login extension and context is recorded, along with the total time the agent was logged in, and the -reason for the logoff if it was not a normal logoff (e.g., Autologoff) +reason for the logoff if it was not a normal logoff +(e.g., Autologoff, Chanunavail) COMPLETEAGENT(holdtime|calltime|origposition) The caller was connected to an agent, and the call was terminated normally -- cgit v1.2.3