Operate/event: Store output data in blob message

This commit is contained in:
Amin Ben Romdhane 2024-07-29 13:25:13 +02:00
parent 10fc12a183
commit 2d8844df87
12 changed files with 371 additions and 157 deletions

View file

@ -647,10 +647,10 @@ static int bbfdm_operate_handler(struct ubus_context *ctx, struct ubus_object *o
INFO("ubus method|%s|, name|%s|, path(%s)", method, obj->name, data.bbf_ctx.in_param);
if (is_sync_operate_cmd(&data)) {
bbfdm_operate_cmd_sync(&data);
bbfdm_operate_cmd(&data, NULL);
} else {
cancel_instance_refresh_timer(ctx);
bbfdm_start_deferred(&data, bbfdm_operate_cmd_async, true);
bbfdm_start_deferred(&data, bbfdm_operate_cmd, true);
}
FREE(str);

View file

@ -76,35 +76,13 @@ static void bbfdm_event_handler(struct ubus_context *ctx, struct ubus_event_hand
cancel_instance_refresh_timer(ctx);
struct dm_parameter *param = NULL;
struct blob_buf b = {0}, bb = {0};
char method_name[256] = {0};
memset(&b, 0, sizeof(struct blob_buf));
memset(&bb, 0, sizeof(struct blob_buf));
blob_buf_init(&b, 0);
blob_buf_init(&bb, 0);
list_for_each_entry(param, &bbf_ctx.list_parameter, list) {
if (strcmp(param->name, "Event_Path") == 0) {
blobmsg_add_string(&b, "name", param->data);
strncpyt(dm_path, param->data, sizeof(dm_path));
} else {
blobmsg_add_string(&bb, param->name, param->data);
}
}
snprintf(method_name, sizeof(method_name), "%s.%s", DM_STRLEN(u->config.out_root_obj) ? u->config.out_root_obj : u->config.out_name, BBF_EVENT_NAME);
blobmsg_add_field(&b, BLOBMSG_TYPE_TABLE, "input", blob_data(bb.head), blob_len(bb.head));
ubus_send_event(ctx, method_name, b.head);
ubus_send_event(ctx, method_name, bbf_ctx.bb.head);
INFO("Event[%s], for [%s] sent", method_name, dm_path);
blob_buf_free(&bb);
blob_buf_free(&b);
register_instance_refresh_timer(ctx, 2000);
end:

View file

@ -16,12 +16,16 @@
#include <libubus.h>
static int bbfdm_dm_operate(bbfdm_data_t *data)
void bbfdm_operate_cmd(bbfdm_data_t *data, void *output)
{
int fault = 0;
void *table, *array;
memset(&data->bb, 0, sizeof(struct blob_buf));
bbf_init(&data->bbf_ctx);
blob_buf_init(&data->bb, 0);
void *global_array = blobmsg_open_array(&data->bb, "results");
void *global_table = blobmsg_open_table(&data->bb, NULL);
blobmsg_add_string(&data->bb, "path", data->bbf_ctx.in_param);
@ -29,23 +33,34 @@ static int bbfdm_dm_operate(bbfdm_data_t *data)
fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_OPERATE);
if (fault == 0) {
struct dm_parameter *n;
void *table = NULL, *array = NULL;
struct blob_attr *cur = NULL;
size_t rem = 0;
if (data->is_raw) {
array = blobmsg_open_array(&data->bb, "output");
list_for_each_entry(n, &data->bbf_ctx.list_parameter, list) {
table = blobmsg_open_table(&data->bb, NULL);
bb_add_string(&data->bb, "path", n->name);
bb_add_string(&data->bb, "data", n->data);
bb_add_string(&data->bb, "type", n->type);
blobmsg_close_table(&data->bb, table);
blobmsg_for_each_attr(cur, data->bbf_ctx.bb.head, rem) {
blobmsg_add_blob(&data->bb, cur);
}
blobmsg_close_array(&data->bb, array);
} else {
LIST_HEAD(pv_local);
list_for_each_entry(n, &data->bbf_ctx.list_parameter, list) {
add_pv_list(n->name, n->data, n->type, &pv_local);
blobmsg_for_each_attr(cur, data->bbf_ctx.bb.head, rem) {
struct blob_attr *tb[3] = {0};
const struct blobmsg_policy p[3] = {
{ "path", BLOBMSG_TYPE_STRING },
{ "data", BLOBMSG_TYPE_STRING },
{ "type", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
char *op_name = blobmsg_get_string(tb[0]);
char *op_data = blobmsg_get_string(tb[1]);
char *op_type = blobmsg_get_string(tb[2]);
add_pv_list(op_name, op_data, op_type, &pv_local);
}
array = blobmsg_open_array(&data->bb, "output");
@ -63,34 +78,13 @@ static int bbfdm_dm_operate(bbfdm_data_t *data)
blobmsg_close_table(&data->bb, global_table);
blobmsg_close_array(&data->bb, global_array);
if (output)
memcpy(output, data->bb.head, blob_pad_len(data->bb.head));
else
ubus_send_reply(data->ctx, data->req, data->bb.head);
blob_buf_free(&data->bb);
bbf_cleanup(&data->bbf_ctx);
return fault;
}
static void bbfdm_operate_cmd(bbfdm_data_t *data)
{
void *array = blobmsg_open_array(&data->bb, "results");
bbfdm_dm_operate(data);
blobmsg_close_array(&data->bb, array);
}
void bbfdm_operate_cmd_async(bbfdm_data_t *data, void *output)
{
blob_buf_init(&data->bb, 0);
bbfdm_operate_cmd(data);
memcpy(output, data->bb.head, blob_pad_len(data->bb.head));
blob_buf_free(&data->bb);
}
void bbfdm_operate_cmd_sync(bbfdm_data_t *data)
{
blob_buf_init(&data->bb, 0);
bbfdm_operate_cmd(data);
ubus_send_reply(data->ctx, data->req, data->bb.head);
blob_buf_free(&data->bb);
}

View file

@ -12,7 +12,6 @@ enum {
__DM_OPERATE_MAX,
};
void bbfdm_operate_cmd_async(bbfdm_data_t *data, void *output);
void bbfdm_operate_cmd_sync(bbfdm_data_t *data);
void bbfdm_operate_cmd(bbfdm_data_t *data, void *output);
#endif /* OPERATE_H */

View file

@ -24,6 +24,7 @@
#include <uci.h>
#include <libubox/list.h>
#include <json-c/json.h>
#include <libubox/blob.h>
extern struct dm_permession_s DMREAD;
extern struct dm_permession_s DMWRITE;
@ -172,6 +173,7 @@ struct dmctx {
int (*checkleaf)(DMOBJECT_ARGS);
struct list_head list_parameter;
struct list_head *memhead;
struct blob_buf bb;
DMOBJ *dm_entryobj;
bool nextlevel;
bool iswildcard;

View file

@ -731,6 +731,120 @@ void free_all_list_parameter(struct dmctx *ctx)
}
}
static void bb_add_flags_arr(struct blob_buf *bb, uint32_t dm_flags)
{
if (!bb || !dm_flags)
return;
void *flags_arr = blobmsg_open_array(bb, "flags");
if (dm_flags & DM_FLAG_REFERENCE)
blobmsg_add_string(bb, NULL, "Reference");
if (dm_flags & DM_FLAG_UNIQUE)
blobmsg_add_string(bb, NULL, "Unique");
if (dm_flags & DM_FLAG_LINKER)
blobmsg_add_string(bb, NULL, "Linker");
if (dm_flags & DM_FLAG_SECURE)
blobmsg_add_string(bb, NULL, "Secure");
blobmsg_close_array(bb, flags_arr);
}
void fill_blob_param(struct blob_buf *bb, char *path, char *data, char *type, uint32_t dm_flags)
{
if (!bb || !path || !data || !type)
return;
void *table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", path);
blobmsg_add_string(bb, "data", data);
blobmsg_add_string(bb, "type", type);
bb_add_flags_arr(bb, dm_flags);
blobmsg_close_table(bb, table);
}
void fill_blob_event(struct blob_buf *bb, char *path, char *type, void *data)
{
if (!bb || !path || !type)
return;
void *table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", path);
blobmsg_add_string(bb, "type", type);
if (data) {
event_args *ev = (event_args *)data;
blobmsg_add_string(bb, "data", (ev && ev->name) ? ev->name : "");
if (ev && ev->param) {
const char **in = ev->param;
void *key = blobmsg_open_array(bb, "input");
for (int i = 0; in[i] != NULL; i++) {
void *in_table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", in[i]);
blobmsg_close_table(bb, in_table);
}
blobmsg_close_array(bb, key);
}
}
blobmsg_close_table(bb, table);
}
void fill_blob_operate(struct blob_buf *bb, char *path, char *data, char *type, void *in_out)
{
if (!bb || !path || !data || !type)
return;
void *op_table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", path);
blobmsg_add_string(bb, "type", type);
blobmsg_add_string(bb, "data", data);
if (in_out) {
void *array, *table;
const char **in, **out;
operation_args *args;
int i;
args = (operation_args *)in_out;
in = args->in;
if (in) {
array = blobmsg_open_array(bb, "input");
for (i = 0; in[i] != NULL; i++) {
table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", in[i]);
blobmsg_close_table(bb, table);
}
blobmsg_close_array(bb, array);
}
out = args->out;
if (out) {
array = blobmsg_open_array(bb, "output");
for (i = 0; out[i] != NULL; i++) {
table = blobmsg_open_table(bb, NULL);
blobmsg_add_string(bb, "path", out[i]);
blobmsg_close_table(bb, table);
}
blobmsg_close_array(bb, array);
}
}
blobmsg_close_table(bb, op_table);
}
int string_to_bool(char *v, bool *b)
{
if (v[0] == '1' && v[1] == '\0') {
@ -1017,6 +1131,51 @@ static void get_reference_paramater_value(struct dmctx *dmctx, char *in_value, c
str[pos - 1] = 0;
}
static struct blob_attr *get_results_array(struct blob_attr *msg)
{
struct blob_attr *tb[1] = {0};
const struct blobmsg_policy p[1] = {
{ "results", BLOBMSG_TYPE_ARRAY }
};
if (msg == NULL)
return NULL;
blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
return tb[0];
}
static void prepare_optional_table(struct dmctx *dmctx, struct blob_buf *bb)
{
void *table = blobmsg_open_table(bb, "optional");
blobmsg_add_string(bb, "proto", (dmctx->dm_type == BBFDM_BOTH) ? "both" : (dmctx->dm_type == BBFDM_CWMP) ? "cwmp" : "usp");
blobmsg_add_string(bb, "format", "raw");
blobmsg_close_table(bb, table);
}
typedef void (*ms_ubus_cb)(struct ubus_request *req, int type, struct blob_attr *msg);
static int ubus_call_blob_msg(char *obj, char *method, struct blob_buf *blob, int timeout, ms_ubus_cb ms_callback, void *callback_arg)
{
struct ubus_context *ubus_ctx = NULL;
uint32_t id;
int rc = -1;
ubus_ctx = ubus_connect(NULL);
if (ubus_ctx == NULL) {
BBF_DEBUG("UBUS context is null\n\r");
return -1;
}
if (!ubus_lookup_id(ubus_ctx, obj, &id)) {
rc = ubus_invoke(ubus_ctx, id, method, blob->head,
ms_callback, callback_arg, timeout);
}
return rc;
}
static int get_ubus_value(struct dmctx *dmctx, struct dmnode *node)
{
json_object *res = NULL, *res_obj = NULL;
@ -1521,71 +1680,88 @@ static int get_ubus_name(struct dmctx *dmctx, struct dmnode *node)
return 0;
}
static int operate_ubus(struct dmctx *dmctx, struct dmnode *node)
static void __operate_ubus(struct ubus_request *req, int type, struct blob_attr *msg)
{
json_object *res = NULL, *res_obj = NULL;
char *ubus_name = node->obj->checkdep;
struct blob_attr *cur = NULL;
int rem = 0;
json_object *in_args = json_object_new_object();
json_object_object_add(in_args, "format", json_object_new_string("raw"));
if (!msg || !req)
return;
dmubus_call_blocking(ubus_name, "operate",
UBUS_ARGS{
{"command", dmctx->in_param, String},
{"command_key", dmctx->linker, String},
{"input", dmctx->in_value ? dmctx->in_value : "{}", Table},
{"optional", json_object_to_json_string(in_args), Table}
},
4, &res);
struct dmctx *dmctx = (struct dmctx *)req->priv;
json_object_put(in_args);
if (!res)
return USP_FAULT_INVALID_PATH;
json_object *res_array = dmjson_get_obj(res, 1, "results");
if (!res_array) {
if (res != NULL)
json_object_put(res);
return USP_FAULT_INVALID_PATH;
struct blob_attr *parameters = get_results_array(msg);
if (parameters == NULL) {
dmctx->faultcode = USP_FAULT_INVALID_PATH;
return;
}
size_t nbre_obj = json_object_array_length(res_array);
int array_len = blobmsg_len(parameters);
if (array_len == 0) {
dmctx->findparam = 1;
return;
}
for (size_t i = 0; i < nbre_obj; i++) {
res_obj = json_object_array_get_idx(res_array, i);
blobmsg_for_each_attr(cur, parameters, rem) {
struct blob_attr *tb[3] = {0};
const struct blobmsg_policy p[3] = {
{ "fault", BLOBMSG_TYPE_INT32 },
{ "fault_msg", BLOBMSG_TYPE_STRING },
{ "output", BLOBMSG_TYPE_ARRAY }
};
char *fault = dmjson_get_value(res_obj, 1, "fault");
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
if (DM_STRLEN(fault) == 0 || (DM_STRTOUL(fault) != FAULT_9005 && DM_STRTOUL(fault) != USP_FAULT_INVALID_PATH))
uint32_t fault = tb[0] ? blobmsg_get_u32(tb[0]) : 0;
if (fault == 0 || (fault != FAULT_9005 && fault != USP_FAULT_INVALID_PATH))
dmctx->stop = 1;
if (DM_STRLEN(fault)) {
char *fault_msg = dmjson_get_value(res_obj, 1, "fault_msg");
bbfdm_set_fault_message(dmctx, "%s", fault_msg);
if (res != NULL)
json_object_put(res);
return DM_STRTOUL(fault);
if (fault) {
bbfdm_set_fault_message(dmctx, "%s", tb[0] ? blobmsg_get_string(tb[0]) : "");
dmctx->faultcode = fault;
return;
} else {
dmctx->faultcode = 0;
}
json_object *output_array = dmjson_get_obj(res_obj, 1, "output");
if (output_array) {
size_t out_nbre = json_object_array_length(output_array);
if (tb[2]) {
struct blob_attr *output = NULL;
int _rem = 0;
for (size_t j = 0; j < out_nbre; j++) {
json_object *out_obj = json_object_array_get_idx(output_array, j);
char *path = dmjson_get_value(out_obj, 1, "path");
char *data = dmjson_get_value(out_obj, 1, "data");
char *type = dmjson_get_value(out_obj, 1, "type");
add_list_parameter(dmctx, dmstrdup(path), dmstrdup(data), dmstrdup(type), NULL);
blobmsg_for_each_attr(output, tb[2], _rem) {
blobmsg_add_blob(&dmctx->bb, output);
}
}
}
}
if (res != NULL)
json_object_put(res);
static int operate_ubus(struct dmctx *dmctx, struct dmnode *node)
{
char *ubus_name = node->obj->checkdep;
struct blob_buf blob = {0};
memset(&blob, 0, sizeof(struct blob_buf));
blob_buf_init(&blob, 0);
blobmsg_add_string(&blob, "command", dmctx->in_param);
blobmsg_add_string(&blob, "command_key", dmctx->linker);
json_object *jobj = json_tokener_parse(dmctx->in_value ? dmctx->in_value : "{}");
blobmsg_add_json_element(&blob, "input", jobj);
json_object_put(jobj);
prepare_optional_table(dmctx, &blob);
int res = ubus_call_blob_msg(ubus_name, "operate", &blob, 20000, __operate_ubus, dmctx);
blob_buf_free(&blob);
if (res)
return USP_FAULT_INVALID_PATH;
if (dmctx->faultcode)
return dmctx->faultcode;
return 0;
}
@ -2652,9 +2828,12 @@ static int mparam_event(DMPARAM_ARGS)
dmctx->stop = 1;
blobmsg_add_string(&dmctx->bb, "name", full_param);
void *table = blobmsg_open_table(&dmctx->bb, "input");
fault = (leaf->setvalue)(full_param, dmctx, data, instance, (char *)j_input, EVENT_RUN);
if (!fault)
add_list_parameter(dmctx, dmstrdup("Event_Path"), dmstrdup(full_param), DMT_TYPE[DMT_STRING], NULL);
blobmsg_close_table(&dmctx->bb, table);
end:
json_object_put(j_input);

View file

@ -33,6 +33,11 @@ char *handle_instance_without_section(struct dmctx *dmctx, DMNODE *parent_node,
int get_empty(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
void add_list_parameter(struct dmctx *ctx, char *param_name, char *param_data, char *param_type, char *additional_data);
void free_all_list_parameter(struct dmctx *ctx);
void fill_blob_param(struct blob_buf *bb, char *path, char *data, char *type, uint32_t dm_flags);
void fill_blob_event(struct blob_buf *bb, char *path, char *type, void *data);
void fill_blob_operate(struct blob_buf *bb, char *path, char *data, char *type, void *in_out);
int string_to_bool(char *v, bool *b);
char *get_value_by_reference(struct dmctx *ctx, char *value);
int dm_entry_get_value(struct dmctx *dmctx);

View file

@ -44,6 +44,8 @@ static struct dm_fault DM_FAULT_ARRAY[] = {
void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj)
{
memset(&ctx->bb, 0, sizeof(struct blob_buf));
blob_buf_init(&ctx->bb, 0);
INIT_LIST_HEAD(&ctx->list_parameter);
ctx->dm_entryobj = tEntryObj;
bbfdm_init_mem(ctx);
@ -52,6 +54,7 @@ void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj)
void bbf_ctx_clean(struct dmctx *ctx)
{
blob_buf_free(&ctx->bb);
free_all_list_parameter(ctx);
dm_uci_exit();
@ -187,7 +190,9 @@ int bbf_fault_map(struct dmctx *ctx, int fault)
int bbf_entry_method(struct dmctx *ctx, int cmd)
{
int fault = 0;
ctx->iswildcard = DM_STRCHR(ctx->in_param, '*') ? 1 : 0;
ctx->fault_msg[0] = 0;
ctx->stop = false;
if (!ctx->dm_entryobj) {
bbfdm_set_fault_message(ctx, "Root entry was not defined.");
@ -199,9 +204,6 @@ int bbf_entry_method(struct dmctx *ctx, int cmd)
return bbf_fault_map(ctx, FAULT_9005);
}
ctx->iswildcard = DM_STRCHR(ctx->in_param, '*') ? 1 : 0;
ctx->stop = false;
switch(cmd) {
case BBF_GET_VALUE:
fault = dm_entry_get_value(ctx);

View file

@ -1091,7 +1091,7 @@ static int ubus_set_operate(json_object *mapping_obj, int json_version, char *re
resolve_all_symbols(ctx, data, instance, "", nbr_instances, json_version, key, buf_key, sizeof(buf_key));
resolve_all_symbols(ctx, data, instance, "", nbr_instances, json_version, json_object_get_string(val), buf_val, sizeof(buf_val));
add_list_parameter(ctx, dmstrdup(buf_key), dmstrdup(buf_val), DMT_TYPE[DMT_STRING], NULL);
fill_blob_param(&ctx->bb, buf_key, buf_val, DMT_TYPE[DMT_STRING], 0);
}
json_object_put(res);
}

View file

@ -143,11 +143,11 @@ static int operate_DeviceXIOPSYSEUPingTEST_Run(char *refparam, struct dmctx *ctx
if (DM_STRSTR(line, "rtt")) {
strtok_r(line, "=", &min);
strtok_r(min ? min+1 : "", "/", &avg);
add_list_parameter(ctx, dmstrdup("MinimumResponseTime"), dmstrdup(min ? min+1 : ""), "xsd:unsignedInt", NULL);
fill_blob_param(&ctx->bb, "MinimumResponseTime", min ? min + 1 : "", "xsd:unsignedInt", 0);
strtok_r(avg, "/", &max);
add_list_parameter(ctx, dmstrdup("AverageResponseTime"), dmstrdup(avg ? avg : ""), "xsd:unsignedInt", NULL);
fill_blob_param(&ctx->bb, "AverageResponseTime", avg ? avg : "", "xsd:unsignedInt", 0);
strtok_r(max, "/", &p);
add_list_parameter(ctx, dmstrdup("MaximumResponseTime"), dmstrdup(max ? max : ""), "xsd:unsignedInt", NULL);
fill_blob_param(&ctx->bb, "MaximumResponseTime", max ? max : "", "xsd:unsignedInt", 0);
break;
}
}
@ -206,8 +206,8 @@ static int event_XIOPSYSEUEventTEST_Test(char *refparam, struct dmctx *ctx, void
char *command_key = dmjson_get_value((json_object *)value, 1, "command_key");
char *status = dmjson_get_value((json_object *)value, 1, "status");
add_list_parameter(ctx, dmstrdup("CommandKey"), dmstrdup(command_key), DMT_TYPE[DMT_STRING], NULL);
add_list_parameter(ctx, dmstrdup("Status"), dmstrdup(status), DMT_TYPE[DMT_STRING], NULL);
fill_blob_param(&ctx->bb, "CommandKey", command_key, DMT_TYPE[DMT_STRING], 0);
fill_blob_param(&ctx->bb, "Status", status, DMT_TYPE[DMT_STRING], 0);
break;
}
}

View file

@ -1,6 +1,6 @@
CC = gcc
CFLAGS = -g -Wall -Werror
LDFLAGS = -lcmocka -L/usr/share/bbfdm -lbbfdm-api -lbbfdm
LDFLAGS = -lcmocka -lbbfdm-api -lbbfdm -lubox -lblobmsg_json
UNIT_TESTS = unit_test_bbfd
FUNCTIONAL_TESTS = functional_test_bbfd
FUNCTIONAL_API_TESTS = functional_api_test_bbfd

View file

@ -1230,7 +1230,8 @@ static void test_api_bbfdm_valid_standard_operate(void **state)
// TODO: To be used later with micro-service
#if 0
struct dmctx *ctx = (struct dmctx *) *state;
struct dm_parameter *n;
struct blob_attr *cur = NULL;
size_t rem = 0;
int fault = 0;
ctx->in_param = "Device.IP.Diagnostics.IPPing()";
@ -1239,22 +1240,35 @@ static void test_api_bbfdm_valid_standard_operate(void **state)
fault = bbf_entry_method(ctx, BBF_OPERATE);
assert_int_equal(fault, 0);
list_for_each_entry(n, &ctx->list_parameter, list) {
if (DM_STRCMP(n->name, "Status") == 0) {
assert_string_equal(n->data, "Complete");
assert_string_equal(n->type, "xsd:string");
} else if (DM_STRCMP(n->name, "IPAddressUsed") == 0) {
assert_string_equal(n->data, "");
assert_string_equal(n->type, "xsd:string");
} else if (DM_STRCMP(n->name, "SuccessCount") == 0) {
assert_string_equal(n->data, "1");
assert_string_equal(n->type, "xsd:unsignedInt");
} else if (DM_STRCMP(n->name, "FailureCount") == 0) {
assert_string_equal(n->data, "0");
assert_string_equal(n->type, "xsd:unsignedInt");
blobmsg_for_each_attr(cur, ctx->bb.head, rem) {
struct blob_attr *tb[3] = {0};
const struct blobmsg_policy p[3] = {
{ "path", BLOBMSG_TYPE_STRING },
{ "data", BLOBMSG_TYPE_STRING },
{ "type", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
char *name = blobmsg_get_string(tb[0]);
char *data = blobmsg_get_string(tb[1]);
char *type = blobmsg_get_string(tb[2]);
if (DM_STRCMP(name, "Status") == 0) {
assert_string_equal(data, "Complete");
assert_string_equal(type, "xsd:string");
} else if (DM_STRCMP(name, "IPAddressUsed") == 0) {
assert_string_equal(data, "");
assert_string_equal(type, "xsd:string");
} else if (DM_STRCMP(name, "SuccessCount") == 0) {
assert_string_equal(data, "1");
assert_string_equal(type, "xsd:unsignedInt");
} else if (DM_STRCMP(name, "FailureCount") == 0) {
assert_string_equal(data, "0");
assert_string_equal(type, "xsd:unsignedInt");
} else {
assert_string_not_equal(n->data, "0");
assert_string_equal(n->type, "xsd:unsignedInt");
assert_string_not_equal(data, "0");
assert_string_equal(type, "xsd:unsignedInt");
}
}
#endif
@ -1341,7 +1355,8 @@ static void test_api_bbfdm_valid_standard_list_operate(void **state)
static void test_api_bbfdm_valid_library_operate(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct dm_parameter *n;
struct blob_attr *cur = NULL;
size_t rem = 0;
int fault = 0;
ctx->in_param = "Device.X_IOPSYS_EU_PingTEST.Run()";
@ -1350,10 +1365,22 @@ static void test_api_bbfdm_valid_library_operate(void **state)
fault = bbf_entry_method(ctx, BBF_OPERATE);
assert_int_equal(fault, 0);
list_for_each_entry(n, &ctx->list_parameter, list) {
assert_string_not_equal(n->data, "0");
assert_string_equal(n->type, "xsd:unsignedInt");
}}
blobmsg_for_each_attr(cur, ctx->bb.head, rem) {
struct blob_attr *tb[2] = {0};
const struct blobmsg_policy p[2] = {
{ "data", BLOBMSG_TYPE_STRING },
{ "type", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 2, tb, blobmsg_data(cur), blobmsg_len(cur));
char *data = blobmsg_get_string(tb[0]);
char *type = blobmsg_get_string(tb[1]);
assert_string_not_equal(data, "0");
assert_string_equal(type, "xsd:unsignedInt");
}
}
static void test_api_bbfdm_valid_library_list_operate(void **state)
{
@ -1419,7 +1446,8 @@ static void test_api_bbfdm_valid_library_list_operate(void **state)
static void test_api_bbfdm_valid_json_operate(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct dm_parameter *n;
struct blob_attr *cur = NULL;
size_t rem = 0;
int fault = 0;
ctx->in_param = "Device.X_IOPSYS_EU_TEST.1.Status()";
@ -1427,10 +1455,23 @@ static void test_api_bbfdm_valid_json_operate(void **state)
fault = bbf_entry_method(ctx, BBF_OPERATE);
assert_int_equal(fault, 0);
list_for_each_entry(n, &ctx->list_parameter, list) {
assert_string_equal(n->name, "Result");
assert_string_equal(n->data, "Success");
assert_string_equal(n->type, "xsd:string");
blobmsg_for_each_attr(cur, ctx->bb.head, rem) {
struct blob_attr *tb[3] = {0};
const struct blobmsg_policy p[3] = {
{ "path", BLOBMSG_TYPE_STRING },
{ "data", BLOBMSG_TYPE_STRING },
{ "type", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
char *dm_name = blobmsg_get_string(tb[0]);
char *dm_data = blobmsg_get_string(tb[1]);
char *dm_type = blobmsg_get_string(tb[2]);
assert_string_equal(dm_name, "Result");
assert_string_equal(dm_data, "Success");
assert_string_equal(dm_type, "xsd:string");
}
}
@ -1486,7 +1527,8 @@ static void test_api_bbfdm_valid_json_list_operate(void **state)
static void test_api_bbfdm_valid_json_v1_operate(void **state)
{
struct dmctx *ctx = (struct dmctx *) *state;
struct dm_parameter *n;
struct blob_attr *cur = NULL;
size_t rem = 0;
int fault = 0;
ctx->in_param = "Device.UBUS_TEST_V1.Interface.3.Status()";
@ -1494,10 +1536,23 @@ static void test_api_bbfdm_valid_json_v1_operate(void **state)
fault = bbf_entry_method(ctx, BBF_OPERATE);
assert_int_equal(fault, 0);
list_for_each_entry(n, &ctx->list_parameter, list) {
assert_string_equal(n->name, "Result");
assert_string_equal(n->data, "Success");
assert_string_equal(n->type, "xsd:string");
blobmsg_for_each_attr(cur, ctx->bb.head, rem) {
struct blob_attr *tb[3] = {0};
const struct blobmsg_policy p[3] = {
{ "path", BLOBMSG_TYPE_STRING },
{ "data", BLOBMSG_TYPE_STRING },
{ "type", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
char *dm_name = blobmsg_get_string(tb[0]);
char *dm_data = blobmsg_get_string(tb[1]);
char *dm_type = blobmsg_get_string(tb[2]);
assert_string_equal(dm_name, "Result");
assert_string_equal(dm_data, "Success");
assert_string_equal(dm_type, "xsd:string");
}
}