Add new features to agent stuff (bug #1693)
authorMark Spencer <markster@digium.com>
Sun, 24 Oct 2004 13:24:16 +0000 (13:24 +0000)
committerMark Spencer <markster@digium.com>
Sun, 24 Oct 2004 13:24:16 +0000 (13:24 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4083 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_agent.c

index 706f675..568d53c 100755 (executable)
@@ -63,13 +63,17 @@ static char *descrip =
 "when a new call comes in.  The agent can dump the call by pressing\n"
 "the star key.\n"
 "The option string may contain zero or more of the following characters:\n"
 "when a new call comes in.  The agent can dump the call by pressing\n"
 "the star key.\n"
 "The option string may contain zero or more of the following characters:\n"
-"      's' -- silent login - do not announce the login ok segment\n";
+"      's' -- silent login - do not announce the login ok segment after agent logged in/off\n";
 
 static char *descrip2 =
 "  AgentCallbackLogin([AgentNo][|[options][exten]@context]):\n"
 
 static char *descrip2 =
 "  AgentCallbackLogin([AgentNo][|[options][exten]@context]):\n"
-"Asks the agent to login to the system with callback.  Always returns -1.\n"
+"Asks the agent to login to the system with callback.\n"
 "The agent's callback extension is called (optionally with the specified\n"
 "The agent's callback extension is called (optionally with the specified\n"
-"context. \n";
+"context). \n"
+"The option string may contain zero or more of the following characters:\n"
+"      's' -- silent login - do not announce the login ok segment agent logged in/off\n";
+
 
 static char *descrip3 =
 "  AgentMonitorOutgoing([options]):\n"
 
 static char *descrip3 =
 "  AgentMonitorOutgoing([options]):\n"
@@ -81,6 +85,7 @@ static char moh[80] = "default";
 
 #define AST_MAX_AGENT  80              /* Agent ID or Password max length */
 #define AST_MAX_BUF    256
 
 #define AST_MAX_AGENT  80              /* Agent ID or Password max length */
 #define AST_MAX_BUF    256
+#define AST_MAX_FILENAME_LEN   256
 
 static int capability = -1;
 
 
 static int capability = -1;
 
@@ -89,6 +94,9 @@ static int autologoff;
 static int wrapuptime;
 static int ackcall;
 
 static int wrapuptime;
 static int ackcall;
 
+static int maxlogintries = 3;
+static char agentgoodbye[AST_MAX_FILENAME_LEN] = "vm-goodbye";
+
 static int usecnt =0;
 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
 
 static int usecnt =0;
 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
 
@@ -868,10 +876,19 @@ static int read_agent_config(void)
                        wrapuptime = atoi(v->value);
                        if (wrapuptime < 0)
                                wrapuptime = 0;
                        wrapuptime = atoi(v->value);
                        if (wrapuptime < 0)
                                wrapuptime = 0;
+               } else if (!strcasecmp(v->name, "maxlogintries") && !ast_strlen_zero(v->value)) {
+                       maxlogintries = atoi(v->value);
+                       if (maxlogintries < 0)
+                               maxlogintries = 0;
+               } else if (!strcasecmp(v->name, "goodbye") && !ast_strlen_zero(v->value)) {
+                       strcpy(agentgoodbye,v->value);
                } else if (!strcasecmp(v->name, "musiconhold")) {
                        strncpy(moh, v->value, sizeof(moh) - 1);
                } else if (!strcasecmp(v->name, "updatecdr")) {
                } else if (!strcasecmp(v->name, "musiconhold")) {
                        strncpy(moh, v->value, sizeof(moh) - 1);
                } else if (!strcasecmp(v->name, "updatecdr")) {
-                       updatecdr = ast_true(v->value);
+                       if (ast_true(v->value))
+                               updatecdr = 1;
+                       else
+                               updatecdr = 0;
                } else if (!strcasecmp(v->name, "recordagentcalls")) {
                        recordagentcalls = ast_true(v->value);
                } else if (!strcasecmp(v->name, "createlink")) {
                } else if (!strcasecmp(v->name, "recordagentcalls")) {
                        recordagentcalls = ast_true(v->value);
                } else if (!strcasecmp(v->name, "createlink")) {
@@ -1205,9 +1222,11 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
 {
        int res=0;
        int tries = 0;
 {
        int res=0;
        int tries = 0;
+       int max_login_tries = maxlogintries;
        struct agent_pvt *p;
        struct localuser *u;
        struct timeval tv;
        struct agent_pvt *p;
        struct localuser *u;
        struct timeval tv;
+       int login_state = 0;
        char user[AST_MAX_AGENT] = "";
        char pass[AST_MAX_AGENT];
        char agent[AST_MAX_AGENT] = "";
        char user[AST_MAX_AGENT] = "";
        char pass[AST_MAX_AGENT];
        char agent[AST_MAX_AGENT] = "";
@@ -1216,9 +1235,15 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
        char info[512];
        char *opt_user = NULL;
        char *options = NULL;
        char info[512];
        char *opt_user = NULL;
        char *options = NULL;
+       char option;
+       char badoption[2];
+       char *tmpoptions = NULL;
        char *context = NULL;
        char *exten = NULL;
        char *context = NULL;
        char *exten = NULL;
-       int play_announcement;
+       int play_announcement = 1;
+       char agent_goodbye[AST_MAX_FILENAME_LEN];
+       strcpy(agent_goodbye, agentgoodbye);
+       int update_cdr = updatecdr;
        char *filename = "agent-loginok";
        
        LOCAL_USER_ADD(u);
        char *filename = "agent-loginok";
        
        LOCAL_USER_ADD(u);
@@ -1226,7 +1251,30 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
        /* Parse the arguments XXX Check for failure XXX */
        strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
        opt_user = info;
        /* Parse the arguments XXX Check for failure XXX */
        strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
        opt_user = info;
-       if( opt_user ) {
+       /* Set Channel Specific Login Overrides */
+       if (pbx_builtin_getvar_helper(chan, "AGENTLMAXLOGINTRIES") && strlen(pbx_builtin_getvar_helper(chan, "AGENTLMAXLOGINTRIES"))) {
+               max_login_tries = atoi(pbx_builtin_getvar_helper(chan, "AGENTMAXLOGINTRIES"));
+               if (max_login_tries < 0)
+                       max_login_tries = 0;
+               tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTMAXLOGINTRIES");
+               ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTMAXLOGINTRIES=%s, setting max_login_tries to: %d on Channel '%s'.\n",tmpoptions,max_login_tries,chan->name);
+       }
+       if (pbx_builtin_getvar_helper(chan, "AGENTUPDATECDR") && strlen(pbx_builtin_getvar_helper(chan, "AGENTUPDATECDR"))) {
+               if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTUPDATECDR")))
+                       update_cdr = 1;
+               else
+                       update_cdr = 0;
+               tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTUPDATECDR");
+               ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTUPDATECDR=%s, setting update_cdr to: %d on Channel '%s'.\n",tmpoptions,update_cdr,chan->name);
+       }
+       if (pbx_builtin_getvar_helper(chan, "AGENTGOODBYE") && strlen(pbx_builtin_getvar_helper(chan, "AGENTGOODBYE"))) {
+               strcpy(agent_goodbye, pbx_builtin_getvar_helper(chan, "AGENTGOODBYE"));
+               tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTGOODBYE");
+               ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTGOODBYE=%s, setting agent_goodbye to: %s on Channel '%s'.\n",tmpoptions,agent_goodbye,chan->name);
+       }
+       /* End Channel Specific Login Overrides */
+       /* Read command line options */
+        if( opt_user ) {
                options = strchr(opt_user, '|');
                if (options) {
                        *options = '\0';
                options = strchr(opt_user, '|');
                if (options) {
                        *options = '\0';
@@ -1243,7 +1291,22 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                                        exten = NULL;
                        }
                }
                                        exten = NULL;
                        }
                }
+               if ( options ) {
+                       while (*options) {
+                               option = (char)options[0];
+                               if (option=='s')
+                                       play_announcement = 0;
+                               else {
+                                       badoption[0] = option;
+                                       badoption[1] = '\0';
+                                       tmpoptions=badoption;
+                                       ast_verbose(VERBOSE_PREFIX_3 "Warning: option %s is unknown.\n",tmpoptions);
+                               }
+                               options++;
+                       }
+               }
        }
        }
+       /* End command line options */
 
        if (chan->_state != AST_STATE_UP)
                res = ast_answer(chan);
 
        if (chan->_state != AST_STATE_UP)
                res = ast_answer(chan);
@@ -1253,7 +1316,8 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                else
                        res = ast_app_getdata(chan, "agent-user", user, sizeof(user) - 1, 0);
        }
                else
                        res = ast_app_getdata(chan, "agent-user", user, sizeof(user) - 1, 0);
        }
-       while (!res && (tries < 3)) {
+       while (!res && (max_login_tries==0 || tries < max_login_tries)) {
+               tries++;
                /* Check for password */
                ast_mutex_lock(&agentlock);
                p = agents;
                /* Check for password */
                ast_mutex_lock(&agentlock);
                p = agents;
@@ -1282,6 +1346,33 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                        ast_mutex_lock(&p->lock);
                        if (!strcmp(p->agent, user) &&
                                !strcmp(p->password, pass) && !p->pending) {
                        ast_mutex_lock(&p->lock);
                        if (!strcmp(p->agent, user) &&
                                !strcmp(p->password, pass) && !p->pending) {
+                                       login_state = 1; /* Successful Login */
+                                       /* Set Channel Specific Agent Overides */
+                                       if (pbx_builtin_getvar_helper(chan, "AGENTACKCALL") && strlen(pbx_builtin_getvar_helper(chan, "AGENTACKCALL"))) {
+                                               if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTACKCALL"), "always"))
+                                                       p->ackcall = 2;
+                                               else if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTACKCALL")))
+                                                       p->ackcall = 1;
+                                               else
+                                                       p->ackcall = 0;
+                                               tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTACKCALL");
+                                               ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTACKCALL=%s, setting ackcall to: %d for Agent '%s'.\n",tmpoptions,p->ackcall,p->agent);
+                                       }
+                                       if (pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF") && strlen(pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF"))) {
+                                               p->autologoff = atoi(pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF"));
+                                               if (p->autologoff < 0)
+                                                       p->autologoff = 0;
+                                               tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF");
+                                               ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTAUTOLOGOFF=%s, setting autologff to: %d for Agent '%s'.\n",tmpoptions,p->autologoff,p->agent);
+                                       }
+                                       if (pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME") && strlen(pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME"))) {
+                                               p->wrapuptime = atoi(pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME"));
+                                               if (p->wrapuptime < 0)
+                                                       p->wrapuptime = 0;
+                                               tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME");
+                                               ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTWRAPUPTIME=%s, setting wrapuptime to: %d for Agent '%s'.\n",tmpoptions,p->wrapuptime,p->agent);
+                                       }
+                                       /* End Channel Specific Agent Overides */
                                        if (!p->chan) {
                                                char last_loginchan[80] = "";
                                                long logintime;
                                        if (!p->chan) {
                                                char last_loginchan[80] = "";
                                                long logintime;
@@ -1318,6 +1409,7 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                                                                        }
                                                                }
                                                        }
                                                                        }
                                                                }
                                                        }
+                                                       exten = tmpchan;
                                                        if (!res) {
                                                                if (context && !ast_strlen_zero(context) && !ast_strlen_zero(tmpchan))
                                                                        snprintf(p->loginchan, sizeof(p->loginchan), "%s@%s", tmpchan, context);
                                                        if (!res) {
                                                                if (context && !ast_strlen_zero(context) && !ast_strlen_zero(tmpchan))
                                                                        snprintf(p->loginchan, sizeof(p->loginchan), "%s@%s", tmpchan, context);
@@ -1325,8 +1417,10 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                                                                        strncpy(last_loginchan, p->loginchan, sizeof(last_loginchan) - 1);
                                                                        strncpy(p->loginchan, tmpchan, sizeof(p->loginchan) - 1);
                                                                }
                                                                        strncpy(last_loginchan, p->loginchan, sizeof(last_loginchan) - 1);
                                                                        strncpy(p->loginchan, tmpchan, sizeof(p->loginchan) - 1);
                                                                }
-                                                               if (ast_strlen_zero(p->loginchan))
+                                                               if (ast_strlen_zero(p->loginchan)) {
+                                                                       login_state = 2;
                                                                        filename = "agent-loggedoff";
                                                                        filename = "agent-loggedoff";
+                                                               }
                                                                p->acknowledged = 0;
                                                                /* store/clear the global variable that stores agentid based on the callerid */
                                                                if (chan->cid.cid_num) {
                                                                p->acknowledged = 0;
                                                                /* store/clear the global variable that stores agentid based on the callerid */
                                                                if (chan->cid.cid_num) {
@@ -1337,7 +1431,7 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                                                                        else
                                                                                pbx_builtin_setvar_helper(NULL, agentvar, p->agent);
                                                                }
                                                                        else
                                                                                pbx_builtin_setvar_helper(NULL, agentvar, p->agent);
                                                                }
-                                                               if(updatecdr && chan->cdr)
+                                                               if(update_cdr && chan->cdr)
                                                                        snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
 
                                                        }
                                                                        snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
 
                                                        }
@@ -1345,13 +1439,9 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                                                        p->loginchan[0] = '\0';
                                                        p->acknowledged = 0;
                                                }
                                                        p->loginchan[0] = '\0';
                                                        p->acknowledged = 0;
                                                }
-                                               play_announcement = 1;
-                                               if( options )
-                                                       if( strchr( options, 's' ) )
-                                                               play_announcement = 0;
                                                ast_mutex_unlock(&p->lock);
                                                ast_mutex_unlock(&agentlock);
                                                ast_mutex_unlock(&p->lock);
                                                ast_mutex_unlock(&agentlock);
-                                               if( !res && play_announcement )
+                                               if( !res && play_announcement==1 )
                                                        res = ast_streamfile(chan, filename, chan->language);
                                                if (!res)
                                                        ast_waitstream(chan, "");
                                                        res = ast_streamfile(chan, filename, chan->language);
                                                if (!res)
                                                        ast_waitstream(chan, "");
@@ -1399,11 +1489,6 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                                                        ast_mutex_unlock(&agentlock);
                                                        if (!res)
                                                                res = ast_safe_sleep(chan, 500);
                                                        ast_mutex_unlock(&agentlock);
                                                        if (!res)
                                                                res = ast_safe_sleep(chan, 500);
-                                                       res = ast_streamfile(chan, "vm-goodbye", chan->language);
-                                                       if (!res)
-                                                               res = ast_waitstream(chan, "");
-                                                       if (!res)
-                                                               res = ast_safe_sleep(chan, 1000);
                                                        ast_mutex_unlock(&p->lock);
                                                } else if (!res) {
 #ifdef HONOR_MUSIC_CLASS
                                                        ast_mutex_unlock(&p->lock);
                                                } else if (!res) {
 #ifdef HONOR_MUSIC_CLASS
@@ -1419,7 +1504,7 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                                                                "Channel: %s\r\n"
                                                                "Uniqueid: %s\r\n",
                                                                p->agent, chan->name, chan->uniqueid);
                                                                "Channel: %s\r\n"
                                                                "Uniqueid: %s\r\n",
                                                                p->agent, chan->name, chan->uniqueid);
-                                                       if (updatecdr && chan->cdr)
+                                                       if (update_cdr && chan->cdr)
                                                                snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
                                                        ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGIN", "%s", chan->name);
                                                        if (option_verbose > 2)
                                                                snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
                                                        ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGIN", "%s", chan->name);
                                                        if (option_verbose > 2)
@@ -1524,13 +1609,49 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
                if (!p)
                        ast_mutex_unlock(&agentlock);
 
                if (!p)
                        ast_mutex_unlock(&agentlock);
 
-               if (!res)
+               if (!res && (max_login_tries==0 || tries < max_login_tries))
                        res = ast_app_getdata(chan, errmsg, user, sizeof(user) - 1, 0);
        }
                
        LOCAL_USER_REMOVE(u);
                        res = ast_app_getdata(chan, errmsg, user, sizeof(user) - 1, 0);
        }
                
        LOCAL_USER_REMOVE(u);
-       /* Always hangup */
-       return -1;
+       if (!res)
+               res = ast_safe_sleep(chan, 500);
+
+       /* AgentLogin() exit */
+       if (!callbackmode) {
+               return -1;
+       }
+       /* AgentCallbackLogin() exit*/
+       else {
+               /* Set variables */
+               if (login_state > 0) {
+                       pbx_builtin_setvar_helper(chan, "AGENTNUMBER", user);
+                       if (login_state==1) {
+                               pbx_builtin_setvar_helper(chan, "AGENTSTATUS", "on");
+                               pbx_builtin_setvar_helper(chan, "AGENTEXTEN", exten);
+                       }
+                       else {
+                               pbx_builtin_setvar_helper(chan, "AGENTSTATUS", "off");
+                       }
+               }
+               else {
+                       pbx_builtin_setvar_helper(chan, "AGENTSTATUS", "fail");
+               }
+               if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1, chan->cid.cid_num))
+                       return 0;
+               /* Do we need to play agent-goodbye now that we will be hanging up? */
+               if (play_announcement==1) {
+                       if (!res)
+                               res = ast_safe_sleep(chan, 1000);
+                       res = ast_streamfile(chan, agent_goodbye, chan->language);
+                       if (!res)
+                               res = ast_waitstream(chan, "");
+                       if (!res)
+                               res = ast_safe_sleep(chan, 1000);
+               }
+       }
+       /* We should never get here if next priority exists when in callbackmode */
+       return -1;
 }
 
 static int login_exec(struct ast_channel *chan, void *data)
 }
 
 static int login_exec(struct ast_channel *chan, void *data)