⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chan_agent.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
						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 + -