aboutsummaryrefslogtreecommitdiffstats
path: root/main/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/data.c')
-rw-r--r--main/data.c494
1 files changed, 455 insertions, 39 deletions
diff --git a/main/data.c b/main/data.c
index c402c4fa6..2a4559c04 100644
--- a/main/data.c
+++ b/main/data.c
@@ -40,6 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/test.h"
+#include "asterisk/frame.h"
/*** DOCUMENTATION
<manager name="DataGet" language="en_US">
@@ -85,8 +86,9 @@ struct ast_data {
int32_t sint;
uint32_t uint;
double dbl;
- unsigned int boolean:1;
+ unsigned int boolean;
char *str;
+ char character;
struct in_addr ipaddr;
void *ptr;
} payload;
@@ -981,7 +983,19 @@ static struct ast_data_search *data_search_get_node(const struct ast_data_search
return current;
}
-int ast_data_search_cmp_string(const struct ast_data_search *root, const char *name,
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current string value.
+ * .search = "somename=somestring"
+ * name = "somename"
+ * value is the current value of something and will be evaluated against "somestring".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The value to compare.
+ * \returns The strcmp return value.
+ */
+static int data_search_cmp_string(const struct ast_data_search *root, const char *name,
char *value)
{
struct ast_data_search *child;
@@ -1001,7 +1015,19 @@ int ast_data_search_cmp_string(const struct ast_data_search *root, const char *n
return data_search_comparison_result(ret, cmp_type);
}
-int ast_data_search_cmp_ptr(const struct ast_data_search *root, const char *name,
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current pointer address value.
+ * .search = "something=0x32323232"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "0x32323232".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] ptr The pointer address to compare.
+ * \returns The (value - current_value) result.
+ */
+static int data_search_cmp_ptr(const struct ast_data_search *root, const char *name,
void *ptr)
{
struct ast_data_search *child;
@@ -1024,7 +1050,19 @@ int ast_data_search_cmp_ptr(const struct ast_data_search *root, const char *name
return data_search_comparison_result((node_ptr - ptr), cmp_type);
}
-int ast_data_search_cmp_ipaddr(const struct ast_data_search *root, const char *name,
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current ipv4 address value.
+ * .search = "something=192.168.2.2"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "192.168.2.2".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] addr The ipv4 address value to compare.
+ * \returns The (value - current_value) result.
+ */
+static int data_search_cmp_ipaddr(const struct ast_data_search *root, const char *name,
struct in_addr addr)
{
struct ast_data_search *child;
@@ -1044,7 +1082,19 @@ int ast_data_search_cmp_ipaddr(const struct ast_data_search *root, const char *n
return data_search_comparison_result((node_addr.s_addr - addr.s_addr), cmp_type);
}
-int ast_data_search_cmp_bool(const struct ast_data_search *root, const char *name,
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current boolean value.
+ * .search = "something=true"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "true".
+ * \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_bool(const struct ast_data_search *root, const char *name,
unsigned int value)
{
struct ast_data_search *child;
@@ -1064,7 +1114,19 @@ int ast_data_search_cmp_bool(const struct ast_data_search *root, const char *nam
return data_search_comparison_result(value - node_value, cmp_type);
}
-int ast_data_search_cmp_dbl(const struct ast_data_search *root, const char *name,
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current double value.
+ * .search = "something=222"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "222".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The double value to compare.
+ * \returns The (value - current_value) result.
+ */
+static int data_search_cmp_dbl(const struct ast_data_search *root, const char *name,
double value)
{
struct ast_data_search *child;
@@ -1084,7 +1146,19 @@ int ast_data_search_cmp_dbl(const struct ast_data_search *root, const char *name
return data_search_comparison_result(value - node_value, cmp_type);
}
-int ast_data_search_cmp_uint(const struct ast_data_search *root, const char *name,
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current unsigned integer value.
+ * .search = "something=10"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "10".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The unsigned value to compare.
+ * \returns The strcmp return value.
+ */
+static int data_search_cmp_uint(const struct ast_data_search *root, const char *name,
unsigned int value)
{
struct ast_data_search *child;
@@ -1104,7 +1178,19 @@ int ast_data_search_cmp_uint(const struct ast_data_search *root, const char *nam
return data_search_comparison_result(value - node_value, cmp_type);
}
-int ast_data_search_cmp_int(const struct ast_data_search *root, const char *name,
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current signed integer value.
+ * .search = "something=10"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "10".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The value to compare.
+ * \returns The strcmp return value.
+ */
+static int data_search_cmp_int(const struct ast_data_search *root, const char *name,
int value)
{
struct ast_data_search *child;
@@ -1126,6 +1212,38 @@ int ast_data_search_cmp_int(const struct ast_data_search *root, const char *name
/*!
* \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.
@@ -1146,21 +1264,6 @@ static inline int data_search_mapping_find(const struct ast_data_mapping_structu
return -1;
}
-int ast_data_search_has_condition(const struct ast_data_search *search,
- const char *compare_condition)
-{
- struct ast_data_search *child;
-
- child = data_search_get_node(search, compare_condition);
- if (!child) {
- return 0;
- }
-
- ao2_ref(child, -1);
-
- return 1;
-}
-
int __ast_data_search_cmp_structure(const struct ast_data_search *search,
const struct ast_data_mapping_structure *mapping, size_t mapping_len,
void *structure, const char *structure_name)
@@ -1191,38 +1294,63 @@ int __ast_data_search_cmp_structure(const struct ast_data_search *search,
notmatch = 0;
switch (mapping[member].type) {
+ case AST_DATA_PASSWORD:
+ notmatch = data_search_cmp_string(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_PASSWORD(structure));
+ break;
+ case AST_DATA_TIMESTAMP:
+ notmatch = data_search_cmp_uint(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_TIMESTAMP(structure));
+ break;
+ case AST_DATA_SECONDS:
+ notmatch = data_search_cmp_uint(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_SECONDS(structure));
+ break;
+ case AST_DATA_MILLISECONDS:
+ notmatch = data_search_cmp_uint(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_MILLISECONDS(structure));
+ break;
case AST_DATA_STRING:
- notmatch = ast_data_search_cmp_string(struct_children,
+ notmatch = data_search_cmp_string(struct_children,
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 = ast_data_search_cmp_int(struct_children,
+ notmatch = data_search_cmp_int(struct_children,
node->name,
mapping[member].get.AST_DATA_INTEGER(structure));
break;
case AST_DATA_BOOLEAN:
- notmatch = ast_data_search_cmp_bool(struct_children,
+ notmatch = data_search_cmp_bool(struct_children,
node->name,
mapping[member].get.AST_DATA_BOOLEAN(structure));
break;
case AST_DATA_UNSIGNED_INTEGER:
- notmatch = ast_data_search_cmp_uint(struct_children,
+ notmatch = data_search_cmp_uint(struct_children,
node->name,
mapping[member].get.AST_DATA_UNSIGNED_INTEGER(structure));
break;
case AST_DATA_DOUBLE:
- notmatch = ast_data_search_cmp_dbl(struct_children,
+ notmatch = data_search_cmp_dbl(struct_children,
node->name,
mapping[member].get.AST_DATA_DOUBLE(structure));
break;
case AST_DATA_IPADDR:
- notmatch = ast_data_search_cmp_ipaddr(struct_children,
+ notmatch = data_search_cmp_ipaddr(struct_children,
node->name,
mapping[member].get.AST_DATA_IPADDR(structure));
break;
case AST_DATA_POINTER:
- notmatch = ast_data_search_cmp_ptr(struct_children,
+ notmatch = data_search_cmp_ptr(struct_children,
node->name,
mapping[member].get.AST_DATA_POINTER(structure));
break;
@@ -1248,11 +1376,18 @@ static void data_result_destructor(void *obj)
struct ast_data *root = obj;
switch (root->type) {
- case AST_DATA_POINTER:
+ case AST_DATA_PASSWORD:
case AST_DATA_STRING:
- ast_free(root->payload.ptr);
+ ast_free(root->payload.str);
+ 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_TIMESTAMP:
+ case AST_DATA_SECONDS:
+ case AST_DATA_MILLISECONDS:
case AST_DATA_UNSIGNED_INTEGER:
case AST_DATA_DOUBLE:
case AST_DATA_BOOLEAN:
@@ -1315,6 +1450,105 @@ static struct ast_data *data_result_find_child(struct ast_data *root, const char
return found;
}
+int ast_data_search_match(const struct ast_data_search *search, struct ast_data *data)
+{
+ struct ao2_iterator i, ii;
+ struct ast_data_search *s, *s_child;
+ struct ast_data *d_child;
+ int notmatch = 1;
+
+ if (!search) {
+ return 1;
+ }
+
+ s_child = data_search_find(search->children, data->name);
+ if (!s_child) {
+ /* nothing to compare */
+ ao2_ref(s_child, -1);
+ return 1;
+ }
+
+ i = ao2_iterator_init(s_child->children, 0);
+ while ((s = ao2_iterator_next(&i))) {
+ if (!ao2_container_count(s->children)) {
+ /* compare this search node with every data node */
+ d_child = data_result_find_child(data, s->name);
+ if (!d_child) {
+ ao2_ref(s, -1);
+ notmatch = 1;
+ continue;
+ }
+
+ switch (d_child->type) {
+ case AST_DATA_PASSWORD:
+ 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,
+ d_child->payload.sint);
+ break;
+ case AST_DATA_BOOLEAN:
+ notmatch = data_search_cmp_bool(s_child, d_child->name,
+ d_child->payload.boolean);
+ break;
+ case AST_DATA_UNSIGNED_INTEGER:
+ notmatch = data_search_cmp_uint(s_child, d_child->name,
+ d_child->payload.uint);
+ break;
+ case AST_DATA_TIMESTAMP:
+ case AST_DATA_SECONDS:
+ case AST_DATA_MILLISECONDS:
+ case AST_DATA_DOUBLE:
+ notmatch = data_search_cmp_uint(s_child, d_child->name,
+ d_child->payload.dbl);
+ break;
+ case AST_DATA_IPADDR:
+ notmatch = data_search_cmp_ipaddr(s_child, d_child->name,
+ d_child->payload.ipaddr);
+ break;
+ case AST_DATA_POINTER:
+ notmatch = data_search_cmp_ptr(s_child, d_child->name,
+ d_child->payload.ptr);
+ break;
+ case AST_DATA_CONTAINER:
+ break;
+ }
+ ao2_ref(d_child, -1);
+ } else {
+ ii = ao2_iterator_init(data->children, 0);
+ while ((d_child = ao2_iterator_next(&ii))) {
+ if (strcmp(d_child->name, s->name)) {
+ ao2_ref(d_child, -1);
+ continue;
+ }
+ if (!(notmatch = !ast_data_search_match(s_child, d_child))) {
+ /* do not continue if we have a match. */
+ ao2_ref(d_child, -1);
+ break;
+ }
+ ao2_ref(d_child, -1);
+ }
+ ao2_iterator_destroy(&ii);
+ }
+ ao2_ref(s, -1);
+ if (notmatch) {
+ /* do not continue if we don't have a match. */
+ break;
+ }
+ }
+ ao2_iterator_destroy(&i);
+
+ ao2_ref(s_child, -1);
+
+ return !notmatch;
+}
+
/*!
* \internal
* \brief Get an internal node, from the result set.
@@ -1872,9 +2106,32 @@ static void data_get_xml_add_child(struct ast_data *parent_data,
case AST_DATA_CONTAINER:
data_get_xml_add_child(node, child_xml);
break;
+ case AST_DATA_PASSWORD:
+ ast_xml_set_text(child_xml, node->payload.str);
+ break;
+ case AST_DATA_TIMESTAMP:
+ snprintf(node_content, sizeof(node_content), "%d",
+ node->payload.uint);
+ ast_xml_set_text(child_xml, node_content);
+ break;
+ case AST_DATA_SECONDS:
+ snprintf(node_content, sizeof(node_content), "%d",
+ node->payload.uint);
+ ast_xml_set_text(child_xml, node_content);
+ break;
+ case AST_DATA_MILLISECONDS:
+ snprintf(node_content, sizeof(node_content), "%d",
+ node->payload.uint);
+ ast_xml_set_text(child_xml, node_content);
+ break;
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);
@@ -2006,15 +2263,24 @@ static struct ast_data *__ast_data_add(struct ast_data *root, const char *name,
node->payload.boolean = *(unsigned int *) ptr;
break;
case AST_DATA_INTEGER:
- node->payload.sint = *(unsigned int *) ptr;
+ node->payload.sint = *(int *) ptr;
break;
+ case AST_DATA_TIMESTAMP:
+ case AST_DATA_SECONDS:
+ case AST_DATA_MILLISECONDS:
case AST_DATA_UNSIGNED_INTEGER:
- node->payload.sint = *(unsigned int *) ptr;
+ node->payload.uint = *(unsigned int *) ptr;
break;
case AST_DATA_DOUBLE:
node->payload.dbl = *(double *) ptr;
break;
+ case AST_DATA_PASSWORD:
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;
@@ -2052,6 +2318,11 @@ struct ast_data *ast_data_add_int(struct ast_data *root, const char *name, int v
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)
{
@@ -2082,6 +2353,45 @@ struct ast_data *ast_data_add_ptr(struct ast_data *root, const char *childname,
return __ast_data_add(root, childname, AST_DATA_POINTER, ptr);
}
+struct ast_data *ast_data_add_timestamp(struct ast_data *root, const char *childname,
+ unsigned int timestamp)
+{
+ return __ast_data_add(root, childname, AST_DATA_TIMESTAMP, &timestamp);
+}
+
+struct ast_data *ast_data_add_seconds(struct ast_data *root, const char *childname,
+ unsigned int seconds)
+{
+ return __ast_data_add(root, childname, AST_DATA_SECONDS, &seconds);
+}
+
+struct ast_data *ast_data_add_milliseconds(struct ast_data *root, const char *childname,
+ unsigned int milliseconds)
+{
+ return __ast_data_add(root, childname, AST_DATA_MILLISECONDS, &milliseconds);
+}
+
+struct ast_data *ast_data_add_password(struct ast_data *root, const char *childname,
+ const char *value)
+{
+ char *name;
+ size_t namelen = 1 + (ast_strlen_zero(value) ? 0 : strlen(value));
+ struct ast_data *res;
+
+ if (!(name = ast_malloc(namelen))) {
+ return NULL;
+ }
+
+ strcpy(name, (ast_strlen_zero(value) ? "" : value));
+
+ res = __ast_data_add(root, childname, AST_DATA_PASSWORD, name);
+ if (!res) {
+ ast_free(name);
+ }
+
+ return res;
+}
+
struct ast_data *ast_data_add_str(struct ast_data *root, const char *childname,
const char *value)
{
@@ -2127,10 +2437,30 @@ int __ast_data_add_structure(struct ast_data *root,
ast_data_add_bool(root, mapping[i].name,
mapping[i].get.AST_DATA_BOOLEAN(structure));
break;
+ case AST_DATA_PASSWORD:
+ ast_data_add_password(root, mapping[i].name,
+ mapping[i].get.AST_DATA_PASSWORD(structure));
+ break;
+ case AST_DATA_TIMESTAMP:
+ ast_data_add_timestamp(root, mapping[i].name,
+ mapping[i].get.AST_DATA_TIMESTAMP(structure));
+ break;
+ case AST_DATA_SECONDS:
+ ast_data_add_seconds(root, mapping[i].name,
+ mapping[i].get.AST_DATA_SECONDS(structure));
+ break;
+ case AST_DATA_MILLISECONDS:
+ ast_data_add_milliseconds(root, mapping[i].name,
+ mapping[i].get.AST_DATA_MILLISECONDS(structure));
+ break;
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;
case AST_DATA_IPADDR:
@@ -2277,6 +2607,21 @@ int ast_data_retrieve(struct ast_data *tree, const char *path,
case AST_DATA_STRING:
content->value.AST_DATA_STRING = node->payload.str;
break;
+ case AST_DATA_PASSWORD:
+ content->value.AST_DATA_PASSWORD = node->payload.str;
+ break;
+ case AST_DATA_TIMESTAMP:
+ content->value.AST_DATA_TIMESTAMP = node->payload.uint;
+ break;
+ case AST_DATA_SECONDS:
+ content->value.AST_DATA_SECONDS = node->payload.uint;
+ break;
+ case AST_DATA_MILLISECONDS:
+ content->value.AST_DATA_MILLISECONDS = node->payload.uint;
+ 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;
@@ -2310,7 +2655,12 @@ static const struct {
enum ast_data_type type;
int color;
} data_result_color[] = {
- { AST_DATA_STRING, COLOR_CYAN },
+ { AST_DATA_STRING, COLOR_BLUE },
+ { AST_DATA_PASSWORD, COLOR_BRBLUE },
+ { AST_DATA_TIMESTAMP, COLOR_CYAN },
+ { AST_DATA_SECONDS, COLOR_MAGENTA },
+ { AST_DATA_MILLISECONDS, COLOR_BRMAGENTA },
+ { AST_DATA_CHARACTER, COLOR_GRAY },
{ AST_DATA_INTEGER, COLOR_RED },
{ AST_DATA_UNSIGNED_INTEGER, COLOR_RED },
{ AST_DATA_DOUBLE, COLOR_RED },
@@ -2373,16 +2723,43 @@ static void data_result_print_cli_node(int fd, const struct ast_data *node, uint
ast_str_append(&output, 0, "%s%s: %p\n", ast_str_buffer(tabs),
node->name, node->payload.ptr);
break;
+ case AST_DATA_PASSWORD:
+ ast_str_append(&output, 0, "%s%s: \"%s\"\n",
+ ast_str_buffer(tabs),
+ node->name,
+ node->payload.str);
+ break;
case AST_DATA_STRING:
ast_str_append(&output, 0, "%s%s: \"%s\"\n",
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),
node->name);
break;
+ case AST_DATA_TIMESTAMP:
+ ast_str_append(&output, 0, "%s%s: %d\n", ast_str_buffer(tabs),
+ node->name,
+ node->payload.uint);
+ break;
+ case AST_DATA_SECONDS:
+ ast_str_append(&output, 0, "%s%s: %d\n", ast_str_buffer(tabs),
+ node->name,
+ node->payload.uint);
+ break;
+ case AST_DATA_MILLISECONDS:
+ ast_str_append(&output, 0, "%s%s: %d\n", ast_str_buffer(tabs),
+ node->name,
+ node->payload.uint);
+ break;
case AST_DATA_INTEGER:
ast_str_append(&output, 0, "%s%s: %d\n", ast_str_buffer(tabs),
node->name,
@@ -2470,6 +2847,8 @@ static void data_result_print_cli(int fd, const struct ast_data *root)
ast_free(output);
__data_result_print_cli(fd, root, 0);
+
+ ast_cli(fd, "\n");
}
/*!
@@ -2644,12 +3023,21 @@ static void data_result_manager_output(struct mansession *s, const char *name,
case AST_DATA_INTEGER:
astman_append(s, ": %d\r\n", node->payload.sint);
break;
+ case AST_DATA_TIMESTAMP:
+ case AST_DATA_SECONDS:
+ case AST_DATA_MILLISECONDS:
case AST_DATA_UNSIGNED_INTEGER:
astman_append(s, ": %u\r\n", node->payload.uint);
break;
+ case AST_DATA_PASSWORD:
+ astman_append(s, ": %s\r\n", node->payload.str);
+ 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));
break;
@@ -2712,6 +3100,34 @@ static int manager_data_get(struct mansession *s, const struct message *m)
return RESULT_SUCCESS;
}
+int ast_data_add_codecs(struct ast_data *root, const char *node_name, format_t capability)
+{
+ struct ast_data *codecs, *codec;
+ size_t fmlist_size;
+ const struct ast_format_list *fmlist;
+ int x;
+
+ codecs = ast_data_add_node(root, node_name);
+ if (!codecs) {
+ return -1;
+ }
+ fmlist = ast_get_format_list(&fmlist_size);
+ for (x = 0; x < fmlist_size; x++) {
+ if (fmlist[x].bits & capability) {
+ codec = ast_data_add_node(codecs, "codec");
+ if (!codec) {
+ return -1;
+ }
+ ast_data_add_str(codec, "name", fmlist[x].name);
+ ast_data_add_int(codec, "samplespersecond", fmlist[x].samplespersecond);
+ ast_data_add_str(codec, "description", fmlist[x].desc);
+ ast_data_add_int(codec, "frame_length", fmlist[x].fr_len);
+ }
+ }
+
+ return 0;
+}
+
#ifdef TEST_FRAMEWORK
/*!
@@ -2753,10 +3169,6 @@ static int test_data_full_provider(const struct ast_data_search *search,
.a_uint = 20
};
- if (ast_data_search_cmp_structure(search, test_structure, &local_test_structure, "test_structure")) {
- return 0;
- }
-
test_structure = ast_data_add_node(root, "test_structure");
if (!test_structure) {
ast_debug(1, "Internal data api error\n");
@@ -2766,6 +3178,10 @@ static int test_data_full_provider(const struct ast_data_search *search,
/* add the complete structure. */
ast_data_add_structure(test_structure, test_structure, &local_test_structure);
+ if (!ast_data_search_match(search, test_structure)) {
+ ast_data_remove_node(root, test_structure);
+ }
+
return 0;
}