📄 chan_agent.c
字号:
ast_channel_unlock(p->owner); } while (p->chan && ast_channel_trylock(p->chan)) { DEADLOCK_AVOIDANCE(&p->lock); } if (p->chan) { ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT); ast_channel_unlock(p->chan); } ast_mutex_unlock(&p->lock); } else p->deferlogoff = 1; } else { logintime = time(NULL) - p->loginstart; p->loginstart = 0; agent_logoff_maintenance(p, p->loginchan, logintime, NULL, "CommandLogoff"); } break; } } AST_LIST_UNLOCK(&agents); return ret;}static int agent_logoff_cmd(int fd, int argc, char **argv){ int ret; char *agent; if (argc < 3 || argc > 4) return RESULT_SHOWUSAGE; if (argc == 4 && strcasecmp(argv[3], "soft")) return RESULT_SHOWUSAGE; agent = argv[2] + 6; ret = agent_logoff(agent, argc == 4); if (ret == 0) ast_cli(fd, "Logging out %s\n", agent); return RESULT_SUCCESS;}/*! * Sets an agent as no longer logged in in the Manager API. * It is registered on load_module() and it gets called by the manager backend. * \param s * \param m * \returns * \sa action_agents(), action_agent_callback_login(), load_module(). */static int action_agent_logoff(struct mansession *s, const struct message *m){ const char *agent = astman_get_header(m, "Agent"); const char *soft_s = astman_get_header(m, "Soft"); /* "true" is don't hangup */ int soft; int ret; /* return value of agent_logoff */ if (ast_strlen_zero(agent)) { astman_send_error(s, m, "No agent specified"); return 0; } soft = ast_true(soft_s) ? 1 : 0; ret = agent_logoff(agent, soft); if (ret == 0) astman_send_ack(s, m, "Agent logged out"); else astman_send_error(s, m, "No such agent"); return 0;}static char *complete_agent_logoff_cmd(const char *line, const char *word, int pos, int state){ char *ret = NULL; if (pos == 2) { struct agent_pvt *p; char name[AST_MAX_AGENT]; int which = 0, len = strlen(word); AST_LIST_LOCK(&agents); AST_LIST_TRAVERSE(&agents, p, list) { snprintf(name, sizeof(name), "Agent/%s", p->agent); if (!strncasecmp(word, name, len) && ++which > state) { ret = ast_strdup(name); break; } } AST_LIST_UNLOCK(&agents); } else if (pos == 3 && state == 0) return ast_strdup("soft"); return ret;}/*! * Show agents in cli. */static int agents_show(int fd, int argc, char **argv){ struct agent_pvt *p; char username[AST_MAX_BUF]; char location[AST_MAX_BUF] = ""; char talkingto[AST_MAX_BUF] = ""; char moh[AST_MAX_BUF]; int count_agents = 0; /*!< Number of agents configured */ int online_agents = 0; /*!< Number of online agents */ int offline_agents = 0; /*!< Number of offline agents */ if (argc != 2) return RESULT_SHOWUSAGE; AST_LIST_LOCK(&agents); AST_LIST_TRAVERSE(&agents, p, list) { ast_mutex_lock(&p->lock); if (p->pending) { if (p->group) ast_cli(fd, "-- Pending call to group %d\n", powerof(p->group)); else ast_cli(fd, "-- Pending call to agent %s\n", p->agent); } else { if (!ast_strlen_zero(p->name)) snprintf(username, sizeof(username), "(%s) ", p->name); else username[0] = '\0'; if (p->chan) { snprintf(location, sizeof(location), "logged in on %s", p->chan->name); if (p->owner && ast_bridged_channel(p->owner)) snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(p->owner)->name); else strcpy(talkingto, " is idle"); online_agents++; } else if (!ast_strlen_zero(p->loginchan)) { if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0 || !(p->lastdisc.tv_sec)) snprintf(location, sizeof(location) - 20, "available at '%s'", p->loginchan); else snprintf(location, sizeof(location) - 20, "wrapping up at '%s'", p->loginchan); talkingto[0] = '\0'; online_agents++; if (p->acknowledged) strncat(location, " (Confirmed)", sizeof(location) - strlen(location) - 1); } else { strcpy(location, "not logged in"); talkingto[0] = '\0'; offline_agents++; } if (!ast_strlen_zero(p->moh)) snprintf(moh, sizeof(moh), " (musiconhold is '%s')", p->moh); ast_cli(fd, "%-12.12s %s%s%s%s\n", p->agent, username, location, talkingto, moh); count_agents++; } ast_mutex_unlock(&p->lock); } AST_LIST_UNLOCK(&agents); if ( !count_agents ) ast_cli(fd, "No Agents are configured in %s\n",config); else ast_cli(fd, "%d agents configured [%d online , %d offline]\n",count_agents, online_agents, offline_agents); ast_cli(fd, "\n"); return RESULT_SUCCESS;}static int agents_show_online(int fd, int argc, char **argv){ struct agent_pvt *p; char username[AST_MAX_BUF]; char location[AST_MAX_BUF] = ""; char talkingto[AST_MAX_BUF] = ""; char moh[AST_MAX_BUF]; int count_agents = 0; /* Number of agents configured */ int online_agents = 0; /* Number of online agents */ int agent_status = 0; /* 0 means offline, 1 means online */ if (argc != 3) return RESULT_SHOWUSAGE; AST_LIST_LOCK(&agents); AST_LIST_TRAVERSE(&agents, p, list) { agent_status = 0; /* reset it to offline */ ast_mutex_lock(&p->lock); if (!ast_strlen_zero(p->name)) snprintf(username, sizeof(username), "(%s) ", p->name); else username[0] = '\0'; if (p->chan) { snprintf(location, sizeof(location), "logged in on %s", p->chan->name); if (p->owner && ast_bridged_channel(p->owner)) snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(p->owner)->name); else strcpy(talkingto, " is idle"); agent_status = 1; online_agents++; } else if (!ast_strlen_zero(p->loginchan)) { snprintf(location, sizeof(location) - 20, "available at '%s'", p->loginchan); talkingto[0] = '\0'; agent_status = 1; online_agents++; if (p->acknowledged) strncat(location, " (Confirmed)", sizeof(location) - strlen(location) - 1); } if (!ast_strlen_zero(p->moh)) snprintf(moh, sizeof(moh), " (musiconhold is '%s')", p->moh); if (agent_status) ast_cli(fd, "%-12.12s %s%s%s%s\n", p->agent, username, location, talkingto, moh); count_agents++; ast_mutex_unlock(&p->lock); } AST_LIST_UNLOCK(&agents); if (!count_agents) ast_cli(fd, "No Agents are configured in %s\n", config); else ast_cli(fd, "%d agents online\n", online_agents); ast_cli(fd, "\n"); return RESULT_SUCCESS;}static char show_agents_usage[] = "Usage: agent show\n"" Provides summary information on agents.\n";static char show_agents_online_usage[] ="Usage: agent show online\n"" Provides a list of all online agents.\n";static char agent_logoff_usage[] ="Usage: agent logoff <channel> [soft]\n"" Sets an agent as no longer logged in.\n"" If 'soft' is specified, do not hangup existing calls.\n";static struct ast_cli_entry cli_show_agents_deprecated = { { "show", "agents", NULL }, agents_show, NULL, NULL, NULL };static struct ast_cli_entry cli_show_agents_online_deprecated = { { "show", "agents", "online" }, agents_show_online, NULL, NULL, NULL };static struct ast_cli_entry cli_agents[] = { { { "agent", "show", NULL }, agents_show, "Show status of agents", show_agents_usage, NULL, &cli_show_agents_deprecated }, { { "agent", "show", "online" }, agents_show_online, "Show all online agents", show_agents_online_usage, NULL, &cli_show_agents_online_deprecated }, { { "agent", "logoff", NULL }, agent_logoff_cmd, "Sets an agent offline", agent_logoff_usage, complete_agent_logoff_cmd },};/*! * \brief Log in agent application. * * \param chan * \param data * \param callbackmode non-zero for AgentCallbackLogin */static int __login_exec(struct ast_channel *chan, void *data, int callbackmode){ int res=0; int tries = 0; int max_login_tries = maxlogintries; struct agent_pvt *p; struct ast_module_user *u; int login_state = 0; char user[AST_MAX_AGENT] = ""; char pass[AST_MAX_AGENT]; char agent[AST_MAX_AGENT] = ""; char xpass[AST_MAX_AGENT] = ""; char *errmsg; char *parse; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(agent_id); AST_APP_ARG(options); AST_APP_ARG(extension); ); const char *tmpoptions = NULL; char *context = NULL; int play_announcement = 1; char agent_goodbye[AST_MAX_FILENAME_LEN]; int update_cdr = updatecdr; char *filename = "agent-loginok"; char tmpchan[AST_MAX_BUF] = ""; u = ast_module_user_add(chan); parse = ast_strdupa(data); AST_STANDARD_APP_ARGS(args, parse); ast_copy_string(agent_goodbye, agentgoodbye, sizeof(agent_goodbye)); ast_channel_lock(chan); /* 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"); if (option_verbose > 2) 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") && !ast_strlen_zero(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"); if (option_verbose > 2) 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") && !ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTGOODBYE"))) { strcpy(agent_goodbye, pbx_builtin_getvar_helper(chan, "AGENTGOODBYE")); tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTGOODBYE"); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTGOODBYE=%s, setting agent_goodbye to: %s on Channel '%s'.\n",tmpoptions,agent_goodbye,chan->name); } ast_channel_unlock(chan); /* End Channel Specific Login Overrides */ if (callbackmode && args.extension) { parse = args.extension; args.extension = strsep(&parse, "@"); context = parse; } if (!ast_strlen_zero(args.options)) { if (strchr(args.options, 's')) { play_announcement = 0; } } if (chan->_state != AST_STATE_UP) res = ast_answer(chan); if (!res) { if (!ast_strlen_zero(args.agent_id)) ast_copy_string(user, args.agent_id, AST_MAX_AGENT); else res = ast_app_getdata(chan, "agent-user", user, sizeof(user) - 1, 0); } while (!res && (max_login_tries==0 || tries < max_login_tries)) { tries++; /* Check for password */ AST_LIST_LOCK(&agents); AST_LIST_TRAVERSE(&agents, p, list) { if (!strcmp(p->agent, user) && !p->pending) ast_copy_string(xpass, p->password, sizeof(xpass)); } AST_LIST_UNLOCK(&agents); if (!res) { if (!ast_strlen_zero(xpass)) res = ast_app_getdata(chan, "agent-pass", pass, sizeof(pass) - 1, 0); else pass[0] = '\0'; } errmsg = "agent-incorrect";#if 0 ast_log(LOG_NOTICE, "user: %s, pass: %s\n", user, pass);#endif /* Check again for accuracy */ AST_LIST_LOCK(&agents); AST_LIST_TRAVERSE(&agents, p, list) { int unlock_channel = 1; ast_channel_lock(chan); ast_mutex_lock(&p->lock); if (!strcmp(p->agent, user) && !strcmp(p->password, pass) && !p->pending) { login_state = 1; /* Successful Login */ /* Ensure we can't be gotten until we're done */ gettimeofday(&p->lastdisc, NULL); p->lastdisc.tv_sec++; /* Set Channel Specific Agent Overrides */ 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"); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTACKCALL=%s, setting ackcall to: %d for Agent '%s'.\n",tmpoptions,p->ackcall,p->agent); } else { p->ackcall = ackcall; } 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"); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Saw variable AGENTAUTOLOGOFF=%s, setting autologff to: %d for Agent '%s'.\n",tmpoptions,p->autologoff,p->agent); } else { p->autologoff = autologoff; } 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_ge
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -