From 7a61a43adbc1ef91229e7757f6ac88619adff202 Mon Sep 17 00:00:00 2001 From: eliel Date: Thu, 8 Jul 2010 14:48:42 +0000 Subject: Implement AstData API data providers as part of the GSOC 2010 project, midterm evaluation. Review: https://reviewboard.asterisk.org/r/757/ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@274727 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_agent.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'channels/chan_agent.c') diff --git a/channels/chan_agent.c b/channels/chan_agent.c index fd05bed19..dfbf2284d 100644 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -67,6 +67,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/monitor.h" #include "asterisk/stringfields.h" #include "asterisk/event.h" +#include "asterisk/data.h" /*** DOCUMENTATION @@ -278,6 +279,19 @@ struct agent_pvt { AST_LIST_ENTRY(agent_pvt) list; /**< Next Agent in the linked list. */ }; +#define DATA_EXPORT_AGENT(MEMBER) \ + MEMBER(agent_pvt, autologoff, AST_DATA_INTEGER) \ + MEMBER(agent_pvt, ackcall, AST_DATA_BOOLEAN) \ + MEMBER(agent_pvt, deferlogoff, AST_DATA_BOOLEAN) \ + MEMBER(agent_pvt, wrapuptime, AST_DATA_MILLISECONDS) \ + MEMBER(agent_pvt, acknowledged, AST_DATA_BOOLEAN) \ + MEMBER(agent_pvt, name, AST_DATA_STRING) \ + MEMBER(agent_pvt, password, AST_DATA_PASSWORD) \ + MEMBER(agent_pvt, acceptdtmf, AST_DATA_CHARACTER) \ + MEMBER(agent_pvt, logincallerid, AST_DATA_STRING) + +AST_DATA_STRUCTURE(agent_pvt, DATA_EXPORT_AGENT); + static AST_LIST_HEAD_STATIC(agents, agent_pvt); /*!< Holds the list of agents (loaded form agents.conf). */ #define CHECK_FORMATS(ast, p) do { \ @@ -2321,6 +2335,75 @@ static struct ast_custom_function agent_function = { .read = function_agent, }; +/*! + * \internal + * \brief Callback used to generate the agents tree. + * \param[in] search The search pattern tree. + * \retval NULL on error. + * \retval non-NULL The generated tree. + */ +static int agents_data_provider_get(const struct ast_data_search *search, + struct ast_data *data_root) +{ + struct agent_pvt *p; + struct ast_data *data_agent, *data_channel, *data_talkingto; + + AST_LIST_LOCK(&agents); + AST_LIST_TRAVERSE(&agents, p, list) { + data_agent = ast_data_add_node(data_root, "agent"); + if (!data_agent) { + continue; + } + + ast_mutex_lock(&p->lock); + if (!(p->pending)) { + ast_data_add_str(data_agent, "id", p->agent); + ast_data_add_structure(agent_pvt, data_agent, p); + + ast_data_add_bool(data_agent, "logged", p->chan ? 1 : 0); + if (p->chan) { + data_channel = ast_data_add_node(data_agent, "loggedon"); + if (!data_channel) { + ast_mutex_unlock(&p->lock); + ast_data_remove_node(data_root, data_agent); + continue; + } + ast_channel_data_add_structure(data_channel, p->chan, 0); + if (p->owner && ast_bridged_channel(p->owner)) { + data_talkingto = ast_data_add_node(data_agent, "talkingto"); + if (!data_talkingto) { + ast_mutex_unlock(&p->lock); + ast_data_remove_node(data_root, data_agent); + continue; + } + ast_channel_data_add_structure(data_talkingto, ast_bridged_channel(p->owner), 0); + } + } else { + ast_data_add_node(data_agent, "talkingto"); + ast_data_add_node(data_agent, "loggedon"); + } + ast_data_add_str(data_agent, "musiconhold", p->moh); + } + ast_mutex_unlock(&p->lock); + + /* if this agent doesn't match remove the added agent. */ + if (!ast_data_search_match(search, data_agent)) { + ast_data_remove_node(data_root, data_agent); + } + } + AST_LIST_UNLOCK(&agents); + + return 0; +} + +static const struct ast_data_handler agents_data_provider = { + .version = AST_DATA_HANDLER_VERSION, + .get = agents_data_provider_get +}; + +static const struct ast_data_entry agents_data_providers[] = { + AST_DATA_ENTRY("asterisk/channel/agent/list", &agents_data_provider), +}; /*! * \brief Initialize the Agents module. @@ -2343,6 +2426,9 @@ static int load_module(void) ast_register_application_xml(app, login_exec); ast_register_application_xml(app3, agentmonitoroutgoing_exec); + /* data tree */ + ast_data_register_multiple(agents_data_providers, ARRAY_LEN(agents_data_providers)); + /* Manager commands */ ast_manager_register_xml("Agents", EVENT_FLAG_AGENT, action_agents); ast_manager_register_xml("AgentLogoff", EVENT_FLAG_AGENT, action_agent_logoff); @@ -2376,6 +2462,8 @@ static int unload_module(void) /* Unregister manager command */ ast_manager_unregister("Agents"); ast_manager_unregister("AgentLogoff"); + /* Unregister the data tree */ + ast_data_unregister(NULL); /* Unregister channel */ AST_LIST_LOCK(&agents); /* Hangup all interfaces if they have an owner */ -- cgit v1.2.3