[asterisk-commits] eliel: branch eliel/data_api_providers_gsoc2010 r271330 - in /team/eliel/data...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jun 18 08:07:35 CDT 2010
Author: eliel
Date: Fri Jun 18 08:07:32 2010
New Revision: 271330
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=271330
Log:
Add the data provider for the agent channel driver.
Modified:
team/eliel/data_api_providers_gsoc2010/channels/chan_agent.c
team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h
team/eliel/data_api_providers_gsoc2010/main/data.c
Modified: team/eliel/data_api_providers_gsoc2010/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/team/eliel/data_api_providers_gsoc2010/channels/chan_agent.c?view=diff&rev=271330&r1=271329&r2=271330
==============================================================================
--- team/eliel/data_api_providers_gsoc2010/channels/chan_agent.c (original)
+++ team/eliel/data_api_providers_gsoc2010/channels/chan_agent.c Fri Jun 18 08:07:32 2010
@@ -67,6 +67,7 @@
#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 @@
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_INTEGER) \
+ 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 { \
@@ -2316,6 +2330,75 @@
.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.
@@ -2337,6 +2420,9 @@
/* Dialplan applications */
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);
@@ -2371,6 +2457,8 @@
/* 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 */
Modified: team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h
URL: http://svnview.digium.com/svn/asterisk/team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h?view=diff&rev=271330&r1=271329&r2=271330
==============================================================================
--- team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h (original)
+++ team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h Fri Jun 18 08:07:32 2010
@@ -191,6 +191,7 @@
AST_DATA_DOUBLE,
AST_DATA_BOOLEAN,
AST_DATA_STRING,
+ AST_DATA_CHARACTER,
AST_DATA_PASSWORD,
AST_DATA_IPADDR,
AST_DATA_POINTER
@@ -215,6 +216,7 @@
enum ast_data_type type;
union {
+ char AST_DATA_CHARACTER;
char *AST_DATA_STRING;
char *AST_DATA_PASSWORD;
int AST_DATA_INTEGER;
@@ -272,6 +274,7 @@
enum ast_data_type type;
/*! \brief member getter. */
union {
+ char (*AST_DATA_CHARACTER)(void *ptr);
char *(*AST_DATA_STRING)(void *ptr);
char *(*AST_DATA_PASSWORD)(void *ptr);
int (*AST_DATA_INTEGER)(void *ptr);
@@ -301,6 +304,8 @@
__AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_PASSWORD, char *)
#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_STRING(__structure, __member) \
__AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_STRING, char *)
+#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_CHARACTER(__structure, __member) \
+ __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_CHARACTER, char)
#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_INTEGER(__structure, __member) \
__AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_INTEGER, int)
#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_UNSIGNED_INTEGER(__structure, __member) \
@@ -466,6 +471,17 @@
int value);
/*!
+ * \brief Add a char node type.
+ * \param[in] root The root of the ast_data to insert into.
+ * \param[in] childname The name of the child element to be added.
+ * \param[in] value The value for the new node.
+ * \retval NULL on error (memory exhaustion only).
+ * \retval non-NULL a newly allocated node.
+ */
+struct ast_data *ast_data_add_char(struct ast_data *root, const char *childname,
+ char value);
+
+/*!
* \brief Add an unsigned integer node type.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
@@ -616,6 +632,21 @@
}
/*!
+ * \brief Retrieve the character value of a node.
+ * \param[in] tree The tree from where to get the value.
+ * \param[in] path The node name or path.
+ * \returns The value of the node.
+ */
+static inline char ast_data_retrieve_char(struct ast_data *tree, const char *path)
+{
+ struct ast_data_retrieve ret;
+
+ ast_data_retrieve(tree, path, &ret);
+
+ return ret.value.AST_DATA_CHARACTER;
+}
+
+/*!
* \brief Retrieve the boolean value of a node.
* \param[in] tree The tree from where to get the value.
* \param[in] path The node name or path.
Modified: team/eliel/data_api_providers_gsoc2010/main/data.c
URL: http://svnview.digium.com/svn/asterisk/team/eliel/data_api_providers_gsoc2010/main/data.c?view=diff&rev=271330&r1=271329&r2=271330
==============================================================================
--- team/eliel/data_api_providers_gsoc2010/main/data.c (original)
+++ team/eliel/data_api_providers_gsoc2010/main/data.c Fri Jun 18 08:07:32 2010
@@ -89,6 +89,7 @@
unsigned int boolean;
char *str;
char *password;
+ char character;
struct in_addr ipaddr;
void *ptr;
} payload;
@@ -1212,6 +1213,38 @@
/*!
* \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current character value.
+ * .search = "something=c"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "c".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The boolean value to compare.
+ * \returns The (value - current_value) result.
+ */
+static int data_search_cmp_char(const struct ast_data_search *root, const char *name,
+ char value)
+{
+ struct ast_data_search *child;
+ char node_value;
+ enum data_search_comparison cmp_type;
+
+ child = data_search_get_node(root, name);
+ if (!child) {
+ return 0;
+ }
+
+ node_value = *(child->value);
+ cmp_type = child->cmp_type;
+
+ ao2_ref(child, -1);
+
+ return data_search_comparison_result(value - node_value, cmp_type);
+}
+
+/*!
+ * \internal
* \brief Get the member pointer, from a mapping structure, based on its name.
* \XXX We will need to improve performance here!!.
* \retval <0 if the member was not found.
@@ -1272,6 +1305,11 @@
node->name,
mapping[member].get.AST_DATA_STRING(structure));
break;
+ case AST_DATA_CHARACTER:
+ notmatch = data_search_cmp_char(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_CHARACTER(structure));
+ break;
case AST_DATA_INTEGER:
notmatch = data_search_cmp_int(struct_children,
node->name,
@@ -1333,6 +1371,7 @@
ao2_ref(root->children, -1);
break;
case AST_DATA_POINTER:
+ case AST_DATA_CHARACTER:
case AST_DATA_CONTAINER:
case AST_DATA_INTEGER:
case AST_DATA_UNSIGNED_INTEGER:
@@ -1434,6 +1473,10 @@
case AST_DATA_STRING:
notmatch = data_search_cmp_string(s_child, d_child->name,
d_child->payload.str);
+ break;
+ case AST_DATA_CHARACTER:
+ notmatch = data_search_cmp_char(s_child, d_child->name,
+ d_child->payload.character);
break;
case AST_DATA_INTEGER:
notmatch = data_search_cmp_int(s_child, d_child->name,
@@ -2055,6 +2098,11 @@
case AST_DATA_STRING:
ast_xml_set_text(child_xml, node->payload.str);
break;
+ case AST_DATA_CHARACTER:
+ snprintf(node_content, sizeof(node_content), "%c",
+ node->payload.character);
+ ast_xml_set_text(child_xml, node_content);
+ break;
case AST_DATA_INTEGER:
snprintf(node_content, sizeof(node_content), "%d",
node->payload.sint);
@@ -2200,6 +2248,9 @@
case AST_DATA_STRING:
node->payload.str = (char *) ptr;
break;
+ case AST_DATA_CHARACTER:
+ node->payload.character = *(char *) ptr;
+ break;
case AST_DATA_POINTER:
node->payload.ptr = ptr;
break;
@@ -2237,6 +2288,11 @@
return __ast_data_add(root, name, AST_DATA_INTEGER, &value);
}
+struct ast_data *ast_data_add_char(struct ast_data *root, const char *name, char value)
+{
+ return __ast_data_add(root, name, AST_DATA_CHARACTER, &value);
+}
+
struct ast_data *ast_data_add_uint(struct ast_data *root, const char *name,
unsigned int value)
{
@@ -2340,6 +2396,10 @@
case AST_DATA_STRING:
ast_data_add_str(root, mapping[i].name,
mapping[i].get.AST_DATA_STRING(structure));
+ break;
+ case AST_DATA_CHARACTER:
+ ast_data_add_char(root, mapping[i].name,
+ mapping[i].get.AST_DATA_CHARACTER(structure));
break;
case AST_DATA_CONTAINER:
break;
@@ -2490,6 +2550,9 @@
case AST_DATA_PASSWORD:
content->value.AST_DATA_PASSWORD = node->payload.password;
break;
+ case AST_DATA_CHARACTER:
+ content->value.AST_DATA_CHARACTER = node->payload.character;
+ break;
case AST_DATA_INTEGER:
content->value.AST_DATA_INTEGER = node->payload.sint;
break;
@@ -2525,6 +2588,7 @@
} data_result_color[] = {
{ AST_DATA_STRING, COLOR_CYAN },
{ AST_DATA_PASSWORD, COLOR_BLUE },
+ { AST_DATA_CHARACTER, COLOR_GRAY },
{ AST_DATA_INTEGER, COLOR_RED },
{ AST_DATA_UNSIGNED_INTEGER, COLOR_RED },
{ AST_DATA_DOUBLE, COLOR_RED },
@@ -2598,6 +2662,12 @@
ast_str_buffer(tabs),
node->name,
node->payload.str);
+ break;
+ case AST_DATA_CHARACTER:
+ ast_str_append(&output, 0, "%s%s: \'%c\'\n",
+ ast_str_buffer(tabs),
+ node->name,
+ node->payload.character);
break;
case AST_DATA_CONTAINER:
ast_str_append(&output, 0, "%s%s\n", ast_str_buffer(tabs),
@@ -2874,6 +2944,9 @@
break;
case AST_DATA_STRING:
astman_append(s, ": %s\r\n", node->payload.str);
+ break;
+ case AST_DATA_CHARACTER:
+ astman_append(s, ": %c\r\n", node->payload.character);
break;
case AST_DATA_IPADDR:
astman_append(s, ": %s\r\n", ast_inet_ntoa(node->payload.ipaddr));
More information about the asterisk-commits
mailing list