[asterisk-commits] eliel: branch group/data_api_gsoc2009 r207090 - in /team/group/data_api_gsoc2...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jul 17 13:55:28 CDT 2009
Author: eliel
Date: Fri Jul 17 13:55:24 2009
New Revision: 207090
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=207090
Log:
Make a first implementation of the CLI command "queue show" using
the tree returned by the data api.
The callers list is missing, i first need to map the ast_channel structure.
Modified:
team/group/data_api_gsoc2009/apps/app_queue.c
team/group/data_api_gsoc2009/include/asterisk/data.h
team/group/data_api_gsoc2009/main/data.c
team/group/data_api_gsoc2009/tests/test_data.c
Modified: team/group/data_api_gsoc2009/apps/app_queue.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/apps/app_queue.c?view=diff&rev=207090&r1=207089&r2=207090
==============================================================================
--- team/group/data_api_gsoc2009/apps/app_queue.c (original)
+++ team/group/data_api_gsoc2009/apps/app_queue.c Fri Jul 17 13:55:24 2009
@@ -6315,101 +6315,114 @@
*/
static char *__queues_show(struct mansession *s, int fd, int argc, const char * const *argv)
{
- struct call_queue *q;
struct ast_str *out = ast_str_alloca(240);
- int found = 0;
- time_t now = time(NULL);
- struct ao2_iterator queue_iter;
- struct ao2_iterator mem_iter;
-
- if (argc != 2 && argc != 3)
+ //int found = 0;
+ //time_t now = time(NULL);
+ struct ast_data *queues, *queue, *member;
+ struct ast_data_iterator *iq, *im;
+ struct ast_data_query query = {
+ .path = "asterisk/application/app_queue/queues",
+ };
+ float sl;
+ int callscompleted, has_members = 0, penalty, calls;
+ const char *name, *membername, *interface;
+
+ if (argc != 2 && argc != 3) {
return CLI_SHOWUSAGE;
+ }
if (argc == 3) { /* specific queue */
- if ((q = load_realtime_queue(argv[2]))) {
- queue_unref(q);
- }
- } else if (ast_check_realtime("queues")) {
- /* This block is to find any queues which are defined in realtime but
- * which have not yet been added to the in-core container
- */
- struct ast_config *cfg = ast_load_realtime_multientry("queues", "name LIKE", "%", SENTINEL);
- char *queuename;
- if (cfg) {
- for (queuename = ast_category_browse(cfg, NULL); !ast_strlen_zero(queuename); queuename = ast_category_browse(cfg, queuename)) {
- if ((q = load_realtime_queue(queuename))) {
- queue_unref(q);
- }
- }
- ast_config_destroy(cfg);
- }
- }
-
- queue_iter = ao2_iterator_init(queues, F_AO2I_DONTLOCK);
- ao2_lock(queues);
- while ((q = ao2_iterator_next(&queue_iter))) {
- float sl;
- struct call_queue *realtime_queue = NULL;
-
- ao2_lock(q);
- /* This check is to make sure we don't print information for realtime
- * queues which have been deleted from realtime but which have not yet
- * been deleted from the in-core container
- */
- if (q->realtime && !(realtime_queue = load_realtime_queue(q->name))) {
- ao2_unlock(q);
- queue_unref(q);
+ }
+
+ queues = ast_data_get(&query);
+ if (!queues) {
+ return CLI_FAILURE;
+ }
+
+ iq = ast_data_iterator_init(queues, "queue");
+ if (!iq) {
+ ast_data_free(queues);
+ return CLI_FAILURE;
+ }
+
+ while ((queue = ast_data_iterator_next(iq))) {
+ name = ast_data_retrieve_string(queue, "name");
+ if (argc == 3 && strcasecmp(name, argv[2])) {
continue;
- } else if (q->realtime) {
- queue_unref(realtime_queue);
- }
- if (argc == 3 && strcasecmp(q->name, argv[2])) {
- ao2_unlock(q);
- queue_unref(q);
- continue;
- }
- found = 1;
-
- ast_str_set(&out, 0, "%-12.12s has %d calls (max ", q->name, q->count);
- if (q->maxlen)
- ast_str_append(&out, 0, "%d", q->maxlen);
- else
+ }
+
+ ast_str_set(&out, 0, "%-12.12s has %d calls (max ", name,
+ ast_data_retrieve_int(queue, "count"));
+
+ if (ast_data_retrieve_int(queue, "maxlen")) {
+ ast_str_append(&out, 0, "%d", ast_data_retrieve_int(queue, "maxlen"));
+ } else {
ast_str_append(&out, 0, "unlimited");
+ }
+
sl = 0;
- if (q->callscompleted > 0)
- sl = 100 * ((float) q->callscompletedinsl / (float) q->callscompleted);
- ast_str_append(&out, 0, ") in '%s' strategy (%ds holdtime, %ds talktime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds",
- int2strat(q->strategy), q->holdtime, q->talktime, q->weight,
- q->callscompleted, q->callsabandoned,sl,q->servicelevel);
+ callscompleted = ast_data_retrieve_int(queue, "callscompleted");
+ if (callscompleted) {
+ sl = 100 * ((float) ast_data_retrieve_int(queue, "callscompletedinsl")
+ / (float) callscompleted);
+ }
+ ast_str_append(&out, 0, ") in '%s' strategy (%ds holdtime, %ds talktime),"
+ " W:%d, C:%d, A:%d, SL:%2.1f%% within %ds",
+ int2strat(ast_data_retrieve_int(queue, "strategy")),
+ ast_data_retrieve_int(queue, "holdtime"),
+ ast_data_retrieve_int(queue, "talktime"),
+ ast_data_retrieve_int(queue, "weight"),
+ ast_data_retrieve_int(queue, "callscompleted"),
+ ast_data_retrieve_int(queue, "callsabandoned"),
+ sl,
+ ast_data_retrieve_int(queue, "servicelevel"));
+
do_print(s, fd, ast_str_buffer(out));
- if (!ao2_container_count(q->members))
+
+ has_members = 0;
+ im = ast_data_iterator_init(queue, "members/member");
+ while ((member = ast_data_iterator_next(im))) {
+ if (!has_members) {
+ do_print(s, fd, " Members: ");
+ }
+ has_members++;
+ membername = ast_data_retrieve_string(member, "membername");
+ ast_str_set(&out, 0, " %s", membername);
+ interface = ast_data_retrieve_string(member, "interface");
+
+ if (strcasecmp(membername, interface)) {
+ ast_str_append(&out, 0, " (%s)", interface);
+ }
+
+ penalty = ast_data_retrieve_int(member, "penalty");
+ if (penalty) {
+ ast_str_append(&out, 0, " with penalty %d", penalty);
+ }
+
+ ast_str_append(&out, 0, "%s%s%s (%s)",
+ ast_data_retrieve_int(member, "dynamic") ? " (dynamic)" : "",
+ ast_data_retrieve_int(member, "realtime") ? " (realtime)" : "",
+ ast_data_retrieve_int(member, "paused") ? " (paused)" : "",
+ ast_devstate2str(ast_data_retrieve_int(member, "status")));
+ calls = ast_data_retrieve_int(member, "calls");
+
+ if (calls) {
+ ast_str_append(&out, 0, " has taken %d calls (last was %ld secs ago)",
+ calls, (long) (time(NULL) -
+ ast_data_retrieve_int(member, "lastcall")));
+ } else {
+ ast_str_append(&out, 0, " has taken no calls yet");
+ }
+ do_print(s, fd, ast_str_buffer(out));
+ }
+ ast_data_iterator_end(im);
+ if (!has_members) {
do_print(s, fd, " No Members");
- else {
- struct member *mem;
-
- do_print(s, fd, " Members: ");
- mem_iter = ao2_iterator_init(q->members, 0);
- while ((mem = ao2_iterator_next(&mem_iter))) {
- ast_str_set(&out, 0, " %s", mem->membername);
- if (strcasecmp(mem->membername, mem->interface)) {
- ast_str_append(&out, 0, " (%s)", mem->interface);
- }
- if (mem->penalty)
- ast_str_append(&out, 0, " with penalty %d", mem->penalty);
- ast_str_append(&out, 0, "%s%s%s (%s)",
- mem->dynamic ? " (dynamic)" : "",
- mem->realtime ? " (realtime)" : "",
- mem->paused ? " (paused)" : "",
- ast_devstate2str(mem->status));
- if (mem->calls)
- ast_str_append(&out, 0, " has taken %d calls (last was %ld secs ago)",
- mem->calls, (long) (time(NULL) - mem->lastcall));
- else
- ast_str_append(&out, 0, " has taken no calls yet");
- do_print(s, fd, ast_str_buffer(out));
- ao2_ref(mem, -1);
- }
- }
+ }
+ }
+ ast_data_iterator_end(iq);
+
+#if 0
if (!q->head)
do_print(s, fd, " No Callers");
else {
@@ -6436,6 +6449,7 @@
ast_str_set(&out, 0, "No queues.");
do_print(s, fd, ast_str_buffer(out));
}
+#endif
return CLI_SUCCESS;
}
@@ -7471,6 +7485,31 @@
AST_DATA_STRUCTURE(member, DATA_EXPORT_MEMBER);
+#define DATA_EXPORT_QUEUE_ENT(MEMBER) \
+ MEMBER(queue_ent, moh, AST_DATA_STRING) \
+ MEMBER(queue_ent, announce, AST_DATA_STRING) \
+ MEMBER(queue_ent, context, AST_DATA_STRING) \
+ MEMBER(queue_ent, digits, AST_DATA_STRING) \
+ MEMBER(queue_ent, valid_digits, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, pos, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, prio, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, last_pos_said, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, last_periodic_announce_time, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, last_periodic_announce_sound, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, last_pos, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, opos, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, handled, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, pending, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, max_penalty, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, min_penalty, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, linpos, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, linwrapped, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, start, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, expire, AST_DATA_INTEGER) \
+ MEMBER(queue_ent, cancel_answered_elsewhere, AST_DATA_INTEGER)
+
+AST_DATA_STRUCTURE(queue_ent, DATA_EXPORT_QUEUE_ENT);
+
/*!
* \internal
* \brief Add a queue to the data_root node.
@@ -7484,7 +7523,9 @@
int member_added = 1;
struct ao2_iterator im;
struct member *member;
- struct ast_data *data_queue = NULL, *data_members = NULL, *data_member;
+ struct queue_ent *qe;
+ struct ast_data *data_queue = NULL, *data_members = NULL;
+ struct ast_data *data_member, *data_callers = NULL, *data_caller;
/* compare the search pattern. */
if (ast_data_search_cmp_structure(search, call_queue, queue, "queues/queue")) {
@@ -7492,6 +7533,7 @@
return;
}
+ /* add queue members */
if (queue->members) {
member_added = 0;
im = ao2_iterator_init(queue->members, 0);
@@ -7530,6 +7572,32 @@
ast_data_add_structure(member, data_member, member);
member_added = 1;
ao2_ref(member, -1);
+ }
+ }
+
+ /* include the callers inside the result. */
+ if (queue->head) {
+ for (qe = queue->head; qe; qe = qe->next) {
+ if (!data_queue) {
+ data_queue = ast_data_add_node(data_root, "queue");
+ if (!data_queue) {
+ continue;
+ }
+ }
+
+ if (!data_callers) {
+ data_callers = ast_data_add_node(data_queue, "callers");
+ if (!data_callers) {
+ continue;
+ }
+ }
+
+ data_caller = ast_data_add_node(data_queue, "caller");
+ if (!data_caller) {
+ continue;
+ }
+
+ ast_data_add_structure(queue_ent, data_caller, qe);
}
}
Modified: team/group/data_api_gsoc2009/include/asterisk/data.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/include/asterisk/data.h?view=diff&rev=207090&r1=207089&r2=207090
==============================================================================
--- team/group/data_api_gsoc2009/include/asterisk/data.h (original)
+++ team/group/data_api_gsoc2009/include/asterisk/data.h Fri Jul 17 13:55:24 2009
@@ -101,7 +101,25 @@
/*! \brief opaque definition of an ast_data_search structure. */
struct ast_data_search;
-typedef int (*ast_data_get_cb)(const struct ast_data_search *search, struct ast_data *root);
+/*! \brief structure retrieved from a node, with the nodes content. */
+struct ast_data_retrieve {
+ enum ast_data_type type;
+
+ union {
+ char *AST_DATA_STRING;
+ int AST_DATA_INTEGER;
+ double AST_DATA_DOUBLE;
+ unsigned int AST_DATA_UNSIGNED_INTEGER;
+ unsigned int AST_DATA_BOOLEAN;
+ void *AST_DATA_POINTER;
+ struct in_addr AST_DATA_IPADDR;
+ void *AST_DATA_CONTAINER;
+
+ } value;
+};
+
+typedef int (*ast_data_get_cb)(const struct ast_data_search *search,
+ struct ast_data *root);
typedef int *(*ast_data_put_cb)(void);
/*! \brief The structure of the node handler. */
@@ -539,45 +557,71 @@
struct ast_data *ast_data_iterator_next(struct ast_data_iterator *iterator);
/*!
- * \brief Retrieve an integer from a node in the tree.
+ * \brief Retrieve a value from a node in the tree.
* \param[in] tree The structure returned by a call to ast_data_get.
* \param[in] path The path to the node.
- * \param[out] value The node content.
+ * \param[out] content The node content.
* \retval 0 on success.
* \retval <0 on error.
*/
-int ast_data_retrieve_int(struct ast_data *tree, const char *path, const int *value);
-
-/*!
- * \brief Retrieve an ast_ string from a node in the tree.
- * \param[in] tree A pointer to the tree structure returned by a call to ast_data_get.
- * \param[in] path The path to the string node.
- * \param[out] value The node content.
- * \retval 0 on success.
- * \retval <0 on error.
- */
-int ast_data_retrieve_str(struct ast_data *tree, const char *path,
- const struct ast_str **value);
-
-/*!
- * \brief Retrieve an string from a node in the tree.
- * \param[in] tree A pointer to the tree structure returned by a call to ast_data_get.
- * \param[in] path The path to the string node.
- * \param[out] value The node content.
- * \retval 0 on success.
- * \retval <0 on error.
- */
-int ast_data_retrieve_char(struct ast_data *tree, const char *path, const char **value);
-
-/*!
- * \brief Retrieve the boolean value of a node.
- * \param[in] tree The pointer to the tree structure returned by a call to ast_data_get.
- * \param[in] path The path to the boolean node.
- * \param[out] value The node content.
- * \retval 0 on success.
- * \retval <0 on error.
- */
-int ast_data_retrieve_bool(struct ast_data *tree, const char *path, const char *value);
+int ast_data_retrieve(struct ast_data *tree, const char *path, struct ast_data_retrieve *content);
+
+/*!
+ * \brief
+ */
+static inline int ast_data_retrieve_int(struct ast_data *tree, const char *path)
+{
+ struct ast_data_retrieve ret;
+
+ ast_data_retrieve(tree, path, &ret);
+
+ return ret.value.AST_DATA_INTEGER;
+}
+
+static inline unsigned int ast_data_retrieve_bool(struct ast_data *tree, const char *path)
+{
+ struct ast_data_retrieve ret;
+
+ ast_data_retrieve(tree, path, &ret);
+
+ return ret.value.AST_DATA_BOOLEAN;
+}
+
+static inline unsigned int ast_data_retrieve_uint(struct ast_data *tree, const char *path)
+{
+ struct ast_data_retrieve ret;
+
+ ast_data_retrieve(tree, path, &ret);
+
+ return ret.value.AST_DATA_UNSIGNED_INTEGER;
+}
+
+static inline const char *ast_data_retrieve_string(struct ast_data *tree, const char *path)
+{
+ struct ast_data_retrieve ret;
+
+ ast_data_retrieve(tree, path, &ret);
+
+ return ret.value.AST_DATA_STRING;
+}
+
+static inline void *ast_data_retrieve_ptr(struct ast_data *tree, const char *path)
+{
+ struct ast_data_retrieve ret;
+
+ ast_data_retrieve(tree, path, &ret);
+
+ return ret.value.AST_DATA_POINTER;
+}
+
+static inline struct in_addr ast_data_retrieve_ipaddr(struct ast_data *tree, const char *path)
+{
+ struct ast_data_retrieve ret;
+
+ ast_data_retrieve(tree, path, &ret);
+
+ return ret.value.AST_DATA_IPADDR;
+}
#if defined(__cplusplus) || defined(c_plusplus)
}
Modified: team/group/data_api_gsoc2009/main/data.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/main/data.c?view=diff&rev=207090&r1=207089&r2=207090
==============================================================================
--- team/group/data_api_gsoc2009/main/data.c (original)
+++ team/group/data_api_gsoc2009/main/data.c Fri Jul 17 13:55:24 2009
@@ -1976,15 +1976,30 @@
{
struct ast_data_iterator *iterator;
struct ao2_iterator i;
+ struct ast_data *internal;
+ char *path, *ptr;
+
+ path = ast_strdupa(elements);
+
+ ptr = strrchr(path, '/');
+ if (ptr) {
+ *ptr = '\0';
+ internal = data_result_get_node(tree, path);
+ if (!internal) {
+ return NULL;
+ }
+ } else {
+ internal = tree;
+ }
iterator = ast_malloc(sizeof(*iterator));
if (!iterator) {
return NULL;
}
- i = ao2_iterator_init(tree->children, 0);
-
- iterator->pattern = elements;
+ i = ao2_iterator_init(internal->children, 0);
+
+ iterator->pattern = (ptr ? strrchr(elements, '/') + 1 : elements);
iterator->last = NULL;
iterator->internal_iterator = i;
@@ -2029,6 +2044,50 @@
return res;
}
+int ast_data_retrieve(struct ast_data *tree, const char *path, struct ast_data_retrieve *content)
+{
+ struct ast_data *node;
+
+ if (!content) {
+ return -1;
+ }
+
+ node = data_result_get_node(tree, path);
+ if (!node) {
+ ast_log(LOG_ERROR, "Invalid internal node %s\n", path);
+ return -1;
+ }
+
+ content->type = node->type;
+ switch (node->type) {
+ case AST_DATA_STRING:
+ content->value.AST_DATA_STRING = node->payload.str;
+ break;
+ case AST_DATA_INTEGER:
+ content->value.AST_DATA_INTEGER = node->payload.sint;
+ break;
+ case AST_DATA_UNSIGNED_INTEGER:
+ content->value.AST_DATA_UNSIGNED_INTEGER = node->payload.uint;
+ break;
+ case AST_DATA_BOOLEAN:
+ content->value.AST_DATA_BOOLEAN = node->payload.boolean;
+ break;
+ case AST_DATA_IPADDR:
+ content->value.AST_DATA_IPADDR = node->payload.ipaddr;
+ break;
+ case AST_DATA_DOUBLE:
+ content->value.AST_DATA_DOUBLE = node->payload.dbl;
+ break;
+ case AST_DATA_CONTAINER:
+ break;
+ case AST_DATA_POINTER:
+ content->value.AST_DATA_POINTER = node->payload.ptr;
+ break;
+ }
+
+ return 0;
+}
+
int ast_data_init(void)
{
ast_rwlock_init(&root_data_lock);
Modified: team/group/data_api_gsoc2009/tests/test_data.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/tests/test_data.c?view=diff&rev=207090&r1=207089&r2=207090
==============================================================================
--- team/group/data_api_gsoc2009/tests/test_data.c (original)
+++ team/group/data_api_gsoc2009/tests/test_data.c Fri Jul 17 13:55:24 2009
@@ -209,8 +209,7 @@
FILE *outfile;
struct ast_data_query query = {
.version = AST_DATA_QUERY_VERSION,
- .path = "asterisk/application/app_queue",
- .search = "app_queue/queues/queue/members/member/interface=Agent/1000",
+ .path = "asterisk/application/app_queue/queues",
};
switch (cmd) {
More information about the asterisk-commits
mailing list