Implement AstData API data providers as part of the GSOC 2010 project,

midterm evaluation.

Review: https://reviewboard.asterisk.org/r/757/



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@274727 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Eliel C. Sardanons
2010-07-08 14:48:42 +00:00
parent 21f8c77934
commit a1b89a6a50
17 changed files with 2244 additions and 329 deletions

View File

@@ -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
<application name="AgentLogin" language="en_US">
@@ -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 */