From 2d8844df8778b72c8ab0d0e40ed0af2bebf989a6 Mon Sep 17 00:00:00 2001 From: Amin Ben Romdhane Date: Mon, 29 Jul 2024 13:25:13 +0200 Subject: [PATCH] Operate/event: Store output data in blob message --- bbfdmd/ubus/bbfdmd.c | 4 +- bbfdmd/ubus/events.c | 24 +-- bbfdmd/ubus/operate.c | 74 ++++---- bbfdmd/ubus/operate.h | 3 +- libbbfdm-api/dmapi.h | 2 + libbbfdm-api/dmbbf.c | 277 ++++++++++++++++++++++++----- libbbfdm-api/dmbbf.h | 5 + libbbfdm-api/dmentry.c | 8 +- libbbfdm-api/plugin/json_plugin.c | 2 +- test/bbf_test/libbbf_test.c | 10 +- test/cmocka/Makefile | 2 +- test/cmocka/functional_test_bbfd.c | 117 ++++++++---- 12 files changed, 371 insertions(+), 157 deletions(-) diff --git a/bbfdmd/ubus/bbfdmd.c b/bbfdmd/ubus/bbfdmd.c index bf4ee306..3655aacf 100644 --- a/bbfdmd/ubus/bbfdmd.c +++ b/bbfdmd/ubus/bbfdmd.c @@ -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); diff --git a/bbfdmd/ubus/events.c b/bbfdmd/ubus/events.c index 37da8b41..95fca3be 100644 --- a/bbfdmd/ubus/events.c +++ b/bbfdmd/ubus/events.c @@ -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: diff --git a/bbfdmd/ubus/operate.c b/bbfdmd/ubus/operate.c index e51cf859..50c8d055 100644 --- a/bbfdmd/ubus/operate.c +++ b/bbfdmd/ubus/operate.c @@ -16,12 +16,16 @@ #include -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); } diff --git a/bbfdmd/ubus/operate.h b/bbfdmd/ubus/operate.h index 7041b037..0cc2ff04 100644 --- a/bbfdmd/ubus/operate.h +++ b/bbfdmd/ubus/operate.h @@ -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 */ diff --git a/libbbfdm-api/dmapi.h b/libbbfdm-api/dmapi.h index 421a6678..a4cc38a4 100644 --- a/libbbfdm-api/dmapi.h +++ b/libbbfdm-api/dmapi.h @@ -24,6 +24,7 @@ #include #include #include +#include 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; diff --git a/libbbfdm-api/dmbbf.c b/libbbfdm-api/dmbbf.c index b711a912..d478ae16 100644 --- a/libbbfdm-api/dmbbf.c +++ b/libbbfdm-api/dmbbf.c @@ -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); diff --git a/libbbfdm-api/dmbbf.h b/libbbfdm-api/dmbbf.h index 1d6c6cfc..ebf3b7be 100644 --- a/libbbfdm-api/dmbbf.h +++ b/libbbfdm-api/dmbbf.h @@ -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); diff --git a/libbbfdm-api/dmentry.c b/libbbfdm-api/dmentry.c index f1c6092d..f389db6b 100644 --- a/libbbfdm-api/dmentry.c +++ b/libbbfdm-api/dmentry.c @@ -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); diff --git a/libbbfdm-api/plugin/json_plugin.c b/libbbfdm-api/plugin/json_plugin.c index e58e9523..9b9b4370 100644 --- a/libbbfdm-api/plugin/json_plugin.c +++ b/libbbfdm-api/plugin/json_plugin.c @@ -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); } diff --git a/test/bbf_test/libbbf_test.c b/test/bbf_test/libbbf_test.c index 4a09369c..4e06b8b7 100644 --- a/test/bbf_test/libbbf_test.c +++ b/test/bbf_test/libbbf_test.c @@ -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; } } diff --git a/test/cmocka/Makefile b/test/cmocka/Makefile index f324fe15..a16d45ad 100644 --- a/test/cmocka/Makefile +++ b/test/cmocka/Makefile @@ -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 diff --git a/test/cmocka/functional_test_bbfd.c b/test/cmocka/functional_test_bbfd.c index 4f1fbf19..8e85c035 100644 --- a/test/cmocka/functional_test_bbfd.c +++ b/test/cmocka/functional_test_bbfd.c @@ -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"); } }