Index: asterisk/channels/chan_agent.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_agent.c,v retrieving revision 1.72 diff -u -r1.72 chan_agent.c --- asterisk/channels/chan_agent.c 9 May 2004 07:51:44 -0000 1.72 +++ asterisk/channels/chan_agent.c 23 May 2004 11:09:00 -0000 @@ -64,13 +64,15 @@ "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 agent logged in/off\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" -"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" @@ -90,6 +92,11 @@ static int wrapuptime; static int ackcall; +static int maxlogintries = 3; +static int playannouncement = 1; /* play logged in/off */ +static int playgoodbye = 1; /* play goodbye on hangup */ +static int hangupcall = 1; /* always hangup*/ + static int usecnt =0; static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER; @@ -771,44 +778,79 @@ v = ast_variable_browse(cfg, "agents"); while(v) { /* Create the interface list */ - if (!strcasecmp(v->name, "agent")) { + if (!strcasecmp(v->name, "agent") && strlen(v->value)) { add_agent(v->value, 0); - } else if (!strcasecmp(v->name, "group")) { + } else if (!strcasecmp(v->name, "group") && strlen(v->value)) { group = ast_get_group(v->value); - } else if (!strcasecmp(v->name, "autologoff")) { + } else if (!strcasecmp(v->name, "autologoff") && strlen(v->value)) { autologoff = atoi(v->value); if (autologoff < 0) autologoff = 0; - } else if (!strcasecmp(v->name, "ackcall")) { + } else if (!strcasecmp(v->name, "ackcall") && strlen(v->value)) { if (!strcasecmp(v->value, "always")) ackcall = 2; else if (ast_true(v->value)) - ackcall = 1; + ackcall = 1; else ackcall = 0; - } else if (!strcasecmp(v->name, "wrapuptime")) { + } else if (!strcasecmp(v->name, "wrapuptime") && strlen(v->value)) { wrapuptime = atoi(v->value); if (wrapuptime < 0) wrapuptime = 0; - } else if (!strcasecmp(v->name, "musiconhold")) { + } else if (!strcasecmp(v->name, "maxlogintries") && strlen(v->value)) { + maxlogintries = atoi(v->value); + if (maxlogintries < 0) + maxlogintries = 0; + } else if (!strcasecmp(v->name, "playannouncement") && strlen(v->value)) { + if (ast_true(v->value)) + playannouncement = 1; + else + playannouncement = 0; + } else if (!strcasecmp(v->name, "playgoodbye") && strlen(v->value)) { + if (ast_true(v->value)) + playgoodbye = 1; + else + playgoodbye = 0; + } else if (!strcasecmp(v->name, "hangupcall") && strlen(v->value)) { + if (!strcasecmp(v->value, "loginok")) + hangupcall = 3; + else if (!strcasecmp(v->value, "ok")) + hangupcall = 3; + else if (!strcasecmp(v->value, "loginfail")) + hangupcall = 2; + else if (!strcasecmp(v->value, "fail")) + hangupcall = 2; + else if (!strcasecmp(v->value, "always")) + hangupcall = 1; + else if (!strcasecmp(v->value, "never")) + hangupcall = 0; + else + if (ast_true(v->value)) + hangupcall = 1; + else + hangupcall = 0; + } else if (!strcasecmp(v->name, "musiconhold") && strlen(v->value)) { strncpy(moh, v->value, sizeof(moh) - 1); - } else if (!strcasecmp(v->name, "updatecdr")) { - updatecdr = ast_true(v->value); - } else if (!strcasecmp(v->name, "recordagentcalls")) { + } else if (!strcasecmp(v->name, "updatecdr") && strlen(v->value)) { + if (ast_true(v->value)) + updatecdr = 1; + else + updatecdr = 0; + } else if (!strcasecmp(v->name, "recordagentcalls") && strlen(v->value)) { recordagentcalls = ast_true(v->value); - } else if (!strcasecmp(v->name, "createlink")) { + } else if (!strcasecmp(v->name, "createlink") && strlen(v->value)) { createlink = ast_true(v->value); - } else if (!strcasecmp(v->name, "recordformat")) { + } else if (!strcasecmp(v->name, "recordformat") && strlen(v->value)) { strncpy(recordformat, v->value, sizeof(recordformat) - 1); if (!strcasecmp(v->value, "wav49")) strcpy(recordformatext, "WAV"); else strncpy(recordformatext, v->value, sizeof(recordformat) - 1); - } else if (!strcasecmp(v->name, "urlprefix")) { + } else if (!strcasecmp(v->name, "urlprefix") && strlen(v->value)) { strncpy(urlprefix, v->value, sizeof(urlprefix) - 2); if (urlprefix[strlen(urlprefix) - 1] != '/') strcat(urlprefix, "/"); - } else if (!strcasecmp(v->name, "savecallsin")) { + } else if (!strcasecmp(v->name, "savecallsin") && strlen(v->value)) { if (v->value[0] == '/') strncpy(savecallsin, v->value, sizeof(savecallsin) - 2); else @@ -1117,10 +1159,12 @@ { int res=0; int tries = 0; + int max_login_tries = maxlogintries; struct agent_pvt *p; struct localuser *u; struct timeval tv; time_t start; + int login_state = 0; char user[AST_MAX_AGENT]; char pass[AST_MAX_AGENT]; char agent[AST_MAX_AGENT] = ""; @@ -1129,9 +1173,15 @@ char info[512]; char *opt_user = NULL; char *options = NULL; + char option; + char badoption[2]; + char *tmpoptions = NULL; char *context = NULL; char *exten = NULL; - int play_announcement; + int play_announcement = playannouncement; + int play_goodbye = playgoodbye; + int hangup_call = hangupcall; + int update_cdr = updatecdr; char *filename = "agent-loginok"; LOCAL_USER_ADD(u); @@ -1139,6 +1189,61 @@ /* Parse the arguments XXX Check for failure XXX */ strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1); opt_user = info; + /* 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, "AGENTPLAYANNOUNCEMENT") && strlen(pbx_builtin_getvar_helper(chan, "AGENTPLAYANNOUNCEMENT"))) { + if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTPLAYANNOUNCEMENT"))) + play_announcement = 1; + else + play_announcement = 0; + tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTPLAYANNOUNCEMENT"); + ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTPLAYANNOUNCEMENT=%s, setting play_announcement to: %d on Channel '%s'.\n",tmpoptions,play_announcement,chan->name); + } + if (pbx_builtin_getvar_helper(chan, "AGENTPLAYGOODBYE") && strlen(pbx_builtin_getvar_helper(chan, "AGENTPLAYGOODBYE"))) { + if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTPLAYGOODBYE"))) + play_goodbye = 1; + else + play_goodbye = 0; + tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTPLAYGOODBYE"); + ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTPLAYGOODBYE=%s, setting play_goodbye to: %d on Channel '%s'.\n",tmpoptions,play_goodbye,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, "AGENTHANGUPCALL") && strlen(pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"))) { + if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"), "loginok")) + hangup_call = 3; + else if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"), "ok")) + hangup_call = 3; + else if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"), "loginfail")) + hangup_call = 2; + else if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"), "fail")) + hangup_call = 2; + else if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"), "always")) + hangup_call = 1; + else if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"), "never")) + hangup_call = 0; + else + if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"))) + hangup_call = 1; + else + hangup_call = 0; + tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTHANGUPCALL"); + ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTHANGUPCALL=%s, setting hangup_call to: %d on Channel '%s'.\n",tmpoptions,hangup_call,chan->name); + } + /* End Channel Specific Login Overrides */ + /* Read command line options */ if( opt_user ) { options = strchr(opt_user, '|'); if (options) { @@ -1156,7 +1261,22 @@ exten = NULL; } } + if( options ) { + while(*options) { + option = (char)options[0]; + if (option=='s') + play_announcement = 1; + 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); @@ -1166,7 +1286,8 @@ 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; @@ -1195,6 +1316,33 @@ 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) { if (callbackmode) { char tmpchan[AST_MAX_BUF] = ""; @@ -1227,13 +1375,16 @@ } } } + exten = tmpchan; if (!res) { if (context && !ast_strlen_zero(context) && !ast_strlen_zero(tmpchan)) snprintf(p->loginchan, sizeof(p->loginchan), "%s@%s", tmpchan, context); else 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"; + } p->acknowledged = 0; /* store/clear the global variable that stores agentid based on the callerid */ if (chan->callerid) { @@ -1244,7 +1395,7 @@ 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); } @@ -1252,10 +1403,7 @@ strcpy(p->loginchan, ""); p->acknowledged = 0; } - play_announcement = 1; - if( options ) - if( strchr( options, 's' ) ) - play_announcement = 0; + ast_mutex_unlock(&p->lock); ast_mutex_unlock(&agentlock); if( !res && play_announcement ) @@ -1278,15 +1426,9 @@ if (p->chan) res = -1; if (callbackmode && !res) { - /* Just say goodbye and be done with it */ 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 @@ -1301,7 +1443,7 @@ p->agent, chan->name); time(&start); snprintf(agent, sizeof(agent), "Agent/%s", p->agent); - 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) @@ -1399,13 +1541,52 @@ 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); - /* Always hangup */ - return -1; + if (!res) + res = ast_safe_sleep(chan, 500); + + /* Do we need to hanup the call */ + if (!callbackmode || hangup_call==1 || (hangup_call==2 && login_state==0) || (hangup_call==3 && login_state==1)) { + /* Do we need to play vm-goodbye? */ + if (!callbackmode && play_announcement && play_goodbye) { + if (!res) + res = ast_safe_sleep(chan, 1000); + res = ast_streamfile(chan, "vm-goodbye", chan->language); + if (!res) + res = ast_waitstream(chan, ""); + if (!res) + res = ast_safe_sleep(chan, 1000); + } + return -1; + } + /* Not hanging up call */ + else { + /* Set variables */ + pbx_builtin_setvar_helper(chan, "AGENTNUMBER", user); + if (login_state==0) { + pbx_builtin_setvar_helper(chan, "AGENTLOGINSTATE", "off"); + } + else if (login_state==1) { + pbx_builtin_setvar_helper(chan, "AGENTLOGINSTATE", "on"); + pbx_builtin_setvar_helper(chan, "AGENTEXTEN", exten); + } + else { + pbx_builtin_setvar_helper(chan, "AGENTLOGINSTATE", "fail"); + } + /* Do we need to jump priority by 100 because login failed? */ + if (login_state==0) { + chan->priority+=100; + ast_verbose(VERBOSE_PREFIX_3 "Increasing priority to %d because caller failed to login.\n",chan->priority); + } + return 0; + } + /* We should never get here! */ + return 0; } static int login_exec(struct ast_channel *chan, void *data)