[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