diff --git a/bbfdmd/ubus/bbfdmd.c b/bbfdmd/ubus/bbfdmd.c index db499f81..1d87090b 100644 --- a/bbfdmd/ubus/bbfdmd.c +++ b/bbfdmd/ubus/bbfdmd.c @@ -49,8 +49,6 @@ extern struct list_head json_memhead; // micro-services should not use fork by default #define BBF_SUBPROCESS_DEPTH (0) -// default instance updater timeout -#define BBF_INSTANCES_UPDATE_TIMEOUT (60 * 1000) LIST_HEAD(head_registered_service); @@ -137,15 +135,12 @@ static void fill_optional_data(bbfdm_data_t *data, struct blob_attr *msg) data->bbf_ctx.dm_type = get_proto_type(val); } - if (is_str_eq(blobmsg_name(attr), "transaction_id")) - data->trans_id = blobmsg_get_u32(attr); - if (is_str_eq(blobmsg_name(attr), "format")) data->is_raw = is_str_eq(blobmsg_get_string(attr), "raw") ? true : false; } char *proto = (data->bbf_ctx.dm_type == BBFDM_BOTH) ? "both" : (data->bbf_ctx.dm_type == BBFDM_CWMP) ? "cwmp" : "usp"; - DEBUG("Proto:|%s|, Tran-id:|%d|, is_raw:|%d|", proto, data->trans_id, data->is_raw); + DEBUG("Proto:|%s|, is_raw:|%d|", proto, data->is_raw); } static void async_req_free(struct bbfdm_async_req *r) @@ -517,7 +512,6 @@ int bbfdm_set_handler(struct ubus_context *ctx, struct ubus_object *obj, char path[PATH_MAX] = {'\0'}; bbfdm_data_t data; int fault = 0; - int trans_id = 0; LIST_HEAD(pv_list); memset(&data, 0, sizeof(bbfdm_data_t)); @@ -555,44 +549,25 @@ int bbfdm_set_handler(struct ubus_context *ctx, struct ubus_object *obj, if (list_empty(&pv_list)) { ERR("Fault in fill pvlist set path |%s| : |list is empty|", data.bbf_ctx.in_param); fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); + fault = USP_FAULT_INTERNAL_ERROR; goto end; } data.plist = &pv_list; - // no need to process it further since transaction-id is not valid - if (data.trans_id && !is_transaction_valid(data.trans_id)) { - WARNING("Transaction not started yet"); - fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); - goto end; - } else { - data.bbf_ctx.trans_id = data.trans_id; - } - - if (data.trans_id == 0) { - // Transaction-id is not defined so create an internal transaction - cancel_instance_refresh_timer(ctx); - trans_id = transaction_start(&data, "INT_SET", 0); - if (trans_id == 0) { - WARNING("Failed to get the lock for the transaction"); - fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); - goto end; - } - } - - bbfdm_set_value(&data); - - if (data.trans_id == 0) { - // Internal transaction: need to commit the changes - transaction_commit(NULL, trans_id, true); - register_instance_refresh_timer(ctx, 100); - } + fault = bbfdm_set_value(&data); end: + if ((data.bbf_ctx.dm_type == BBFDM_BOTH) && (is_micro_service == false)) { + bbf_entry_services(data.bbf_ctx.dm_type, (!fault) ? true : false, true); + } + + bbf_cleanup(&data.bbf_ctx); + free_pv_list(&pv_list); + ubus_send_reply(ctx, req, data.bb.head); blob_buf_free(&data.bb); - free_pv_list(&pv_list); - bbf_cleanup(&data.bbf_ctx); + return 0; } @@ -662,7 +637,6 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj, struct blob_attr *tb[__DM_ADD_MAX]; char path[PATH_MAX]; bbfdm_data_t data; - int trans_id = 0; int fault = 0; memset(&data, 0, sizeof(bbfdm_data_t)); @@ -687,36 +661,9 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj, blob_buf_init(&data.bb, 0); bbf_init(&data.bbf_ctx); - // no need to process it further since transaction-id is not valid - if (data.trans_id && !is_transaction_valid(data.trans_id)) { - WARNING("Transaction not started yet"); - fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); - goto end; - } else { - data.bbf_ctx.trans_id = data.trans_id; - } - - if (data.trans_id == 0) { - // Transaction-id is not defined so create an internal transaction - cancel_instance_refresh_timer(ctx); - trans_id = transaction_start(&data, "INT_ADD", 0); - if (trans_id == 0) { - ERR("Failed to get the lock for the transaction"); - fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); - goto end; - } - } - fault = create_add_response(&data); if (fault) { ERR("Fault in add path |%s|", data.bbf_ctx.in_param); - - if (data.trans_id == 0) { - // Internal transaction: need to abort the changes - transaction_abort(NULL, trans_id); - register_instance_refresh_timer(ctx, 100); - } - goto end; } @@ -729,13 +676,6 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj, if (fault) { ERR("Fault in fill pvlist set path |%s|", path); fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); - - if (data.trans_id == 0) { - // Internal transaction: need to abort the changes - transaction_abort(NULL, trans_id); - register_instance_refresh_timer(ctx, 100); - } - free_pv_list(&pv_list); goto end; } @@ -747,16 +687,16 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj, free_pv_list(&pv_list); } - if (data.trans_id == 0) { - // Internal transaction: need to commit the changes - transaction_commit(NULL, trans_id, true); - register_instance_refresh_timer(ctx, 100); +end: + if ((data.bbf_ctx.dm_type == BBFDM_BOTH) && (is_micro_service == false)) { + bbf_entry_services(data.bbf_ctx.dm_type, (!fault) ? true : false, false); } -end: + bbf_cleanup(&data.bbf_ctx); + ubus_send_reply(ctx, req, data.bb.head); blob_buf_free(&data.bb); - bbf_cleanup(&data.bbf_ctx); + return 0; } @@ -773,7 +713,7 @@ int bbfdm_del_handler(struct ubus_context *ctx, struct ubus_object *obj, struct blob_attr *tb[__DM_DEL_MAX]; LIST_HEAD(paths_list); bbfdm_data_t data; - int trans_id = 0; + int fault = 0; memset(&data, 0, sizeof(bbfdm_data_t)); @@ -814,121 +754,17 @@ int bbfdm_del_handler(struct ubus_context *ctx, struct ubus_object *obj, data.bbf_ctx.in_param = tb[DM_DEL_PATH] ? blobmsg_get_string(tb[DM_DEL_PATH]) : ""; - // no need to process it further since transaction-id is not valid - if (data.trans_id && !is_transaction_valid(data.trans_id)) { - WARNING("Transaction not started yet"); - fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); - goto end; - } else { - data.bbf_ctx.trans_id = data.trans_id; + fault = create_del_response(&data); + + if ((data.bbf_ctx.dm_type == BBFDM_BOTH) && (is_micro_service == false)) { + bbf_entry_services(data.bbf_ctx.dm_type, (!fault) ? true : false, true); } - if (data.trans_id == 0) { - // Transaction-id is not defined so create an internal transaction - cancel_instance_refresh_timer(ctx); - trans_id = transaction_start(&data, "INT_DEL", 0); - if (trans_id == 0) { - WARNING("Failed to get the lock for the transaction"); - fill_err_code_array(&data, USP_FAULT_INTERNAL_ERROR); - goto end; - } - } - - create_del_response(&data); - - if (data.trans_id == 0) { - // Internal transaction: need to commit the changes - transaction_commit(NULL, trans_id, true); - register_instance_refresh_timer(ctx, 100); - } - -end: - ubus_send_reply(ctx, req, data.bb.head); - blob_buf_free(&data.bb); bbf_cleanup(&data.bbf_ctx); free_path_list(&paths_list); - return 0; -} - -enum { - TRANS_CMD, - TRANS_TIMEOUT, - TRANS_RESTART, - TRANS_OPTIONAL, - __TRANS_MAX, -}; - -static const struct blobmsg_policy transaction_policy[] = { - [TRANS_CMD] = { .name = "cmd", .type = BLOBMSG_TYPE_STRING }, - [TRANS_TIMEOUT] = { .name = "timeout", .type = BLOBMSG_TYPE_INT32 }, - [TRANS_RESTART] = { .name = "restart_services", .type = BLOBMSG_TYPE_INT8 }, - [TRANS_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, -}; - -static int bbfdm_transaction_handler(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__TRANS_MAX] = {NULL}; - bbfdm_data_t data; - - bool is_service_restart = true; - uint32_t max_timeout = 0; - char *trans_cmd = "status"; - int ret; - - memset(&data, 0, sizeof(bbfdm_data_t)); - - if (blobmsg_parse(transaction_policy, __TRANS_MAX, tb, blob_data(msg), blob_len(msg))) { - ERR("Failed to parse blob"); - return UBUS_STATUS_UNKNOWN_ERROR; - } - - if (!tb[TRANS_CMD]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[TRANS_CMD]) - trans_cmd = blobmsg_get_string(tb[TRANS_CMD]); - - if (tb[TRANS_TIMEOUT]) - max_timeout = blobmsg_get_u32(tb[TRANS_TIMEOUT]); - - if (tb[TRANS_RESTART]) - is_service_restart = blobmsg_get_bool(tb[TRANS_RESTART]); - - fill_optional_data(&data, tb[TRANS_OPTIONAL]); - - INFO("ubus method|%s|, name|%s|, cmd [%s]", method, obj->name, trans_cmd); - - bbf_init(&data.bbf_ctx); - blob_buf_init(&data.bb, 0); - - data.ctx = ctx; - - if (is_str_eq(trans_cmd, "start")) { - ret = transaction_start(&data, "API", max_timeout); - if (ret) { - blobmsg_add_u8(&data.bb, "status", true); - blobmsg_add_u32(&data.bb, "transaction_id", ret); - } else { - blobmsg_add_u8(&data.bb, "status", false); - transaction_status(&data.bb); - } - } else if (is_str_eq(trans_cmd, "commit")) { - ret = transaction_commit(&data, data.trans_id, is_service_restart); - blobmsg_add_u8(&data.bb, "status", (ret == 0)); - } else if (is_str_eq(trans_cmd, "abort")) { - ret = transaction_abort(&data, data.trans_id); - blobmsg_add_u8(&data.bb, "status", (ret == 0)); - } else if (is_str_eq(trans_cmd, "status")) { - transaction_status(&data.bb); - } else { - WARNING("method(%s) not supported", method); - } ubus_send_reply(ctx, req, data.bb.head); blob_buf_free(&data.bb); - bbf_cleanup(&data.bbf_ctx); return 0; } @@ -1093,7 +929,6 @@ static struct ubus_method bbf_methods[] = { UBUS_METHOD("operate", bbfdm_operate_handler, dm_operate_policy), UBUS_METHOD("add", bbfdm_add_handler, dm_add_policy), UBUS_METHOD("del", bbfdm_del_handler, dm_del_policy), - UBUS_METHOD("transaction", bbfdm_transaction_handler, transaction_policy), UBUS_METHOD("service", bbfdm_service_handler, service_policy), UBUS_METHOD("notify_event", bbfdm_notify_event, dm_notify_event_policy), }; @@ -1125,25 +960,17 @@ static void run_schema_updater(struct bbfdm_context *u) } } -static void broadcast_add_del_event(const char *method, struct list_head *inst, bool is_add) +static void broadcast_add_del_event(struct ubus_context *ctx, const char *method, struct list_head *inst, bool is_add) { - struct ubus_context ctx; struct blob_buf bb; struct pathNode *ptr; char method_name[40]; void *a; - int ret; if (list_empty(inst)) { return; } - ret = ubus_connect_ctx(&ctx, NULL); - if (ret != UBUS_STATUS_OK) { - fprintf(stderr, "Failed to connect to ubus\n"); - return; - } - memset(&bb, 0, sizeof(struct blob_buf)); blob_buf_init(&bb, 0); @@ -1157,12 +984,11 @@ static void broadcast_add_del_event(const char *method, struct list_head *inst, snprintf(method_name, sizeof(method_name), "%s.%s", method, is_add ? BBF_ADD_EVENT : BBF_DEL_EVENT); if (is_add) - ubus_send_event(&ctx, method_name, bb.head); + ubus_send_event(ctx, method_name, bb.head); else - ubus_send_event(&ctx, method_name, bb.head); + ubus_send_event(ctx, method_name, bb.head); blob_buf_free(&bb); - ubus_shutdown(&ctx); } static void update_instances_list(struct list_head *inst) @@ -1172,7 +998,7 @@ static void update_instances_list(struct list_head *inst) .in_param = ROOT_NODE, .nextlevel = false, .disable_mservice_browse = true, - .dm_type = BBFDM_USP + .dm_type = BBFDM_BOTH }; bbf_init(&bbf_ctx); @@ -1182,6 +1008,9 @@ static void update_instances_list(struct list_head *inst) struct blob_attr *cur = NULL; size_t rem = 0; + // Apply all bbfdm changes + dmuci_commit_bbfdm(); + blobmsg_for_each_attr(cur, bbf_ctx.bb.head, rem) { struct blob_attr *tb[1] = {0}; const struct blobmsg_policy p[1] = { @@ -1201,26 +1030,6 @@ static void update_instances_list(struct list_head *inst) bbf_cleanup(&bbf_ctx); } -static void instance_fork_done(struct uloop_process *p, int ret) -{ - struct bbfdm_async_req *r = container_of(p, struct bbfdm_async_req, process); - - if (r) { - INFO("Instance updater(%d) completed, starting a new instance timer", r->process.pid); - struct bbfdm_context *u = (struct bbfdm_context *)r->result; - - if (u->config.refresh_time != 0) { - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, u->config.refresh_time); - } - free_path_list(&u->old_instances); - async_req_free(r); - } - if (ret) { - WARNING("Instance updater cb failed %d", ret); - } -} - static void instance_compare_publish(struct bbfdm_context *daemon_ctx) { struct pathNode *ptr; @@ -1237,7 +1046,7 @@ static void instance_compare_publish(struct bbfdm_context *daemon_ctx) add_path_list(ptr->path, &inst_list); } } - broadcast_add_del_event(method, &inst_list, false); + broadcast_add_del_event(&daemon_ctx->ubus_ctx, method, &inst_list, false); free_path_list(&inst_list); list_for_each_entry(ptr, new_inst, list) { @@ -1245,65 +1054,10 @@ static void instance_compare_publish(struct bbfdm_context *daemon_ctx) add_path_list(ptr->path, &inst_list); } } - broadcast_add_del_event(method, &inst_list, true); + broadcast_add_del_event(&daemon_ctx->ubus_ctx, method, &inst_list, true); free_path_list(&inst_list); } -static int fork_instance_checker(struct bbfdm_context *u) -{ - struct bbfdm_async_req *r = NULL; - pid_t child; - - r = async_req_new(); - if (r == NULL) { - ERR("Error allocating instance req"); - if (u->config.refresh_time != 0) { - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, u->config.refresh_time); - } - free_path_list(&u->old_instances); - goto err_out; - } - child = fork(); - if (child == 0) { - char inst_ser[32] = {0}; - - snprintf(inst_ser, sizeof(inst_ser), "dm_%s_in", u->config.service_name); - INFO("{%s::fork} Instances checker entry", inst_ser); - prctl(PR_SET_NAME, inst_ser, NULL, NULL, NULL); - // child initialise signal to prevent segfaults - signal_init(); - /* free fd's and memory inherited from parent */ - uloop_done(); - ubus_shutdown(&u->ubus_ctx); - async_req_free(r); - fclose(stdin); - fclose(stdout); - fclose(stderr); - - instance_compare_publish(u); - bbfdm_cleanup(u); - closelog(); - INFO("{fork} Instances checker exit"); - /* write result and exit */ - exit(EXIT_SUCCESS); - } - - // parent - INFO("# Creating instance checker process child %d", child); - r->result = u; - r->process.pid = child; - r->process.cb = instance_fork_done; - uloop_process_add(&r->process); - return 0; - -err_out: - if (r) - async_req_free(r); - - return UBUS_STATUS_UNKNOWN_ERROR; -} - static void periodic_instance_updater(struct uloop_timeout *t) { struct bbfdm_context *u; @@ -1314,43 +1068,23 @@ static void periodic_instance_updater(struct uloop_timeout *t) return; } - if (u->config.refresh_time == 0) { - return; // periodic refresh disabled - } - - if (is_transaction_running()) { - DEBUG("Transaction ongoing, schedule refresh timer after 1s"); - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, 1000); - return; - } - if (list_empty(&u->instances)) { if (!list_empty(&u->old_instances)) { list_splice_init(&u->old_instances, &u->instances); } else { update_instances_list(&u->instances); - DEBUG("Creating timer for instance update checker, init instances"); - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, u->config.refresh_time); return; } } free_path_list(&u->old_instances); list_splice_init(&u->instances, &u->old_instances); - update_instances_list(&u->instances); - if (list_empty(&u->instances)) { - update_instances_list(&u->instances); - WARNING("Failed to get current instances, restart the timer"); - u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, u->config.refresh_time); - return; - } - // fork a process and send it to compare, when process completes - // delete the old instances and add a new timer - fork_instance_checker(u); + update_instances_list(&u->instances); + if (!list_empty(&u->instances) && !list_empty(&u->old_instances)) { + INFO("Comparing instances ..."); + instance_compare_publish(u); + } } static bool register_service(struct ubus_context *ctx) @@ -1404,22 +1138,6 @@ static int _parse_daemon_config_options(bbfdm_config_t *config, json_object *dae set_debug_level(BBFDM_DEFAULT_DEBUG_LEVEL); } - opt_val = dmjson_get_value(daemon_obj, 2, "config", "refresh_time"); - if (DM_STRLEN(opt_val)) { - config->refresh_time = (unsigned int) strtoul(opt_val, NULL, 10) * 1000; - } else { - config->refresh_time = BBF_INSTANCES_UPDATE_TIMEOUT; - } - - opt_val = dmjson_get_value(daemon_obj, 2, "config", "transaction_timeout"); - if (DM_STRLEN(opt_val)) { - config->transaction_timeout = (int) strtol(opt_val, NULL, 10); - configure_transaction_timeout(config->transaction_timeout); - } else { - config->transaction_timeout = 30; - configure_transaction_timeout(30*1000); - } - opt_val = dmjson_get_value(daemon_obj, 2, "config", "subprocess_level"); if (DM_STRLEN(opt_val)) { config->subprocess_level = (unsigned int) strtoul(opt_val, NULL, 10); @@ -1672,7 +1390,6 @@ static void lookup_event_cb(struct ubus_context *ctx, void register_instance_refresh_timer(struct ubus_context *ctx, int start_in) { struct bbfdm_context *u; - unsigned refresh_time = 0; u = container_of(ctx, struct bbfdm_context, ubus_ctx); if (u == NULL) { @@ -1680,16 +1397,10 @@ void register_instance_refresh_timer(struct ubus_context *ctx, int start_in) return; } - if (start_in < 0) { - refresh_time = u->config.refresh_time; - } else { - refresh_time = start_in; - } - - if (u->config.refresh_time != 0) { - INFO("Register instance refresh timer in %d ms...", refresh_time); + if (start_in >= 0) { + INFO("Register instance refresh timer in %d ms...", start_in); u->instance_timer.cb = periodic_instance_updater; - uloop_timeout_set(&u->instance_timer, refresh_time); + uloop_timeout_set(&u->instance_timer, start_in); } } @@ -1704,9 +1415,7 @@ void cancel_instance_refresh_timer(struct ubus_context *ctx) } DEBUG("Cancelling Instance refresh timer"); - if (u->config.refresh_time != 0) { - uloop_timeout_cancel(&u->instance_timer); - } + uloop_timeout_cancel(&u->instance_timer); } static void bbf_config_change_cb(struct ubus_context *ctx, struct ubus_event_handler *ev, @@ -1719,8 +1428,10 @@ static void bbf_config_change_cb(struct ubus_context *ctx, struct ubus_event_han if (type && strcmp(type, "bbf.config.change") != 0) return; + INFO("Config updated, Scheduling instance refresh timers"); + cancel_instance_refresh_timer(ctx); - register_instance_refresh_timer(ctx, 100); + register_instance_refresh_timer(ctx, 0); } static void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx) diff --git a/bbfdmd/ubus/bbfdmd.h b/bbfdmd/ubus/bbfdmd.h index 62ff3aca..5e0154b9 100644 --- a/bbfdmd/ubus/bbfdmd.h +++ b/bbfdmd/ubus/bbfdmd.h @@ -19,7 +19,6 @@ struct bbfdm_async_req { typedef struct bbfdm_config { int proto; // Protocol identifier, Possible values: { '0', '1', '2' } - int transaction_timeout; // Timeout for transactions int subprocess_level; // Subprocess level uint8_t log_level; // Log level, Possible values: { '1', '2', '3', '4' } uint32_t refresh_time; // Refresh time @@ -62,7 +61,6 @@ typedef struct bbfdm_data { struct blob_buf bb; uint8_t depth; bool is_raw; - int trans_id; } bbfdm_data_t; void register_instance_refresh_timer(struct ubus_context *ctx, int start_sec); diff --git a/bbfdmd/ubus/cli.c b/bbfdmd/ubus/cli.c index 2f888571..34aa9c64 100644 --- a/bbfdmd/ubus/cli.c +++ b/bbfdmd/ubus/cli.c @@ -181,7 +181,7 @@ static int in_ubus_out_cli_exec_cmd(cli_data_t *cli_data, const char *path, cons if (value) blobmsg_add_string(&b, "value", value); table = blobmsg_open_table(&b, "optional"); - blobmsg_add_string(&b, "proto", (cli_data->proto == BBFDM_CWMP) ? "cwmp" : "usp"); + blobmsg_add_string(&b, "proto", (cli_data->proto == BBFDM_CWMP) ? "cwmp" : (cli_data->proto == BBFDM_USP) ? "usp" : "both"); blobmsg_add_string(&b, "format", "raw"); blobmsg_close_table(&b, table); @@ -280,6 +280,8 @@ static int in_dotso_out_cli_exec_get(cli_data_t *cli_data, char *argv[]) printf("%s => %s\n", name, data); } + + // Apply all bbfdm changes dmuci_commit_bbfdm(); } else { printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param); @@ -319,10 +321,10 @@ static int in_dotso_out_cli_exec_set(cli_data_t *cli_data, char *argv[]) err = bbf_entry_method(&cli_data->bbf_ctx, BBF_SET_VALUE); if (!err) { printf("%s => Set value is successfully done\n", cli_data->bbf_ctx.in_param); - bbf_entry_restart_services(NULL, true); + bbf_entry_services(cli_data->proto, true, true); } else { printf("Fault %d: %s\n", err, cli_data->bbf_ctx.fault_msg); - bbf_entry_revert_changes(NULL); + bbf_entry_services(cli_data->proto, false, true); err = EXIT_FAILURE; } @@ -357,10 +359,10 @@ static int in_dotso_out_cli_exec_add(cli_data_t *cli_data, char *argv[]) err = bbf_entry_method(&cli_data->bbf_ctx, BBF_ADD_OBJECT); if (!err) { printf("Added %s%s.\n", cli_data->bbf_ctx.in_param, cli_data->bbf_ctx.addobj_instance); - bbf_entry_restart_services(NULL, true); + bbf_entry_services(cli_data->proto, true, false); } else { printf("Fault %d: %s\n", err, cli_data->bbf_ctx.fault_msg); - bbf_entry_revert_changes(NULL); + bbf_entry_services(cli_data->proto, false, false); err = EXIT_FAILURE; } @@ -395,10 +397,10 @@ static int in_dotso_out_cli_exec_del(cli_data_t *cli_data, char *argv[]) err = bbf_entry_method(&cli_data->bbf_ctx, BBF_DEL_OBJECT); if (!err) { printf("Deleted %s\n", cli_data->bbf_ctx.in_param); - bbf_entry_restart_services(NULL, true); + bbf_entry_services(cli_data->proto, true, true); } else { printf("Fault %d: %s\n", err, cli_data->bbf_ctx.fault_msg); - bbf_entry_revert_changes(NULL); + bbf_entry_services(cli_data->proto, false, true); err = EXIT_FAILURE; } diff --git a/bbfdmd/ubus/get.c b/bbfdmd/ubus/get.c index e35561de..d8db2a68 100644 --- a/bbfdmd/ubus/get.c +++ b/bbfdmd/ubus/get.c @@ -880,6 +880,10 @@ void bbfdm_get_value(bbfdm_data_t *data, void *output) // free blob_buf_free(&data->bb); + + // Apply all bbfdm changes + dmuci_commit_bbfdm(); + bbf_cleanup(&data->bbf_ctx); } @@ -914,6 +918,9 @@ void bbfdm_get_names(bbfdm_data_t *data) if (data->ctx && data->req) ubus_send_reply(data->ctx, data->req, data->bbf_ctx.bb.head); + // Apply all bbfdm changes + dmuci_commit_bbfdm(); + bbf_cleanup(&data->bbf_ctx); } @@ -948,6 +955,9 @@ void bbfdm_get_instances(bbfdm_data_t *data) if (data->ctx && data->req) ubus_send_reply(data->ctx, data->req, data->bbf_ctx.bb.head); + // Apply all bbfdm changes + dmuci_commit_bbfdm(); + bbf_cleanup(&data->bbf_ctx); } diff --git a/bbfdmd/ubus/get_helper.c b/bbfdmd/ubus/get_helper.c index 6e3fbd26..4619778c 100644 --- a/bbfdmd/ubus/get_helper.c +++ b/bbfdmd/ubus/get_helper.c @@ -18,17 +18,8 @@ #include "common.h" #include "pretty_print.h" -extern struct list_head head_registered_service; - DMOBJ *DEAMON_DM_ROOT_OBJ = NULL; -static struct { - int trans_id; - struct uloop_timeout trans_timeout; - int timeout_ms; - char app[32]; -} g_current_trans = {.trans_id=0, .timeout_ms=10000}; - static jmp_buf gs_jump_location; static bool gs_jump_called_by_bbf = false; @@ -189,24 +180,6 @@ void fill_err_code_array(bbfdm_data_t *data, int fault) blobmsg_close_array(&data->bb, array); } -static void transaction_timeout_handler(struct uloop_timeout *t __attribute__((unused))) -{ - INFO("Transaction timeout called, aborting tid %d", g_current_trans.trans_id); - transaction_abort(NULL, g_current_trans.trans_id); -} - -static int get_random_id(void) -{ - int ret; - - srand(time(0)); - ret = rand(); - if (!ret) - ret = 1; - - return ret; -} - static int CountConsecutiveDigits(char *p) { char c; @@ -273,134 +246,6 @@ static int compare_path(const void *arg1, const void *arg2) return (int)c1 - (int)c2; } -// Returns transaction id if successful, otherwise 0 -int transaction_start(bbfdm_data_t *data, char *app, uint32_t max_timeout) -{ - int ret = 0; - uint32_t timeout; - - if (g_current_trans.trans_id) { - WARNING("%s Transaction locked by %s", app, g_current_trans.app); - return 0; - } - - if (max_timeout > 0) { - timeout = max_timeout; - } else { - timeout = g_current_trans.timeout_ms; - } - - ret = data->trans_id ? data->trans_id : get_random_id(); - strncpyt(g_current_trans.app, app, 32); - - g_current_trans.trans_id = ret; - g_current_trans.trans_timeout.cb = transaction_timeout_handler; - uloop_timeout_set(&g_current_trans.trans_timeout, timeout); - INFO("Transaction created by [%s] id %d, timeout %zd", g_current_trans.app, g_current_trans.trans_id, timeout); - - if (strcmp(app, "API") == 0) { - // Call transaction for registered services only if transaction id is defined - handle_transaction_of_registered_service(data->ctx, NULL, &head_registered_service, "start", ret, timeout, 0); - } - - return ret; -} - -int transaction_status(struct blob_buf *bb) -{ - if (g_current_trans.trans_id) { - int64_t rem = uloop_timeout_remaining64(&g_current_trans.trans_timeout); - blobmsg_add_string(bb, "app", g_current_trans.app); - blobmsg_add_string(bb, "tstatus", "running"); - blobmsg_add_u64(bb, "remaining_time", rem / 1000); - } else { - blobmsg_add_string(bb, "tstatus", "Idle"); - } - - return 0; -} - -bool is_transaction_running(void) -{ - return (g_current_trans.trans_id == 0 ? false : true); -} - -bool is_transaction_valid(int trans_id) -{ - if (trans_id == 0) - return false; - - return (trans_id == g_current_trans.trans_id); -} - -int transaction_commit(bbfdm_data_t *data, int trans_id, bool is_service_restart) -{ - int ret = -1; - - if (is_transaction_valid(trans_id)) { - struct blob_buf *bb = data ? &data->bb : NULL; - void *arr = NULL; - - INFO("Commit on-going transaction by %s", g_current_trans.app); - uloop_timeout_cancel(&g_current_trans.trans_timeout); - g_current_trans.trans_id = 0; - g_current_trans.app[0] = '\0'; - - if (bb) arr = blobmsg_open_array(bb, "updated_services"); - bbf_entry_restart_services(bb, is_service_restart); - if (data && data->trans_id) { - // Call transaction for registered services only if transaction id is defined - handle_transaction_of_registered_service(data->ctx, bb, &head_registered_service, "commit", data->trans_id, 0, is_service_restart); - } - if (bb) blobmsg_close_array(bb, arr); - - ret = 0; - } else { - WARNING("Transaction id mismatch(%d)", trans_id); - } - - return ret; -} - -int transaction_abort(bbfdm_data_t *data, int trans_id) -{ - int ret = -1; - - if (is_transaction_valid(trans_id)) { - struct blob_buf *bb = data ? &data->bb : NULL; - void *arr = NULL; - - INFO("Abort on-going transaction by %s", g_current_trans.app); - uloop_timeout_cancel(&g_current_trans.trans_timeout); - g_current_trans.trans_id = 0; - g_current_trans.app[0] = '\0'; - - if (bb) arr = blobmsg_open_array(bb, "updated_services"); - bbf_entry_revert_changes(bb); - if (data && data->trans_id) { - // Call transaction for registered services only if transaction id is defined - handle_transaction_of_registered_service(data->ctx, bb, &head_registered_service, "abort", data->trans_id, 0, 0); - } - if (bb) blobmsg_close_array(bb, arr); - - ret = 0; - } else { - WARNING("Transaction id mismatch(%d)", trans_id); - } - - return ret; -} - -int configure_transaction_timeout(int timeout) -{ - if (timeout <= 0) - return -1; - - g_current_trans.timeout_ms = timeout * 1000; - - return 0; -} - // Returns a pointer to the sorted array of PVs, memory need to be freed by caller struct pvNode *sort_pv_path(struct list_head *pv_list, size_t pv_count) { diff --git a/bbfdmd/ubus/get_helper.h b/bbfdmd/ubus/get_helper.h index 4eef1da0..f6c219dc 100644 --- a/bbfdmd/ubus/get_helper.h +++ b/bbfdmd/ubus/get_helper.h @@ -40,13 +40,6 @@ void fill_err_code_array(bbfdm_data_t *data, int fault); void bb_add_string(struct blob_buf *bb, const char *name, const char *value); -int transaction_start(bbfdm_data_t *data, char *app, uint32_t max_timeout); -int transaction_commit(bbfdm_data_t *data, int trans_id, bool is_service_restart); -int transaction_abort(bbfdm_data_t *data, int trans_id); -int transaction_status(struct blob_buf *bb); -bool is_transaction_running(void); -bool is_transaction_valid(int trans_id); -int configure_transaction_timeout(int timeout); struct pvNode *sort_pv_path(struct list_head *pv_list, size_t pv_count); #endif /* GET_HELPER_H */ diff --git a/docs/api/ubus/bbfdm.json b/docs/api/ubus/bbfdm.json index cb1dcd5d..e9c0f938 100644 --- a/docs/api/ubus/bbfdm.json +++ b/docs/api/ubus/bbfdm.json @@ -113,11 +113,6 @@ "raw", "pretty" ] - }, - "trans_id_t": { - "description": "Required for CUD operation, it shall be same number as got from transaction->start", - "type": "integer", - "minimum": 1 } }, "$schema": "http://json-schema.org/draft-07/schema#", @@ -406,8 +401,7 @@ "input": { "type": "object", "required": [ - "path", - "optional" + "path" ], "properties": { "path": { @@ -416,14 +410,6 @@ "obj_path": { "type": "object", "properties": {} - }, - "optional": { - "type": "object", - "properties": { - "transaction_id": { - "$ref": "#/definitions/trans_id_t" - } - } } } }, @@ -473,8 +459,7 @@ "input": { "type": "object", "required": [ - "path", - "transaction_id" + "path" ], "properties": { "path": { @@ -488,14 +473,6 @@ "$ref": "#/definitions/query_path_t" } ] - }, - "optional": { - "type": "object", - "properties": { - "transaction_id": { - "$ref": "#/definitions/trans_id_t" - } - } } } }, @@ -547,8 +524,7 @@ "type": "object", "required": [ "path", - "value", - "optional" + "value" ], "properties": { "path": { @@ -571,17 +547,6 @@ ], "type": "object", "properties": {} - }, - "optional": { - "type": "object", - "properties": { - "proto": { - "$ref": "#/definitions/proto_t" - }, - "transaction_id": { - "$ref": "#/definitions/trans_id_t" - } - } } } }, @@ -715,62 +680,6 @@ } } }, - "transaction": { - "title": "Start/commit/abort/status a transaction before set/add/del operations", - "type": "object", - "properties": { - "input": { - "type": "object", - "properties": { - "cmd": { - "$ref": "#/definitions/trans_type_t" - }, - "timeout": { - "type": "integer", - "description": "Timeout (in milliseconds) for the transaction, on timeout changes will be reverted", - "minimum":0 - }, - "restart_services": { - "description": "If yes, bbfdmd restart the service after CUD operation, else return list of updated uci to handler restart externally.", - "type": "boolean" - }, - "optional": { - "type": "object", - "properties": { - "transaction_id": { - "$ref": "#/definitions/trans_id_t" - } - } - } - }, - "required": [ - "cmd" - ] - }, - "output": { - "type": "object", - "properties": { - "status": { - "type": "boolean" - }, - "transaction_id": { - "type": "integer", - "minimum": 1 - }, - "error": { - "type": "string" - } - }, - "required": [ - "status" - ] - } - }, - "required": [ - "input", - "output" - ] - }, "service": { "title": "Register a micro-service in the main service", "type": "object", diff --git a/docs/api/ubus/bbfdm.md b/docs/api/ubus/bbfdm.md index 7b537e8f..ec1f7f22 100644 --- a/docs/api/ubus/bbfdm.md +++ b/docs/api/ubus/bbfdm.md @@ -21,7 +21,6 @@ https://dev.iopsys.eu/bbf/bbfdm/-/blob/devel/docs/api/ubus/bbfdm.md | [schema](#schema) | Method | bbf (this schema) | | [service](#service) | Method | bbf (this schema) | | [set](#set) | Method | bbf (this schema) | -| [transaction](#transaction) | Method | bbf (this schema) | ## add @@ -56,7 +55,6 @@ Add a new object in multi instance object | Property | Type | Required | | ---------- | ------ | ------------ | | `obj_path` | object | Optional | -| `optional` | object | **Required** | | `path` | string | **Required** | #### obj_path @@ -74,36 +72,6 @@ Add a new object in multi instance object | -------- | ---- | -------- | | None | None | None | -#### optional - -`optional` - -- is **required** -- type: `object` - -##### optional Type - -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ------- | -------- | -| `transaction_id` | integer | Optional | - -#### transaction_id - -Required for CUD operation, it shall be same number as got from transaction->start - -`transaction_id` - -- is optional -- type: reference - -##### transaction_id Type - -`integer` - -- minimum value: `1` - #### path Complete object element path as per TR181 @@ -141,7 +109,7 @@ Device.WiFi. ### Ubus CLI Example ``` -ubus call bbf add {"path":"dolore magna","optional":{"transaction_id":48031089},"obj_path":{}} +ubus call bbf add {"path":"voluptate veniam","obj_path":{}} ``` ### JSONRPC Example @@ -151,12 +119,7 @@ ubus call bbf add {"path":"dolore magna","optional":{"transaction_id":48031089}, "jsonrpc": "2.0", "id": 0, "method": "call", - "params": [ - "", - "bbf", - "add", - { "path": "dolore magna", "optional": { "transaction_id": 48031089 }, "obj_path": {} } - ] + "params": ["", "bbf", "add", { "path": "voluptate veniam", "obj_path": {} }] } ``` @@ -223,10 +186,10 @@ All items must be of the type: Unknown type ``. { "results": [ { - "path": "commodo oc", - "data": "reprehenderit amet culpa Excepteur", - "fault": 8107, - "fault_msg": "elit in ea ut non" + "path": "laborum", + "data": "occaecat tempor fugiat sit", + "fault": 9015, + "fault_msg": "cillum deserunt incididunt " } ] } @@ -262,41 +225,10 @@ Delete a object instance from multi instance object `object` with following properties: -| Property | Type | Required | -| ---------- | ------ | ------------ | -| `optional` | object | Optional | -| `path` | string | **Required** | -| `paths` | array | Optional | - -#### optional - -`optional` - -- is optional -- type: `object` - -##### optional Type - -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ------- | -------- | -| `transaction_id` | integer | Optional | - -#### transaction_id - -Required for CUD operation, it shall be same number as got from transaction->start - -`transaction_id` - -- is optional -- type: reference - -##### transaction_id Type - -`integer` - -- minimum value: `1` +| Property | Type | Required | +| -------- | ------ | ------------ | +| `path` | string | **Required** | +| `paths` | array | Optional | #### path @@ -361,7 +293,7 @@ All items must be of the type: Unknown type ``. ### Ubus CLI Example ``` -ubus call bbf del {"path":"non ipsu","paths":["dolor nisi amet veniam Duis"],"optional":{"transaction_id":85944852}} +ubus call bbf del {"path":"elit sit Ut magna","paths":["dolor irure"]} ``` ### JSONRPC Example @@ -371,12 +303,7 @@ ubus call bbf del {"path":"non ipsu","paths":["dolor nisi amet veniam Duis"],"op "jsonrpc": "2.0", "id": 0, "method": "call", - "params": [ - "", - "bbf", - "del", - { "path": "non ipsu", "paths": ["dolor nisi amet veniam Duis"], "optional": { "transaction_id": 85944852 } } - ] + "params": ["", "bbf", "del", { "path": "elit sit Ut magna", "paths": ["dolor irure"] }] } ``` @@ -440,7 +367,16 @@ All items must be of the type: Unknown type ``. ### Output Example ```json -{ "results": [{ "path": "cupidatat in", "data": "tempo", "fault": 7626, "fault_msg": "mollit dolore commodo" }] } +{ + "results": [ + { + "path": "fugiat consequat dolor culpa", + "data": "Lorem et veniam laboris nulla", + "fault": 8956, + "fault_msg": "dolor" + } + ] +} ``` ## get @@ -619,7 +555,7 @@ All items must be of the type: Unknown type ``. ### Ubus CLI Example ``` -ubus call bbf get {"path":"esseco","paths":["esttempor labore nisi cillum sint"],"maxdepth":-31080155,"optional":{"format":"pretty","proto":"cwmp"}} +ubus call bbf get {"path":"amet elit occaecat mag","paths":["in nisi"],"maxdepth":54340400,"optional":{"format":"pretty","proto":"both"}} ``` ### JSONRPC Example @@ -634,10 +570,10 @@ ubus call bbf get {"path":"esseco","paths":["esttempor labore nisi cillum sint"] "bbf", "get", { - "path": "esseco", - "paths": ["esttempor labore nisi cillum sint"], - "maxdepth": -31080155, - "optional": { "format": "pretty", "proto": "cwmp" } + "path": "amet elit occaecat mag", + "paths": ["in nisi"], + "maxdepth": 54340400, + "optional": { "format": "pretty", "proto": "both" } } ] } @@ -709,11 +645,11 @@ All items must be of the type: Unknown type ``. { "results": [ { - "path": "quisExcepteur ullamco magna non et", - "data": "dolor nisi ex eu ut", - "type": "xsd:unsignedLong", - "fault": 8725, - "fault_msg": "elit Lorem" + "path": "do laborum culpa ad", + "data": "anim minim sint pariatur", + "type": "xsd:object", + "fault": 8594, + "fault_msg": "con" } ] } @@ -846,7 +782,7 @@ Device.WiFi. ### Ubus CLI Example ``` -ubus call bbf instances {"path":"elitanim Lorem eiusmod ea","first_level":false,"optional":{"proto":"both"}} +ubus call bbf instances {"path":"in Lor","first_level":true,"optional":{"proto":"both"}} ``` ### JSONRPC Example @@ -856,12 +792,7 @@ ubus call bbf instances {"path":"elitanim Lorem eiusmod ea","first_level":false, "jsonrpc": "2.0", "id": 0, "method": "call", - "params": [ - "", - "bbf", - "instances", - { "path": "elitanim Lorem eiusmod ea", "first_level": false, "optional": { "proto": "both" } } - ] + "params": ["", "bbf", "instances", { "path": "in Lor", "first_level": true, "optional": { "proto": "both" } }] } ``` @@ -922,11 +853,7 @@ All items must be of the type: Unknown type ``. ### Output Example ```json -{ - "results": [ - { "path": "fugiat reprehenderit sunt aliqua est", "fault": 7511, "fault_msg": "Duis ut labore proident" } - ] -} +{ "results": [{ "path": "in eiusmod dolore mollit", "fault": 8737, "fault_msg": "eu dolore ipsum" }] } ``` ## notify_event @@ -991,7 +918,7 @@ All items must be of the type: Unknown type ``. ### Ubus CLI Example ``` -ubus call bbf notify_event {"name":"dolore voluptate minim","input":{}} +ubus call bbf notify_event {"name":"","input":{}} ``` ### JSONRPC Example @@ -1001,7 +928,7 @@ ubus call bbf notify_event {"name":"dolore voluptate minim","input":{}} "jsonrpc": "2.0", "id": 0, "method": "call", - "params": ["", "bbf", "notify_event", { "name": "dolore voluptate minim", "input": {} }] + "params": ["", "bbf", "notify_event", { "name": "", "input": {} }] } ``` @@ -1101,14 +1028,9 @@ Unknown type ``. "type": "string", "default": "pretty", "enum": ["raw", "pretty"] - }, - "trans_id_t": { - "description": "Required for CUD operation, it shall be same number as got from transaction->start", - "type": "integer", - "minimum": 1 } }, - "out": "{\"definitions\":{\"path_t\":{\"description\":\"Complete object element path as per TR181\",\"type\":\"string\",\"minLength\":6,\"maxLength\":1024,\"examples\":[\"Device.\",\"Device.DeviceInfo.Manufacturer\",\"Device.WiFi.SSID.1.\",\"Device.WiFi.\"]},\"schema_path_t\":{\"description\":\"Datamodel object schema path\",\"type\":\"string\",\"minLength\":6,\"maxLength\":1024,\"examples\":[\"Device.Bridging.Bridge.{i}.\",\"Device.DeviceInfo.Manufacturer\",\"Device.WiFi.SSID.{i}.SSID\"]},\"boolean_t\":{\"type\":\"string\",\"enum\":[\"0\",\"1\"]},\"operate_path_t\":{\"description\":\"Datamodel object schema path\",\"type\":\"string\",\"minLength\":6,\"maxLength\":1024,\"examples\":[\"Device.IP.Diagnostics.IPPing()\",\"Device.DHCPv4.Client.{i}.Renew()\",\"Device.FactoryReset()\"]},\"query_path_t\":{\"description\":\"DM object path with search queries\",\"type\":\"string\",\"minLength\":6,\"maxLength\":1024,\"examples\":[\"Device.\",\"Device.DeviceInfo.Manufacturer\",\"Device.WiFi.SSID.1.BSSID\",\"Device.WiFi.SSID.*.BSSID\",\"Device.WiFi.\"]},\"instance_t\":{\"description\":\"Multi object instances\",\"type\":\"string\",\"minLength\":6,\"maxLength\":256},\"proto_t\":{\"type\":\"string\",\"default\":\"both\",\"enum\":[\"usp\",\"cwmp\",\"both\"]},\"type_t\":{\"type\":\"string\",\"enum\":[\"xsd:string\",\"xsd:unsignedInt\",\"xsd:int\",\"xsd:unsignedLong\",\"xsd:long\",\"xsd:boolean\",\"xsd:dateTime\",\"xsd:hexBinary\",\"xsd:object\",\"xsd:command\",\"xsd:event\"]},\"fault_t\":{\"type\":\"integer\",\"minimum\":7000,\"maximum\":9050},\"trans_type_t\":{\"type\":\"string\",\"enum\":[\"start\",\"commit\",\"abort\",\"status\"]},\"srv_type_t\":{\"type\":\"string\",\"enum\":[\"register\",\"list\"]},\"format_t\":{\"type\":\"string\",\"default\":\"pretty\",\"enum\":[\"raw\",\"pretty\"]},\"trans_id_t\":{\"description\":\"Required for CUD operation, it shall be same number as got from transaction->start\",\"type\":\"integer\",\"minimum\":1}}}", + "out": "{\"definitions\":{\"path_t\":{\"description\":\"Complete object element path as per TR181\",\"type\":\"string\",\"minLength\":6,\"maxLength\":1024,\"examples\":[\"Device.\",\"Device.DeviceInfo.Manufacturer\",\"Device.WiFi.SSID.1.\",\"Device.WiFi.\"]},\"schema_path_t\":{\"description\":\"Datamodel object schema path\",\"type\":\"string\",\"minLength\":6,\"maxLength\":1024,\"examples\":[\"Device.Bridging.Bridge.{i}.\",\"Device.DeviceInfo.Manufacturer\",\"Device.WiFi.SSID.{i}.SSID\"]},\"boolean_t\":{\"type\":\"string\",\"enum\":[\"0\",\"1\"]},\"operate_path_t\":{\"description\":\"Datamodel object schema path\",\"type\":\"string\",\"minLength\":6,\"maxLength\":1024,\"examples\":[\"Device.IP.Diagnostics.IPPing()\",\"Device.DHCPv4.Client.{i}.Renew()\",\"Device.FactoryReset()\"]},\"query_path_t\":{\"description\":\"DM object path with search queries\",\"type\":\"string\",\"minLength\":6,\"maxLength\":1024,\"examples\":[\"Device.\",\"Device.DeviceInfo.Manufacturer\",\"Device.WiFi.SSID.1.BSSID\",\"Device.WiFi.SSID.*.BSSID\",\"Device.WiFi.\"]},\"instance_t\":{\"description\":\"Multi object instances\",\"type\":\"string\",\"minLength\":6,\"maxLength\":256},\"proto_t\":{\"type\":\"string\",\"default\":\"both\",\"enum\":[\"usp\",\"cwmp\",\"both\"]},\"type_t\":{\"type\":\"string\",\"enum\":[\"xsd:string\",\"xsd:unsignedInt\",\"xsd:int\",\"xsd:unsignedLong\",\"xsd:long\",\"xsd:boolean\",\"xsd:dateTime\",\"xsd:hexBinary\",\"xsd:object\",\"xsd:command\",\"xsd:event\"]},\"fault_t\":{\"type\":\"integer\",\"minimum\":7000,\"maximum\":9050},\"trans_type_t\":{\"type\":\"string\",\"enum\":[\"start\",\"commit\",\"abort\",\"status\"]},\"srv_type_t\":{\"type\":\"string\",\"enum\":[\"register\",\"list\"]},\"format_t\":{\"type\":\"string\",\"default\":\"pretty\",\"enum\":[\"raw\",\"pretty\"]}}}", "simpletype": "complex" } ``` @@ -1174,12 +1096,7 @@ Unknown type ``. "fault_t": { "type": "integer", "minimum": 7000, "maximum": 9050 }, "trans_type_t": { "type": "string", "enum": ["start", "commit", "abort", "status"] }, "srv_type_t": { "type": "string", "enum": ["register", "list"] }, - "format_t": { "type": "string", "default": "pretty", "enum": ["raw", "pretty"] }, - "trans_id_t": { - "description": "Required for CUD operation, it shall be same number as got from transaction->start", - "type": "integer", - "minimum": 1 - } + "format_t": { "type": "string", "default": "pretty", "enum": ["raw", "pretty"] } } } ``` @@ -1347,7 +1264,7 @@ The value of this property **must** be equal to one of the [known values below]( ### Ubus CLI Example ``` -ubus call bbf operate {"command":"minim enim au","command_key":"proident adipisicing enim ullamco","input":{},"optional":{"format":"pretty","proto":"cwmp"}} +ubus call bbf operate {"command":"minim tempor dolor ut","command_key":"cillum elit","input":{},"optional":{"format":"raw","proto":"both"}} ``` ### JSONRPC Example @@ -1362,10 +1279,10 @@ ubus call bbf operate {"command":"minim enim au","command_key":"proident adipisi "bbf", "operate", { - "command": "minim enim au", - "command_key": "proident adipisicing enim ullamco", + "command": "minim tempor dolor ut", + "command_key": "cillum elit", "input": {}, - "optional": { "format": "pretty", "proto": "cwmp" } + "optional": { "format": "raw", "proto": "both" } } ] } @@ -1453,11 +1370,11 @@ All items must be of the type: Unknown type ``. { "results": [ { - "path": "quis dolor occaecat tempor", - "data": "1", - "fault": 8348, - "fault_msg": "aliqua dolore ad eu id", - "output": [{ "path": "sit esse dolor", "data": "1", "type": "xsd:command" }] + "path": "sit dolor dolore Lorem eiusmod", + "data": "0", + "fault": 8955, + "fault_msg": "elit occaecat tempor", + "output": [{ "path": "in qui cillum", "data": "0", "type": "xsd:int" }] } ] } @@ -1659,7 +1576,7 @@ All items must be of the type: Unknown type ``. ### Ubus CLI Example ``` -ubus call bbf schema {"path":"ut nisi Duis aliqua","paths":["anim aliqua in ipsum mollit"],"first_level":true,"commands":true,"events":false,"params":true,"optional":{"proto":"both"}} +ubus call bbf schema {"path":"velit aliquip","paths":["volupta"],"first_level":true,"commands":false,"events":true,"params":true,"optional":{"proto":"cwmp"}} ``` ### JSONRPC Example @@ -1674,13 +1591,13 @@ ubus call bbf schema {"path":"ut nisi Duis aliqua","paths":["anim aliqua in ipsu "bbf", "schema", { - "path": "ut nisi Duis aliqua", - "paths": ["anim aliqua in ipsum mollit"], + "path": "velit aliquip", + "paths": ["volupta"], "first_level": true, - "commands": true, - "events": false, + "commands": false, + "events": true, "params": true, - "optional": { "proto": "both" } + "optional": { "proto": "cwmp" } } ] } @@ -1790,13 +1707,13 @@ All items must be of the type: Unknown type ``. { "results": [ { - "path": "laboris", - "data": "1", - "type": "xsd:int", - "fault": 8767, - "fault_msg": "cupidatat amet", - "input": [{ "path": "quiselit ad", "data": "0", "type": "xsd:hexBinary" }], - "output": [{ "path": "ipsum do Lorem nulla officia", "data": "0", "type": "xsd:unsignedLong" }] + "path": "aliquip nisi ven", + "data": "0", + "type": "xsd:object", + "fault": 8719, + "fault_msg": "mollit", + "input": [{ "path": "tempor Ut consectetu", "data": "1", "type": "xsd:long" }], + "output": [{ "path": "velit ipsum e", "data": "1", "type": "xsd:dateTime" }] } ] } @@ -1899,7 +1816,7 @@ Object path where the micro-service object will be added ### Ubus CLI Example ``` -ubus call bbf service {"cmd":"register","name":"ea","parent_dm":"Ut labore in","object":"Duis commodo"} +ubus call bbf service {"cmd":"register","name":"sit dolore et qui in","parent_dm":"reprehenderit pariatur Excepteur","object":"enim non ex in"} ``` ### JSONRPC Example @@ -1913,7 +1830,12 @@ ubus call bbf service {"cmd":"register","name":"ea","parent_dm":"Ut labore in"," "", "bbf", "service", - { "cmd": "register", "name": "ea", "parent_dm": "Ut labore in", "object": "Duis commodo" } + { + "cmd": "register", + "name": "sit dolore et qui in", + "parent_dm": "reprehenderit pariatur Excepteur", + "object": "enim non ex in" + } ] } ``` @@ -1959,7 +1881,7 @@ ubus call bbf service {"cmd":"register","name":"ea","parent_dm":"Ut labore in"," ### Output Example ```json -{ "status": true, "error": "tempor consectetur minim id anim" } +{ "status": false, "error": "magna nostrud Lorem" } ``` ## set @@ -1995,7 +1917,6 @@ Set values of datamodel object element | Property | Type | Required | | ---------- | ------ | ------------ | | `obj_path` | object | Optional | -| `optional` | object | **Required** | | `path` | string | **Required** | | `value` | string | **Required** | @@ -2026,59 +1947,6 @@ To set multiple values at once, path should be relative to object elements { "path": "Device.WiFi.SSID.2.", "obj_path": { "SSID": "test_ssid" } } ``` -#### optional - -`optional` - -- is **required** -- type: `object` - -##### optional Type - -`object` with following properties: - -| Property | Type | Required | Default | -| ---------------- | ------- | -------- | -------- | -| `proto` | string | Optional | `"both"` | -| `transaction_id` | integer | Optional | | - -#### proto - -`proto` - -- is optional -- type: reference -- default: `"both"` - -##### proto Type - -`string` - -The value of this property **must** be equal to one of the [known values below](#set-known-values). - -##### proto Known Values - -| Value | -| ----- | -| usp | -| cwmp | -| both | - -#### transaction_id - -Required for CUD operation, it shall be same number as got from transaction->start - -`transaction_id` - -- is optional -- type: reference - -##### transaction_id Type - -`integer` - -- minimum value: `1` - #### path DM object path with search queries @@ -2147,7 +2015,7 @@ value of the object element provided in path, path should contains valid writabl ### Ubus CLI Example ``` -ubus call bbf set {"path":"amet aute laboris irure ad","value":"est dolore","optional":{"proto":"usp","transaction_id":79839602},"obj_path":{}} +ubus call bbf set {"path":"aliqua","value":"ullamco eu adipisicing tempor","obj_path":{}} ``` ### JSONRPC Example @@ -2157,17 +2025,7 @@ ubus call bbf set {"path":"amet aute laboris irure ad","value":"est dolore","opt "jsonrpc": "2.0", "id": 0, "method": "call", - "params": [ - "", - "bbf", - "set", - { - "path": "amet aute laboris irure ad", - "value": "est dolore", - "optional": { "proto": "usp", "transaction_id": 79839602 }, - "obj_path": {} - } - ] + "params": ["", "bbf", "set", { "path": "aliqua", "value": "ullamco eu adipisicing tempor", "obj_path": {} }] } ``` @@ -2231,200 +2089,5 @@ All items must be of the type: Unknown type ``. ### Output Example ```json -{ "results": [{ "path": "eiusmod tempor dolore", "data": "1", "fault": 7804, "fault_msg": "amet commodo id tempor" }] } -``` - -## transaction - -### Start/commit/abort/status a transaction before set/add/del operations - -`transaction` - -- type: `Method` - -### transaction Type - -`object` with following properties: - -| Property | Type | Required | -| -------- | ------ | ------------ | -| `input` | object | **Required** | -| `output` | object | **Required** | - -#### input - -`input` - -- is **required** -- type: `object` - -##### input Type - -`object` with following properties: - -| Property | Type | Required | -| ------------------ | ------- | ------------ | -| `cmd` | string | **Required** | -| `optional` | object | Optional | -| `restart_services` | boolean | Optional | -| `timeout` | integer | Optional | - -#### cmd - -`cmd` - -- is **required** -- type: reference - -##### cmd Type - -`string` - -The value of this property **must** be equal to one of the [known values below](#transaction-known-values). - -##### cmd Known Values - -| Value | -| ------ | -| start | -| commit | -| abort | -| status | - -#### optional - -`optional` - -- is optional -- type: `object` - -##### optional Type - -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ------- | -------- | -| `transaction_id` | integer | Optional | - -#### transaction_id - -Required for CUD operation, it shall be same number as got from transaction->start - -`transaction_id` - -- is optional -- type: reference - -##### transaction_id Type - -`integer` - -- minimum value: `1` - -#### restart_services - -If yes, bbfdmd restart the service after CUD operation, else return list of updated uci to handler restart externally. - -`restart_services` - -- is optional -- type: `boolean` - -##### restart_services Type - -`boolean` - -#### timeout - -Timeout (in milliseconds) for the transaction, on timeout changes will be reverted - -`timeout` - -- is optional -- type: `integer` - -##### timeout Type - -`integer` - -- minimum value: `0` - -### Ubus CLI Example - -``` -ubus call bbf transaction {"cmd":"commit","timeout":98560738,"restart_services":false,"optional":{"transaction_id":36502520}} -``` - -### JSONRPC Example - -```json -{ - "jsonrpc": "2.0", - "id": 0, - "method": "call", - "params": [ - "", - "bbf", - "transaction", - { "cmd": "commit", "timeout": 98560738, "restart_services": false, "optional": { "transaction_id": 36502520 } } - ] -} -``` - -#### output - -`output` - -- is **required** -- type: `object` - -##### output Type - -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ------- | ------------ | -| `error` | string | Optional | -| `status` | boolean | **Required** | -| `transaction_id` | integer | Optional | - -#### error - -`error` - -- is optional -- type: `string` - -##### error Type - -`string` - -#### status - -`status` - -- is **required** -- type: `boolean` - -##### status Type - -`boolean` - -#### transaction_id - -`transaction_id` - -- is optional -- type: `integer` - -##### transaction_id Type - -`integer` - -- minimum value: `1` - -### Output Example - -```json -{ "status": true, "transaction_id": 33849248, "error": "Duis nostrud amet enim" } +{ "results": [{ "path": "ea sed Ut aute", "data": "0", "fault": 7846, "fault_msg": "magna veniam eu fugiat id" }] } ``` diff --git a/docs/api/ubus/bbfdm_micro_service.json b/docs/api/ubus/bbfdm_micro_service.json index 88ac2234..ae9b8a2c 100644 --- a/docs/api/ubus/bbfdm_micro_service.json +++ b/docs/api/ubus/bbfdm_micro_service.json @@ -113,11 +113,6 @@ "raw", "pretty" ] - }, - "trans_id_t": { - "description": "Required for CUD operation, it shall be same number as got from transaction->start", - "type": "integer", - "minimum": 1 } }, "$schema": "http://json-schema.org/draft-07/schema#", @@ -406,8 +401,7 @@ "input": { "type": "object", "required": [ - "path", - "optional" + "path" ], "properties": { "path": { @@ -416,14 +410,6 @@ "obj_path": { "type": "object", "properties": {} - }, - "optional": { - "type": "object", - "properties": { - "transaction_id": { - "$ref": "#/definitions/trans_id_t" - } - } } } }, @@ -473,8 +459,7 @@ "input": { "type": "object", "required": [ - "path", - "transaction_id" + "path" ], "properties": { "path": { @@ -488,14 +473,6 @@ "$ref": "#/definitions/query_path_t" } ] - }, - "optional": { - "type": "object", - "properties": { - "transaction_id": { - "$ref": "#/definitions/trans_id_t" - } - } } } }, @@ -547,8 +524,7 @@ "type": "object", "required": [ "path", - "value", - "optional" + "value" ], "properties": { "path": { @@ -571,17 +547,6 @@ ], "type": "object", "properties": {} - }, - "optional": { - "type": "object", - "properties": { - "proto": { - "$ref": "#/definitions/proto_t" - }, - "transaction_id": { - "$ref": "#/definitions/trans_id_t" - } - } } } }, @@ -714,62 +679,6 @@ } } } - }, - "transaction": { - "title": "Start/commit/abort/status a transaction before set/add/del operations", - "type": "object", - "properties": { - "input": { - "type": "object", - "properties": { - "cmd": { - "$ref": "#/definitions/trans_type_t" - }, - "timeout": { - "type": "integer", - "description": "Timeout (in milliseconds) for the transaction, on timeout changes will be reverted", - "minimum":0 - }, - "restart_services": { - "description": "If yes, bbfdmd restart the service after CUD operation, else return list of updated uci to handler restart externally.", - "type": "boolean" - }, - "optional": { - "type": "object", - "properties": { - "transaction_id": { - "$ref": "#/definitions/trans_id_t" - } - } - } - }, - "required": [ - "cmd" - ] - }, - "output": { - "type": "object", - "properties": { - "status": { - "type": "boolean" - }, - "transaction_id": { - "type": "integer", - "minimum": 1 - }, - "error": { - "type": "string" - } - }, - "required": [ - "status" - ] - } - }, - "required": [ - "input", - "output" - ] } } } diff --git a/docs/api/ubus/bbfdm_micro_service.md b/docs/api/ubus/bbfdm_micro_service.md index fb3ef598..4c3abb41 100644 --- a/docs/api/ubus/bbfdm_micro_service.md +++ b/docs/api/ubus/bbfdm_micro_service.md @@ -10,16 +10,15 @@ https://dev.iopsys.eu/bbf/bbfdm/-/blob/devel/docs/api/ubus/bbfdm.md # bbf -| List of Methods | -| --------------------------- | -| [add](#add) | Method | bbf (this schema) | -| [del](#del) | Method | bbf (this schema) | -| [get](#get) | Method | bbf (this schema) | -| [instances](#instances) | Method | bbf (this schema) | -| [operate](#operate) | Method | bbf (this schema) | -| [schema](#schema) | Method | bbf (this schema) | -| [set](#set) | Method | bbf (this schema) | -| [transaction](#transaction) | Method | bbf (this schema) | +| List of Methods | +| ----------------------- | +| [add](#add) | Method | bbf (this schema) | +| [del](#del) | Method | bbf (this schema) | +| [get](#get) | Method | bbf (this schema) | +| [instances](#instances) | Method | bbf (this schema) | +| [operate](#operate) | Method | bbf (this schema) | +| [schema](#schema) | Method | bbf (this schema) | +| [set](#set) | Method | bbf (this schema) | ## add @@ -54,7 +53,6 @@ Add a new object in multi instance object | Property | Type | Required | | ---------- | ------ | ------------ | | `obj_path` | object | Optional | -| `optional` | object | **Required** | | `path` | string | **Required** | #### obj_path @@ -72,36 +70,6 @@ Add a new object in multi instance object | -------- | ---- | -------- | | None | None | None | -#### optional - -`optional` - -- is **required** -- type: `object` - -##### optional Type - -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ------- | -------- | -| `transaction_id` | integer | Optional | - -#### transaction_id - -Required for CUD operation, it shall be same number as got from transaction->start - -`transaction_id` - -- is optional -- type: reference - -##### transaction_id Type - -`integer` - -- minimum value: `1` - #### path Complete object element path as per TR181 @@ -139,7 +107,7 @@ Device.WiFi. ### Ubus CLI Example ``` -ubus call bbf add {"path":"labore ullamco","optional":{"transaction_id":3482835},"obj_path":{}} +ubus call bbf add {"path":"tempor nostrud in i","obj_path":{}} ``` ### JSONRPC Example @@ -149,12 +117,7 @@ ubus call bbf add {"path":"labore ullamco","optional":{"transaction_id":3482835} "jsonrpc": "2.0", "id": 0, "method": "call", - "params": [ - "", - "bbf", - "add", - { "path": "labore ullamco", "optional": { "transaction_id": 3482835 }, "obj_path": {} } - ] + "params": ["", "bbf", "add", { "path": "tempor nostrud in i", "obj_path": {} }] } ``` @@ -218,16 +181,7 @@ All items must be of the type: Unknown type ``. ### Output Example ```json -{ - "results": [ - { - "path": "tempor consequat dolor", - "data": "in aliquip", - "fault": 7759, - "fault_msg": "ea irure sunt laboris commodo" - } - ] -} +{ "results": [{ "path": "laborum", "data": "mollit enim", "fault": 8110, "fault_msg": "culpa fugiat" }] } ``` ## del @@ -260,41 +214,10 @@ Delete a object instance from multi instance object `object` with following properties: -| Property | Type | Required | -| ---------- | ------ | ------------ | -| `optional` | object | Optional | -| `path` | string | **Required** | -| `paths` | array | Optional | - -#### optional - -`optional` - -- is optional -- type: `object` - -##### optional Type - -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ------- | -------- | -| `transaction_id` | integer | Optional | - -#### transaction_id - -Required for CUD operation, it shall be same number as got from transaction->start - -`transaction_id` - -- is optional -- type: reference - -##### transaction_id Type - -`integer` - -- minimum value: `1` +| Property | Type | Required | +| -------- | ------ | ------------ | +| `path` | string | **Required** | +| `paths` | array | Optional | #### path @@ -359,7 +282,7 @@ All items must be of the type: Unknown type ``. ### Ubus CLI Example ``` -ubus call bbf del {"path":"laborum","paths":["aliquip ea"],"optional":{"transaction_id":37938814}} +ubus call bbf del {"path":"culpasunt","paths":["deserunt labore ut consequa"]} ``` ### JSONRPC Example @@ -369,12 +292,7 @@ ubus call bbf del {"path":"laborum","paths":["aliquip ea"],"optional":{"transact "jsonrpc": "2.0", "id": 0, "method": "call", - "params": [ - "", - "bbf", - "del", - { "path": "laborum", "paths": ["aliquip ea"], "optional": { "transaction_id": 37938814 } } - ] + "params": ["", "bbf", "del", { "path": "culpasunt", "paths": ["deserunt labore ut consequa"] }] } ``` @@ -438,11 +356,7 @@ All items must be of the type: Unknown type ``. ### Output Example ```json -{ - "results": [ - { "path": "proident eiusmod et Lorem", "data": "ullamco sed", "fault": 8168, "fault_msg": "sint quis nostrud est" } - ] -} +{ "results": [{ "path": "dolor laborum esse", "data": "laborum amet Excepteur", "fault": 8595, "fault_msg": "ut" }] } ``` ## get @@ -506,10 +420,10 @@ Integer to decide the depth of data model to be parsed `object` with following properties: -| Property | Type | Required | Default | -| --------------- | ------- | -------- | ---------- | -| `format` | string | Optional | `"pretty"` | -| `proto` | string | Optional | `"both"` | +| Property | Type | Required | Default | +| -------- | ------ | -------- | ---------- | +| `format` | string | Optional | `"pretty"` | +| `proto` | string | Optional | `"both"` | #### format @@ -621,7 +535,7 @@ All items must be of the type: Unknown type ``. ### Ubus CLI Example ``` -ubus call bbf get {"path":"officia","paths":["aliqua nisi sunt"],"maxdepth":-49153948,"optional":{"format":"raw","proto":"cwmp"}} +ubus call bbf get {"path":"officia","paths":["reprehenderit Ut"],"maxdepth":-61996452,"optional":{"format":"pretty","proto":"both"}} ``` ### JSONRPC Example @@ -637,9 +551,9 @@ ubus call bbf get {"path":"officia","paths":["aliqua nisi sunt"],"maxdepth":-491 "get", { "path": "officia", - "paths": ["aliqua nisi sunt"], - "maxdepth": -49153948, - "optional": { "format": "raw", "proto": "cwmp" } + "paths": ["reprehenderit Ut"], + "maxdepth": -61996452, + "optional": { "format": "pretty", "proto": "both" } } ] } @@ -710,13 +624,7 @@ All items must be of the type: Unknown type ``. ```json { "results": [ - { - "path": "anim sit aute non mollit", - "data": "sed consectetur ipsum exercitation magna", - "type": "xsd:string", - "fault": 8050, - "fault_msg": "nostrud nisi laboris exercitation" - } + { "path": "proident", "data": "consectetur", "type": "xsd:unsignedLong", "fault": 8751, "fault_msg": "culpa ea" } ] } ``` @@ -781,9 +689,9 @@ gets only first level objects if true `object` with following properties: -| Property | Type | Required | Default | -| --------------- | ------- | -------- | -------- | -| `proto` | string | Optional | `"both"` | +| Property | Type | Required | Default | +| -------- | ------ | -------- | -------- | +| `proto` | string | Optional | `"both"` | #### proto @@ -848,7 +756,7 @@ Device.WiFi. ### Ubus CLI Example ``` -ubus call bbf instances {"path":"id aliquip","first_level":false,"optional":{"proto":"usp"}} +ubus call bbf instances {"path":"et elit officia ut","first_level":false,"optional":{"proto":"both"}} ``` ### JSONRPC Example @@ -862,7 +770,7 @@ ubus call bbf instances {"path":"id aliquip","first_level":false,"optional":{"pr "", "bbf", "instances", - { "path": "id aliquip", "first_level": false, "optional": { "proto": "usp" } } + { "path": "et elit officia ut", "first_level": false, "optional": { "proto": "both" } } ] } ``` @@ -924,7 +832,7 @@ All items must be of the type: Unknown type ``. ### Output Example ```json -{ "results": [{ "path": "ad qui ", "fault": 7181, "fault_msg": "elit" }] } +{ "results": [{ "path": "est do aliqua dolor", "fault": 7913, "fault_msg": "enim ex ipsum tempor elit" }] } ``` ## operate @@ -1039,10 +947,10 @@ Input arguments for the operate command as defined in TR-181-2.13 `object` with following properties: -| Property | Type | Required | Default | -| --------------- | ------- | -------- | ---------- | -| `format` | string | Optional | `"pretty"` | -| `proto` | string | Optional | `"both"` | +| Property | Type | Required | Default | +| -------- | ------ | -------- | ---------- | +| `format` | string | Optional | `"pretty"` | +| `proto` | string | Optional | `"both"` | #### format @@ -1090,7 +998,7 @@ The value of this property **must** be equal to one of the [known values below]( ### Ubus CLI Example ``` -ubus call bbf operate {"command":"et sit dolor","command_key":"nulla velit ut in Excepteur","input":{},"optional":{"format":"raw","proto":"both"}} +ubus call bbf operate {"command":"irure reprehen","command_key":"tempor ipsum","input":{},"optional":{"format":"raw","proto":"usp"}} ``` ### JSONRPC Example @@ -1105,10 +1013,10 @@ ubus call bbf operate {"command":"et sit dolor","command_key":"nulla velit ut in "bbf", "operate", { - "command": "et sit dolor", - "command_key": "nulla velit ut in Excepteur", + "command": "irure reprehen", + "command_key": "tempor ipsum", "input": {}, - "optional": { "format": "raw", "proto": "both" } + "optional": { "format": "raw", "proto": "usp" } } ] } @@ -1196,11 +1104,11 @@ All items must be of the type: Unknown type ``. { "results": [ { - "path": "aliqua", - "data": "0", - "fault": 7611, - "fault_msg": "ea occaecat voluptate tempor", - "output": [{ "path": "consequat dolor elit", "data": "1", "type": "xsd:int" }] + "path": "ea Lorem officia n", + "data": "1", + "fault": 8207, + "fault_msg": "in Duis eiusmod culpa", + "output": [{ "path": "eiusmod voluptate", "data": "1", "type": "xsd:command" }] } ] } @@ -1402,7 +1310,7 @@ All items must be of the type: Unknown type ``. ### Ubus CLI Example ``` -ubus call bbf schema {"path":"laboris elit in dolore ali","paths":["pariatur elit eu"],"first_level":false,"commands":false,"events":false,"params":false,"optional":{"proto":"usp"}} +ubus call bbf schema {"path":"sit Lorem aliquip quis adipisic","paths":["cupidatat Excepteur"],"first_level":true,"commands":true,"events":false,"params":true,"optional":{"proto":"both"}} ``` ### JSONRPC Example @@ -1417,13 +1325,13 @@ ubus call bbf schema {"path":"laboris elit in dolore ali","paths":["pariatur eli "bbf", "schema", { - "path": "laboris elit in dolore ali", - "paths": ["pariatur elit eu"], - "first_level": false, - "commands": false, + "path": "sit Lorem aliquip quis adipisic", + "paths": ["cupidatat Excepteur"], + "first_level": true, + "commands": true, "events": false, - "params": false, - "optional": { "proto": "usp" } + "params": true, + "optional": { "proto": "both" } } ] } @@ -1533,13 +1441,13 @@ All items must be of the type: Unknown type ``. { "results": [ { - "path": "Excepteur irure consequat", + "path": "veniam ipsum ea elit lab", "data": "0", - "type": "xsd:dateTime", - "fault": 7546, - "fault_msg": "cupidatat Excepteur", - "input": [{ "path": "minim pariatur id laboris ut", "data": "1", "type": "xsd:unsignedInt" }], - "output": [{ "path": "ea enim Excepteur proident est", "data": "1", "type": "xsd:long" }] + "type": "xsd:command", + "fault": 7148, + "fault_msg": "laboris et officia Duis", + "input": [{ "path": "cillum ea", "data": "1", "type": "xsd:dateTime" }], + "output": [{ "path": "esse aliquip in eu et", "data": "1", "type": "xsd:string" }] } ] } @@ -1578,7 +1486,6 @@ Set values of datamodel object element | Property | Type | Required | | ---------- | ------ | ------------ | | `obj_path` | object | Optional | -| `optional` | object | **Required** | | `path` | string | **Required** | | `value` | string | **Required** | @@ -1609,59 +1516,6 @@ To set multiple values at once, path should be relative to object elements { "path": "Device.WiFi.SSID.2.", "obj_path": { "SSID": "test_ssid" } } ``` -#### optional - -`optional` - -- is **required** -- type: `object` - -##### optional Type - -`object` with following properties: - -| Property | Type | Required | Default | -| ---------------- | ------- | -------- | -------- | -| `proto` | string | Optional | `"both"` | -| `transaction_id` | integer | Optional | | - -#### proto - -`proto` - -- is optional -- type: reference -- default: `"both"` - -##### proto Type - -`string` - -The value of this property **must** be equal to one of the [known values below](#set-known-values). - -##### proto Known Values - -| Value | -| ----- | -| usp | -| cwmp | -| both | - -#### transaction_id - -Required for CUD operation, it shall be same number as got from transaction->start - -`transaction_id` - -- is optional -- type: reference - -##### transaction_id Type - -`integer` - -- minimum value: `1` - #### path DM object path with search queries @@ -1730,7 +1584,7 @@ value of the object element provided in path, path should contains valid writabl ### Ubus CLI Example ``` -ubus call bbf set {"path":"nonmagna ut anim","value":"cupidatat","optional":{"proto":"usp","transaction_id":45864115},"obj_path":{}} +ubus call bbf set {"path":"quioccaecat labore elit offic","value":"dolore nostrud dolore anim non","obj_path":{}} ``` ### JSONRPC Example @@ -1744,12 +1598,7 @@ ubus call bbf set {"path":"nonmagna ut anim","value":"cupidatat","optional":{"pr "", "bbf", "set", - { - "path": "nonmagna ut anim", - "value": "cupidatat", - "optional": { "proto": "usp", "transaction_id": 45864115 }, - "obj_path": {} - } + { "path": "quioccaecat labore elit offic", "value": "dolore nostrud dolore anim non", "obj_path": {} } ] } ``` @@ -1814,200 +1663,5 @@ All items must be of the type: Unknown type ``. ### Output Example ```json -{ "results": [{ "path": "pariatur", "data": "0", "fault": 8723, "fault_msg": "ut aliquip" }] } -``` - -## transaction - -### Start/commit/abort/status a transaction before set/add/del operations - -`transaction` - -- type: `Method` - -### transaction Type - -`object` with following properties: - -| Property | Type | Required | -| -------- | ------ | ------------ | -| `input` | object | **Required** | -| `output` | object | **Required** | - -#### input - -`input` - -- is **required** -- type: `object` - -##### input Type - -`object` with following properties: - -| Property | Type | Required | -| ------------------ | ------- | ------------ | -| `cmd` | string | **Required** | -| `optional` | object | Optional | -| `restart_services` | boolean | Optional | -| `timeout` | integer | Optional | - -#### cmd - -`cmd` - -- is **required** -- type: reference - -##### cmd Type - -`string` - -The value of this property **must** be equal to one of the [known values below](#transaction-known-values). - -##### cmd Known Values - -| Value | -| ------ | -| start | -| commit | -| abort | -| status | - -#### optional - -`optional` - -- is optional -- type: `object` - -##### optional Type - -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ------- | -------- | -| `transaction_id` | integer | Optional | - -#### transaction_id - -Required for CUD operation, it shall be same number as got from transaction->start - -`transaction_id` - -- is optional -- type: reference - -##### transaction_id Type - -`integer` - -- minimum value: `1` - -#### restart_services - -If yes, bbfdmd restart the service after CUD operation, else return list of updated uci to handler restart externally. - -`restart_services` - -- is optional -- type: `boolean` - -##### restart_services Type - -`boolean` - -#### timeout - -Timeout (in milliseconds) for the transaction, on timeout changes will be reverted - -`timeout` - -- is optional -- type: `integer` - -##### timeout Type - -`integer` - -- minimum value: `0` - -### Ubus CLI Example - -``` -ubus call bbf transaction {"cmd":"commit","timeout":95277085,"restart_services":false,"optional":{"transaction_id":36491321}} -``` - -### JSONRPC Example - -```json -{ - "jsonrpc": "2.0", - "id": 0, - "method": "call", - "params": [ - "", - "bbf", - "transaction", - { "cmd": "commit", "timeout": 95277085, "restart_services": false, "optional": { "transaction_id": 36491321 } } - ] -} -``` - -#### output - -`output` - -- is **required** -- type: `object` - -##### output Type - -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ------- | ------------ | -| `error` | string | Optional | -| `status` | boolean | **Required** | -| `transaction_id` | integer | Optional | - -#### error - -`error` - -- is optional -- type: `string` - -##### error Type - -`string` - -#### status - -`status` - -- is **required** -- type: `boolean` - -##### status Type - -`boolean` - -#### transaction_id - -`transaction_id` - -- is optional -- type: `integer` - -##### transaction_id Type - -`integer` - -- minimum value: `1` - -### Output Example - -```json -{ "status": false, "transaction_id": 87022462, "error": "occaecat Excepteur" } +{ "results": [{ "path": "anim no", "data": "0", "fault": 7259, "fault_msg": "ad" }] } ``` diff --git a/docs/api/uci/bbfdm.json b/docs/api/uci/bbfdm.json index 28a13f13..b3a2052b 100644 --- a/docs/api/uci/bbfdm.json +++ b/docs/api/uci/bbfdm.json @@ -26,13 +26,6 @@ "default": "", "description": "Path for ubus socket to register bbfdmd services" }, - { - "name": "transaction_timeout", - "type": "integer", - "required": "no", - "default": "10", - "description": "Transaction timeout value in seconds" - }, { "name": "loglevel", "type": "integer", diff --git a/docs/api/uci/bbfdm.md b/docs/api/uci/bbfdm.md index 7c8938fa..8d45f50f 100644 --- a/docs/api/uci/bbfdm.md +++ b/docs/api/uci/bbfdm.md @@ -84,23 +84,6 @@
Path for ubus socket to register bbfdmd services
- - -
transaction_timeout
- - -
integer
- - -
no
- - -
10
- - -
Transaction timeout value in seconds
- -
loglevel
diff --git a/docs/guide/bbfdmd.md b/docs/guide/bbfdmd.md index 4f9d02e3..863b7c60 100644 --- a/docs/guide/bbfdmd.md +++ b/docs/guide/bbfdmd.md @@ -14,7 +14,6 @@ "config": { "loglevel": "1", "refresh_time": "120", - "transaction_timeout": "30", "subprocess_level": "2" }, "input": { @@ -132,7 +131,6 @@ Following are the ubus methods exposed by `bbfdmd` main process: "operate":{"command":"String","command_key":"String","input":"Table","optional":"Table"} "add":{"path":"String","obj_path":"Table","optional":"Table"} "del":{"path":"String","paths":"Array","optional":"Table"} - "transaction":{"cmd":"String","timeout":"Integer","restart_services":"Boolean","optional":"Table"} "service":{"cmd":"String","name":"String","parent_dm":"String","objects":"Array"} "notify_event":{"name":"String","input":"Table"} ``` @@ -149,19 +147,16 @@ Each datamodel micro-service expose their own ubus object, which is slightly dif "operate":{"command":"String","command_key":"String","input":"Table","optional":"Table"} "add":{"path":"String","obj_path":"Table","optional":"Table"} "del":{"path":"String","paths":"Array","optional":"Table"} - "transaction":{"cmd":"String","timeout":"Integer","restart_services":"Boolean","optional":"Table"} ``` > Note1: `optional` table are present in all methods and it supports below options: ```console -"optional":{"proto":"String", "transaction_id":"Integer", "format":"String"} +"optional":{"proto":"String", "format":"String"} ``` - `proto` in each method specify the data-model prototype('cwmp', 'usp') to use, if not provided default data-model will be used. - - `transaction_id` to define the transaction id number. - - `format` could be 'raw' or 'pretty', to specify the format to use as output, if not provided 'pretty' format will be used. > Note2: `first_level` true means only get next level objects and false means get all objects recursively diff --git a/docs/guide/libbbfdm-api.md b/docs/guide/libbbfdm-api.md index 5f415336..0e6fad86 100644 --- a/docs/guide/libbbfdm-api.md +++ b/docs/guide/libbbfdm-api.md @@ -118,8 +118,8 @@ input pointer to the struct blob_buf object. contains all the packages updated. bool restart_services - if true packages will be updated through ubus call. - if false packages will be updated through uci. + if true packages will be updated through ubus call bbf.config internally. + if false packages will be updated through ubus call bbf.config externally. return None @@ -129,11 +129,15 @@ return This method is used to revert the changes whenever its state is changed ``` -void bbf_entry_revert_changes(struct blob_buf *bb) +void bbf_entry_revert_changes(struct blob_buf *bb, bool revert_changes) input struct blob_buf *bb pointer to the struct blob_buf object. contains all the packages updated. + + bool revert_changes + if true changes will be reverted through ubus call bbf.config internally. + if false changes will be reverted through ubus call bbf.config externally. return None diff --git a/gitlab-ci/bbfdmd-functional-test.sh b/gitlab-ci/bbfdmd-functional-test.sh index 3d379e64..fa238ae0 100755 --- a/gitlab-ci/bbfdmd-functional-test.sh +++ b/gitlab-ci/bbfdmd-functional-test.sh @@ -55,8 +55,8 @@ supervisorctl status gcovr -r . --xml -o ./funl-test-coverage.xml gcovr -r . -echo > memory-report.xml -check_valgrind_xml "Main Service bbfdmd" "/tmp/memory-report.xml" +check_valgrind_xml "/tmp/memory-report.xml" "bbfdmd" +check_valgrind_xml "/tmp/memory-config-report.xml" "bbf.config" if [ "${fault}" -ne 0 ]; then echo "Failed running ubus-api-validator fault[$fault]" diff --git a/gitlab-ci/functional-test.sh b/gitlab-ci/functional-test.sh index 43525774..f0ea915b 100755 --- a/gitlab-ci/functional-test.sh +++ b/gitlab-ci/functional-test.sh @@ -11,6 +11,7 @@ make clean -C test/cmocka/ make functional-test -C test/cmocka/ check_ret $? +sleep 10 supervisorctl stop all supervisorctl status diff --git a/gitlab-ci/install-dependencies.sh b/gitlab-ci/install-dependencies.sh index 97379536..fa29642b 100755 --- a/gitlab-ci/install-dependencies.sh +++ b/gitlab-ci/install-dependencies.sh @@ -7,7 +7,7 @@ source ./gitlab-ci/shared.sh # install required packages exec_cmd apt update exec_cmd apt install -y python3-pip iproute2 jq -exec_cmd pip3 install pexpect ubus xlwt +exec_cmd pip3 install pexpect ubus xlwt ValgrindCI # Make sure that all plugins are removed [ ! -d "${BBFDM_PLUGIN_DIR}" ] && mkdir -p "${BBFDM_PLUGIN_DIR}" diff --git a/gitlab-ci/reload_service.conf b/gitlab-ci/reload_service.conf new file mode 100644 index 00000000..97fb47c1 --- /dev/null +++ b/gitlab-ci/reload_service.conf @@ -0,0 +1,5 @@ +[program:bbf.config] +priority=5 +command=/bin/bash -c "/usr/bin/valgrind --xml=yes --xml-file=/tmp/memory-config-report.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes --leak-resolution=high --show-error-list=yes --child-silent-after-fork=yes /usr/sbin/bbf_configd" + + diff --git a/gitlab-ci/setup.sh b/gitlab-ci/setup.sh index 915a0909..2bc618de 100755 --- a/gitlab-ci/setup.sh +++ b/gitlab-ci/setup.sh @@ -6,7 +6,8 @@ echo "# Preparation script ..." ln -sf bash /bin/sh echo "Installing bbfdm rpcd utilities" -cp utilities/files/usr/libexec/rpcd/* /usr/libexec/rpcd/ +cp utilities/files/usr/libexec/rpcd/bbf.diag /usr/libexec/rpcd/ +cp utilities/files/usr/libexec/rpcd/bbf.secure /usr/libexec/rpcd/ cp -r ./test/files/etc/* /etc/ cp -r ./test/files/usr/* /usr/ @@ -14,7 +15,10 @@ cp -r ./test/files/var/* /var/ cp -r ./test/files/tmp/* /tmp/ cp -r ./test/files/lib/* /lib/ +mkdir -p /tmp/bbfdm/.bbfdm /tmp/bbfdm/.cwmp /tmp/bbfdm/.usp + cp ./gitlab-ci/core_service.conf /etc/supervisor/conf.d/ +cp ./gitlab-ci/reload_service.conf /etc/supervisor/conf.d/ rm -f /etc/bbfdm/dmmap/* diff --git a/gitlab-ci/shared.sh b/gitlab-ci/shared.sh index 8827c18b..65564e27 100755 --- a/gitlab-ci/shared.sh +++ b/gitlab-ci/shared.sh @@ -72,6 +72,7 @@ function install_libbbf() exec_cmd_verbose make install echo "371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04" > /etc/bbfdm/.secure_hash cd .. + exec_cmd cp utilities/bbf_configd /usr/sbin/ } function install_libbbf_test() @@ -100,18 +101,9 @@ function error_on_zero() } function check_valgrind_xml() { - echo "${1}: Checking memory leaks..." - echo "checking UninitCondition" - grep -q "UninitCondition" ${2} - error_on_zero $? - - echo "checking Leak_PossiblyLost" - grep -q "Leak_PossiblyLost" ${2} - error_on_zero $? - - echo "checking Leak_DefinitelyLost" - grep -q "Leak_DefinitelyLost" ${2} - error_on_zero $? + echo "Memory check [$@] ..." + valgrind-ci ${1} --summary + exec_cmd valgrind-ci ${1} --abort-on-errors } function generate_report() diff --git a/libbbfdm-api/dmapi.h b/libbbfdm-api/dmapi.h index 6e2bd22c..4b3991bf 100644 --- a/libbbfdm-api/dmapi.h +++ b/libbbfdm-api/dmapi.h @@ -174,6 +174,9 @@ struct dmctx { struct list_head *memhead; struct blob_buf bb; DMOBJ *dm_entryobj; + struct uci_context *config_uci_ctx; + struct uci_context *dmmap_uci_ctx; + struct uci_context *varstate_uci_ctx; bool nextlevel; bool iswildcard; int faultcode; @@ -193,7 +196,6 @@ struct dmctx { bool isevent; bool isinfo; bool disable_mservice_browse; - int trans_id; }; typedef struct dmnode { diff --git a/libbbfdm-api/dmbbf.c b/libbbfdm-api/dmbbf.c index d6fefd39..eb974b4f 100644 --- a/libbbfdm-api/dmbbf.c +++ b/libbbfdm-api/dmbbf.c @@ -1285,7 +1285,6 @@ static int add_ubus_object(struct dmctx *dmctx, struct dmnode *node) json_object *in_args = json_object_new_object(); json_object_object_add(in_args, "proto", json_object_new_string((dmctx->dm_type == BBFDM_BOTH) ? "both" : (dmctx->dm_type == BBFDM_CWMP) ? "cwmp" : "usp")); json_object_object_add(in_args, "format", json_object_new_string("raw")); - json_object_object_add(in_args, "transaction_id", json_object_new_int(dmctx->trans_id)); dmubus_call(ubus_name, "add", UBUS_ARGS{ @@ -1331,7 +1330,6 @@ static int del_ubus_object(struct dmctx *dmctx, struct dmnode *node) json_object *in_args = json_object_new_object(); json_object_object_add(in_args, "proto", json_object_new_string((dmctx->dm_type == BBFDM_BOTH) ? "both" : (dmctx->dm_type == BBFDM_CWMP) ? "cwmp" : "usp")); json_object_object_add(in_args, "format", json_object_new_string("raw")); - json_object_object_add(in_args, "transaction_id", json_object_new_int(dmctx->trans_id)); dmubus_call(ubus_name, "del", UBUS_ARGS{ @@ -1405,7 +1403,6 @@ static int set_ubus_value(struct dmctx *dmctx, struct dmnode *node) json_object *in_args = json_object_new_object(); json_object_object_add(in_args, "proto", json_object_new_string((dmctx->dm_type == BBFDM_BOTH) ? "both" : (dmctx->dm_type == BBFDM_CWMP) ? "cwmp" : "usp")); json_object_object_add(in_args, "format", json_object_new_string("raw")); - json_object_object_add(in_args, "transaction_id", json_object_new_int(dmctx->trans_id)); if (is_reference_parameter(ubus_name, dmctx->in_param, in_args, &ref_value)) { ref_value = get_value_by_reference(dmctx, ref_value); diff --git a/libbbfdm-api/dmentry.c b/libbbfdm-api/dmentry.c index 94db9e4e..1f2b1974 100644 --- a/libbbfdm-api/dmentry.c +++ b/libbbfdm-api/dmentry.c @@ -17,7 +17,6 @@ #include "dmcommon.h" #include "dmentry.h" -LIST_HEAD(head_package_change); LIST_HEAD(global_memhead); static struct dm_fault DM_FAULT_ARRAY[] = { @@ -49,16 +48,16 @@ void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj) ctx->dm_entryobj = tEntryObj; bbfdm_init_mem(ctx); - dm_uci_init(); + bbfdm_uci_init(ctx); } void bbf_ctx_clean(struct dmctx *ctx) { blob_buf_free(&ctx->bb); - dm_uci_exit(); - dmubus_free(); + bbfdm_uci_exit(ctx); bbfdm_clean_mem(ctx); + dmubus_free(); } void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj) @@ -216,18 +215,12 @@ int bbf_entry_method(struct dmctx *ctx, int cmd) break; case BBF_SET_VALUE: fault = dm_entry_set_value(ctx); - if (!fault) - dmuci_change_packages(&head_package_change); break; case BBF_ADD_OBJECT: fault = dm_entry_add_object(ctx); - if (!fault) - dmuci_change_packages(&head_package_change); break; case BBF_DEL_OBJECT: fault = dm_entry_delete_object(ctx); - if (!fault) - dmuci_change_packages(&head_package_change); break; case BBF_OPERATE: fault = dm_entry_operate(ctx); @@ -349,40 +342,19 @@ bool adm_entry_object_exists(struct dmctx *ctx, char *param) // To be removed la return dmctx.match; } -void bbf_entry_restart_services(struct blob_buf *bb, bool restart_services) +void bbf_entry_services(unsigned int proto, bool is_commit, bool reload_required) { - struct package_change *pc = NULL; + struct blob_buf bb = {0}; - list_for_each_entry(pc, &head_package_change, list) { + memset(&bb, 0, sizeof(struct blob_buf)); - if (bb) blobmsg_add_string(bb, NULL, pc->package); + blob_buf_init(&bb, 0); - if (restart_services) { - // Internal transaction: need to commit the changes - dmubus_call_set("uci", "commit", UBUS_ARGS{{"config", pc->package, String}}, 1); - } - } + blobmsg_add_string(&bb, "proto", (proto == BBFDM_CWMP) ? "cwmp": (proto == BBFDM_USP) ? "usp" : "both"); + blobmsg_add_u8(&bb, "monitor", false); + blobmsg_add_u8(&bb, "reload", reload_required); - if (restart_services) { - // Internal transaction: need to commit the changes - dmuci_commit_bbfdm(); - } + dmubus_call_blob_msg_set("bbf.config", is_commit ? "commit" : "revert", &bb); - free_all_list_package_change(&head_package_change); -} - -void bbf_entry_revert_changes(struct blob_buf *bb) -{ - struct package_change *pc = NULL; - - list_for_each_entry(pc, &head_package_change, list) { - - if (bb) blobmsg_add_string(bb, NULL, pc->package); - - dmubus_call_set("uci", "revert", UBUS_ARGS{{"config", pc->package, String}}, 1); - } - - dmuci_revert_bbfdm(); - - free_all_list_package_change(&head_package_change); + blob_buf_free(&bb); } diff --git a/libbbfdm-api/dmentry.h b/libbbfdm-api/dmentry.h index 3c4d0564..66a5669c 100644 --- a/libbbfdm-api/dmentry.h +++ b/libbbfdm-api/dmentry.h @@ -32,14 +32,10 @@ int dm_validate_allowed_objects(struct dmctx *ctx, struct dm_reference *referenc bool adm_entry_object_exists(struct dmctx *ctx, char *param); // To be removed later!!!!!!!!!!!! (After moving all Objects outside bbfdm core) -void bbf_entry_restart_services(struct blob_buf *bb, bool restart_services); -void bbf_entry_revert_changes(struct blob_buf *bb); +void bbf_entry_services(unsigned int proto, bool is_commit, bool reload_required); void get_list_of_registered_service(struct list_head *srvlist, struct blob_buf *bb); bool load_service(DMOBJ *main_dm, struct list_head *srv_list, char *srv_name, char *srv_parent_dm, char *srv_obj); void free_services_from_list(struct list_head *clist); -int handle_transaction_of_registered_service(struct ubus_context *ctx, struct blob_buf *trans_bb, struct list_head *srvlist, - const char *trans_cmd, int trans_id, uint32_t max_timeout, bool service_restart); - #endif //__DMENTRY_H__ diff --git a/libbbfdm-api/dmplugin.c b/libbbfdm-api/dmplugin.c index 997d6db2..0692065d 100644 --- a/libbbfdm-api/dmplugin.c +++ b/libbbfdm-api/dmplugin.c @@ -122,71 +122,6 @@ bool load_service(DMOBJ *main_dm, struct list_head *srv_list, char *srv_name, ch return true; } -static void ubus_transaction_callback(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg) -{ - struct blob_attr *tb[1] = {0}; - const struct blobmsg_policy p[1] = { - { "updated_services", BLOBMSG_TYPE_ARRAY }, - }; - - if (msg == NULL || req == NULL) - return; - - struct blob_buf *bb = (struct blob_buf *)req->priv; - if (bb == NULL) - return; - - blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg)); - - if (tb[0]) { - struct blob_attr *service = NULL; - size_t rem; - - blobmsg_for_each_attr(service, tb[0], rem) { - blobmsg_add_string(bb, NULL, blobmsg_get_string(service)); - } - } -} - -int handle_transaction_of_registered_service(struct ubus_context *ctx, struct blob_buf *trans_bb, struct list_head *srvlist, - const char *trans_cmd, int trans_id, uint32_t max_timeout, bool service_restart) -{ - struct service *srv = NULL; - - if (is_micro_service == true) // This should be called only from main daemon - return -1; - - if (ctx == NULL || trans_id == 0) - return -1; - - list_for_each_entry(srv, srvlist, list) { - struct blob_buf bb = {0}; - void *table = NULL; - uint32_t ubus_id; - - // check if object already present - int ret = ubus_lookup_id(ctx, srv->name, &ubus_id); - if (ret != 0) - continue; - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - blobmsg_add_string(&bb, "cmd", trans_cmd); - blobmsg_add_u8(&bb, "restart_services", service_restart); - blobmsg_add_u32(&bb, "timeout", max_timeout); - - table = blobmsg_open_table(&bb, "optional"); - blobmsg_add_u32(&bb, "transaction_id", trans_id); - blobmsg_close_table(&bb, table); - - ubus_invoke(ctx, ubus_id, "transaction", bb.head, ubus_transaction_callback, (void *)trans_bb, 5000); - blob_buf_free(&bb); - } - - return 0; -} - void get_list_of_registered_service(struct list_head *srvlist, struct blob_buf *bb) { struct service *srv = NULL; diff --git a/libbbfdm-api/dmubus.c b/libbbfdm-api/dmubus.c index 3943e176..75b934e4 100644 --- a/libbbfdm-api/dmubus.c +++ b/libbbfdm-api/dmubus.c @@ -260,7 +260,7 @@ static int dmubus_call_blob_internal(char *obj, char *method, void *value, int t int dmubus_call_blob(char *obj, char *method, void *value, json_object **resp) { - return dmubus_call_blob_internal(obj, method, value, UBUS_TIMEOUT, resp); + return dmubus_call_blob_internal(obj, method, value, UBUS_TIMEOUT, resp); } int dmubus_call_blob_blocking(char *obj, char *method, void *value, json_object **resp) @@ -280,6 +280,47 @@ int dmubus_call_blob_set(char *obj, char *method, void *value) return rc; } +static int dmubus_call_blob_msg_internal(char *obj, char *method, struct blob_buf *data, int timeout, json_object **resp) +{ + uint32_t id = 0; + int rc = -1; + + json_res = NULL; + + if (resp) + *resp = NULL; + + if (ubus_ctx == NULL) { + ubus_ctx = dm_libubus_init(); + if (ubus_ctx == NULL) { + printf("UBUS context is null\n\r"); + return -1; + } + } + + if (!ubus_lookup_id(ubus_ctx, obj, &id)) { + rc = ubus_invoke(ubus_ctx, id, method, data->head, + receive_call_result_data, NULL, timeout); + } + + if (resp) + *resp = json_res; + + return rc; +} + +int dmubus_call_blob_msg_set(char *obj, char *method, struct blob_buf *data) +{ + int rc = dmubus_call_blob_msg_internal(obj, method, data, UBUS_TIMEOUT, NULL); + + if (json_res != NULL) { + json_object_put(json_res); + json_res = NULL; + } + + return rc; +} + /* Based on an efficient hash function published by D. J. Bernstein */ static unsigned int djbhash(unsigned hash, const char *data, unsigned len) diff --git a/libbbfdm-api/dmubus.h b/libbbfdm-api/dmubus.h index 1f11c4ee..98b2159b 100644 --- a/libbbfdm-api/dmubus.h +++ b/libbbfdm-api/dmubus.h @@ -44,6 +44,8 @@ int dmubus_call_blob(char *obj, char *method, void *value, json_object **resp); int dmubus_call_blob_blocking(char *obj, char *method, void *value, json_object **resp); int dmubus_call_blob_set(char *obj, char *method, void *value); +int dmubus_call_blob_msg_set(char *obj, char *method, struct blob_buf *blob_msg); + void dmubus_free(); bool dmubus_object_method_exists(const char *obj); diff --git a/libbbfdm-api/dmuci.c b/libbbfdm-api/dmuci.c index 05083488..3b8429e5 100644 --- a/libbbfdm-api/dmuci.c +++ b/libbbfdm-api/dmuci.c @@ -19,50 +19,62 @@ static struct uci_context *uci_ctx = NULL; static char *db_config = NULL; -NEW_UCI_PATH(bbfdm, BBFDM_CONFIG, BBFDM_SAVEDIR) -NEW_UCI_PATH(varstate, VARSTATE_CONFDIR, VARSTATE_SAVEDIR) +NEW_UCI_PATH(bbfdm) +NEW_UCI_PATH(varstate) -int dmuci_init(void) +static void bbfdm_uci_init_ctx(struct uci_context **uci_ctx, const char *confdir, const char *savedir) { - if (uci_ctx == NULL) { - uci_ctx = uci_alloc_context(); - if (!uci_ctx) - return -1; - uci_set_confdir(uci_ctx, UCI_CONFIG_DIR); + *uci_ctx = uci_alloc_context(); + if (!*uci_ctx) { + BBF_ERR("Failed to allocate memory for (%s) && (%s)!!!", confdir, savedir); + return; } - return 0; + uci_set_confdir(*uci_ctx, confdir); + uci_set_savedir(*uci_ctx, savedir); } -void dmuci_exit(void) +void bbfdm_uci_init(struct dmctx *bbf_ctx) { - if (uci_ctx) - uci_free_context(uci_ctx); - uci_ctx = NULL; -} + if (bbf_ctx->dm_type == BBFDM_CWMP) { + bbfdm_uci_init_ctx(&bbf_ctx->config_uci_ctx, "/etc/config/", "/tmp/bbfdm/.cwmp/config/"); + bbfdm_uci_init_ctx(&bbf_ctx->dmmap_uci_ctx, "/etc/bbfdm/dmmap/", "/tmp/bbfdm/.cwmp/dmmap/"); + } else if (bbf_ctx->dm_type == BBFDM_USP) { + bbfdm_uci_init_ctx(&bbf_ctx->config_uci_ctx, "/etc/config/", "/tmp/bbfdm/.usp/config/"); + bbfdm_uci_init_ctx(&bbf_ctx->dmmap_uci_ctx, "/etc/bbfdm/dmmap/", "/tmp/bbfdm/.usp/dmmap/"); + } else { + bbfdm_uci_init_ctx(&bbf_ctx->config_uci_ctx, "/etc/config/", "/tmp/bbfdm/.bbfdm/config/"); + bbfdm_uci_init_ctx(&bbf_ctx->dmmap_uci_ctx, "/etc/bbfdm/dmmap/", "/tmp/bbfdm/.bbfdm/dmmap/"); + } -int dm_uci_init(void) -{ - dmuci_init(); + bbfdm_uci_init_ctx(&bbf_ctx->varstate_uci_ctx, "/var/state/", "/tmp/bbfdm/.varstate/"); - dmuci_init_varstate(); - - dmuci_init_bbfdm(); + uci_ctx = bbf_ctx->config_uci_ctx; + uci_ctx_bbfdm = bbf_ctx->dmmap_uci_ctx; + uci_ctx_varstate = bbf_ctx->varstate_uci_ctx; db_config = ETC_DB_CONFIG; - - return 0; } -int dm_uci_exit(void) +void bbfdm_uci_exit(struct dmctx *bbf_ctx) { - dmuci_exit(); + if (bbf_ctx->config_uci_ctx) { + uci_free_context(bbf_ctx->config_uci_ctx); + bbf_ctx->config_uci_ctx = NULL; + uci_ctx = NULL; + } - dmuci_exit_varstate(); + if (bbf_ctx->dmmap_uci_ctx) { + uci_free_context(bbf_ctx->dmmap_uci_ctx); + bbf_ctx->dmmap_uci_ctx = NULL; + uci_ctx_bbfdm = NULL; + } - dmuci_exit_bbfdm(); - - return 0; + if (bbf_ctx->varstate_uci_ctx) { + uci_free_context(bbf_ctx->varstate_uci_ctx); + bbf_ctx->varstate_uci_ctx = NULL; + uci_ctx_varstate = NULL; + } } char *dmuci_list_to_string(struct uci_list *list, const char *delimitor) @@ -101,30 +113,6 @@ static inline bool check_section_name(const char *str, bool name) return true; } -static void add_list_package_change(struct list_head *clist, char *package) -{ - struct package_change *pc = NULL; - - list_for_each_entry(pc, clist, list) { - if (DM_STRCMP(pc->package, package) == 0) - return; - } - pc = calloc(1, sizeof(struct package_change)); - list_add_tail(&pc->list, clist); - pc->package = strdup(package); -} - -void free_all_list_package_change(struct list_head *clist) -{ - struct package_change *pc; - while (clist->next != clist) { - pc = list_entry(clist->next, struct package_change, list); - list_del(&pc->list); - free(pc->package); - free(pc); - } -} - /**** UCI LOOKUP ****/ int dmuci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value) { @@ -466,34 +454,6 @@ int dmuci_revert(void) return 0; } -/**** UCI CHANGES PACKAGES *****/ -int dmuci_change_packages(struct list_head *clist) -{ - char **configs = NULL; - char **p; - - if (uci_list_configs(uci_ctx, &configs) != UCI_OK) - return -1; - - if (!configs) - return -1; - - for (p = configs; *p; p++) { - struct uci_ptr ptr = {0}; - - if (uci_lookup_ptr(uci_ctx, &ptr, *p, true) != UCI_OK) - continue; - - if (uci_list_empty(&ptr.p->delta)) - continue; - - add_list_package_change(clist, *p); - } - - free(configs); - return 0; -} - /**** UCI SET *****/ int dmuci_set_value(char *package, char *section, char *option, char *value) { diff --git a/libbbfdm-api/dmuci.h b/libbbfdm-api/dmuci.h index 01dffe98..db820b1a 100644 --- a/libbbfdm-api/dmuci.h +++ b/libbbfdm-api/dmuci.h @@ -24,19 +24,11 @@ #include #include +#include "dmapi.h" + #ifndef ETC_DB_CONFIG #define ETC_DB_CONFIG "/etc/board-db/config" #endif -#define VARSTATE_CONFIG "/var/state" -#ifndef BBFDM_CONFIG -#define BBFDM_CONFIG "/etc/bbfdm/dmmap" -#endif -#define BBFDM_SAVEDIR "/tmp/.bbfdm" -#ifndef UCI_CONFIG_DIR -#define UCI_CONFIG_DIR "/etc/config/" -#endif -#define VARSTATE_CONFDIR "/var/state/" -#define VARSTATE_SAVEDIR "/tmp/.bbfdm_var" struct package_change { @@ -153,10 +145,8 @@ static inline void uci_list_init(struct uci_list *ptr) ptr->next = ptr; } -#define NEW_UCI_PATH(UCI_PATH, CPATH, DPATH) \ +#define NEW_UCI_PATH(UCI_PATH) \ struct uci_context *uci_ctx_##UCI_PATH = NULL; \ -const char *uci_savedir_##UCI_PATH = DPATH; \ -const char *uci_confdir_##UCI_PATH = CPATH; \ int dmuci_get_section_type_##UCI_PATH(char *package, char *section,char **value) \ {\ struct uci_context *save_uci_ctx; \ @@ -166,23 +156,6 @@ int dmuci_get_section_type_##UCI_PATH(char *package, char *section,char **value) uci_ctx = save_uci_ctx; \ return res; \ }\ -int dmuci_init_##UCI_PATH(void) \ -{\ - if (uci_ctx_##UCI_PATH == NULL) { \ - uci_ctx_##UCI_PATH = uci_alloc_context(); \ - if (!uci_ctx_##UCI_PATH) \ - return -1; \ - uci_add_delta_path(uci_ctx_##UCI_PATH, uci_ctx_##UCI_PATH->savedir); \ - uci_set_savedir(uci_ctx_##UCI_PATH, uci_savedir_##UCI_PATH); \ - uci_set_confdir(uci_ctx_##UCI_PATH, uci_confdir_##UCI_PATH); \ - } \ - return 0; \ -}\ -void dmuci_exit_##UCI_PATH(void) \ -{\ - if (uci_ctx_##UCI_PATH) uci_free_context(uci_ctx_##UCI_PATH);\ - uci_ctx_##UCI_PATH = NULL; \ -}\ int dmuci_get_option_value_string_##UCI_PATH(char *package, char *section, char *option, char **value) \ {\ struct uci_context *save_uci_ctx; \ @@ -328,12 +301,10 @@ int dmuci_delete_by_section_unnamed_##UCI_PATH(struct uci_section *s, char *opti return res; \ }\ -int dmuci_init(void); -void dmuci_exit(void); -int dm_uci_init(void); -int dm_uci_exit(void); +void bbfdm_uci_init(struct dmctx *bbf_ctx); +void bbfdm_uci_exit(struct dmctx *bbf_ctx); + char *dmuci_list_to_string(struct uci_list *list, const char *delimitor); -void free_all_list_package_change(struct list_head *clist); int dmuci_lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value); int dmuci_import(char *package_name, const char *input_path); int dmuci_export_package(char *package, const char *output_path); @@ -344,7 +315,6 @@ int dmuci_save_package(char *package); int dmuci_save(void); int dmuci_revert_package(char *package); int dmuci_revert(void); -int dmuci_change_packages(struct list_head *clist); int dmuci_get_section_type(char *package, char *section, char **value); int dmuci_get_option_value_string(char *package, char *section, char *option, char **value); @@ -386,12 +356,8 @@ int dmuci_save_package_varstate(char *package); int dmuci_revert_package_varstate(char *package); struct uci_section *dmuci_walk_section_bbfdm(char *package, char *stype, void *arg1, void *arg2, int cmp , int (*filter)(struct uci_section *s, void *value), struct uci_section *prev_section, int walk); struct uci_section *dmuci_walk_section_varstate(char *package, char *stype, void *arg1, void *arg2, int cmp , int (*filter)(struct uci_section *s, void *value), struct uci_section *prev_section, int walk); -int dmuci_init_bbfdm(void); -void dmuci_exit_bbfdm(void); void commit_and_free_uci_ctx_bbfdm(char *dmmap_config); int dmuci_add_section_varstate(char *package, char *stype, struct uci_section **s); -int dmuci_init_varstate(void); -void dmuci_exit_varstate(void); int db_get_value_string(char *package, char *section, char *option, char **value); int dmuci_get_option_value_string_varstate(char *package, char *section, char *option, char **value); int dmuci_set_value_varstate(char *package, char *section, char *option, char *value); diff --git a/test/cmocka/functional_api_test_bbfd.c b/test/cmocka/functional_api_test_bbfd.c index e2cbb393..23ebf1d8 100644 --- a/test/cmocka/functional_api_test_bbfd.c +++ b/test/cmocka/functional_api_test_bbfd.c @@ -11,15 +11,15 @@ static struct dmctx bbf_ctx = {0}; static int setup_teardown(void **state) { bbfdm_init_mem(&bbf_ctx); - dm_uci_init(); + bbfdm_uci_init(&bbf_ctx); return 0; } static int group_teardown(void **state) { - dm_uci_exit(); - dmubus_free(); + bbfdm_uci_exit(&bbf_ctx); bbfdm_clean_mem(&bbf_ctx); + dmubus_free(); return 0; } diff --git a/test/cmocka/functional_test_bbfd.c b/test/cmocka/functional_test_bbfd.c index 9526317f..68f9b692 100644 --- a/test/cmocka/functional_test_bbfd.c +++ b/test/cmocka/functional_test_bbfd.c @@ -32,7 +32,7 @@ static int teardown_commit(void **state) { struct dmctx *ctx = (struct dmctx *) *state; - bbf_entry_restart_services(NULL, true); + bbf_entry_services(ctx->dm_type, true, true); bbf_ctx_clean(ctx); free(ctx); @@ -183,6 +183,7 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state) ctx->in_value = "iopsys_test"; fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); + dmuci_commit_package("users"); // get value ==> expected "0" error ctx->in_param = "Device.UCI_TEST_V1.Password"; @@ -285,6 +286,7 @@ static void test_api_bbfdm_get_set_json_v1_parameter(void **state) ctx->in_value = "owsd_pwd"; fault = bbf_entry_method(ctx, BBF_SET_VALUE); assert_int_equal(fault, 0); + dmuci_commit_package("owsd"); // get value ==> expected "0" error ctx->in_param = "Device.UCI_TEST_V1.OWSD.3.Password"; diff --git a/test/cmocka/unit_test_bbfd.c b/test/cmocka/unit_test_bbfd.c index c3555b58..1c309c0d 100644 --- a/test/cmocka/unit_test_bbfd.c +++ b/test/cmocka/unit_test_bbfd.c @@ -32,7 +32,7 @@ static int teardown_commit(void **state) { struct dmctx *ctx = (struct dmctx *) *state; - bbf_entry_restart_services(NULL, true); + bbf_entry_services(ctx->dm_type, true, true); bbf_ctx_clean(ctx); free(ctx); @@ -43,7 +43,7 @@ static int teardown_revert(void **state) { struct dmctx *ctx = (struct dmctx *) *state; - bbf_entry_revert_changes(NULL); + bbf_entry_services(ctx->dm_type, false, true); bbf_ctx_clean(ctx); free(ctx); @@ -553,7 +553,7 @@ static void test_api_bbfdm_library_get_value(void **state) bbf_ctx_clean(ctx); bbf_ctx_init(ctx, TR181_ROOT_TREE); - ctx->in_param = "Device.WiFi.SSID.1.Enable"; + ctx->in_param = "Device.WiFi.SSID.2.Enable"; fault = bbf_entry_method(ctx, BBF_GET_VALUE); assert_int_equal(fault, 0); @@ -580,7 +580,7 @@ static void test_api_bbfdm_library_delete_object(void **state) struct dmctx *ctx = (struct dmctx *) *state; int fault = 0; - ctx->in_param = "Device.WiFi.SSID.1."; + ctx->in_param = "Device.WiFi.SSID.2."; fault = bbf_entry_method(ctx, BBF_DEL_OBJECT); assert_int_equal(fault, 0); diff --git a/test/files/tmp/bbfdm/input.json b/test/files/tmp/bbfdm/input.json index a42752ef..6d2881c1 100755 --- a/test/files/tmp/bbfdm/input.json +++ b/test/files/tmp/bbfdm/input.json @@ -1,8 +1,7 @@ { "daemon": { "config": { - "loglevel": "1", - "transaction_timeout": "30", + "loglevel": "4", "subprocess_level": "2" }, "input": { diff --git a/test/funl/validation/bbf.validation.json b/test/funl/validation/bbf.validation.json index 35ead135..24bf54ba 100644 --- a/test/funl/validation/bbf.validation.json +++ b/test/funl/validation/bbf.validation.json @@ -118,22 +118,6 @@ }, "rc": 0 }, - { - "method": "transaction", - "args": { - "cmd": "commit", - "optional":{"transaction_id":123} - }, - "rc": 0 - }, - { - "method": "transaction", - "args": { - "cmd": "abort", - "optional":{"transaction_id":123} - }, - "rc": 0 - }, { "method": "get", "args": { @@ -146,8 +130,7 @@ "method": "set", "args": { "path": "Device.WiFi.SSID.1.", - "obj_path": {"Alias":"test", "Enable":"1"}, - "optional":{"transaction_id":123} + "obj_path": {"Alias":"test", "Enable":"1"} }, "rc": 0 } diff --git a/test/python/validate_invalid_transaction_id.py b/test/python/validate_invalid_transaction_id.py deleted file mode 100755 index eb00510f..00000000 --- a/test/python/validate_invalid_transaction_id.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python3 - -import ubus -import json -import pathlib - -TEST_NAME = "Validate fault on invalid transaction id with bbf" - -print("Running: " + TEST_NAME) - -def fault_wrong_transaction(cmd, param, efault): - out = ubus.call("bbfdm", cmd, param) - assert out[0]['results'][0]['fault'] == efault, "FAIL: for " + cmd + str(param) + " output " + str(out) - - -sock = pathlib.Path('/var/run/ubus/ubus.sock') -if sock.exists (): - assert ubus.connect('/var/run/ubus/ubus.sock') -else: - assert ubus.connect() - -fault_wrong_transaction("set", {"path":"Device.WiFi.SSID.1.SSID", "value":"abc", "optional":{"format":"raw", "transaction_id":1234}}, 7003) -fault_wrong_transaction("set", {"path":"Device.WiFi.SSID.1.SSID", "value":"abc", "optional":{"format":"raw", "proto":"usp", "transaction_id":1234}}, 7003) -fault_wrong_transaction("set", {"path":"Device.WiFi.SSID.1.SSID", "value":"abc", "optional":{"format":"raw", "proto":"cwmp", "transaction_id":1234}}, 9002) - -fault_wrong_transaction("set", {"path":"Device.WiFi.SSID.1.", "obj_path":{"SSID":"abc"}, "optional":{"format":"raw", "transaction_id":1234}}, 7003) -fault_wrong_transaction("set", {"path":"Device.WiFi.SSID.1.", "obj_path":{"SSID":"abc"}, "optional":{"format":"raw", "transaction_id":1234, "proto":"usp"}}, 7003) -fault_wrong_transaction("set", {"path":"Device.WiFi.SSID.1.", "obj_path":{"SSID":"abc"}, "optional":{"format":"raw", "transaction_id":1234, "proto":"cwmp"}}, 9002) - -fault_wrong_transaction("add", {"path":"Device.WiFi.SSID.", "optional":{"format":"raw", "transaction_id":1234}}, 7003) -fault_wrong_transaction("add", {"path":"Device.WiFi.SSID.", "optional":{"format":"raw", "transaction_id":1234, "proto":"usp"}}, 7003) -fault_wrong_transaction("add", {"path":"Device.WiFi.SSID.", "optional":{"format":"raw", "transaction_id":1234, "proto":"cwmp"}}, 9002) - -fault_wrong_transaction("del", {"path":"Device.WiFi.SSID.1", "optional":{"format":"raw", "transaction_id":1234}}, 7003) -fault_wrong_transaction("del", {"path":"Device.WiFi.SSID.1", "optional":{"format":"raw", "transaction_id":1234, "proto":"usp"}}, 7003) -fault_wrong_transaction("del", {"path":"Device.WiFi.SSID.1", "optional":{"format":"raw", "transaction_id":1234, "proto":"cwmp"}}, 9002) - -ubus.disconnect() - -print("PASS: " + TEST_NAME) diff --git a/test/python/validate_schema_notify.py b/test/python/validate_schema_notify.py deleted file mode 100755 index b9acb8b4..00000000 --- a/test/python/validate_schema_notify.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python3 - -import pexpect -import os - -print("Running: Schema updater notification validation") - -ret = 1 -child = pexpect.spawn('ubus monitor') - -# force change in schema, by removing dependency uci file -os.rename("/etc/config/dropbear", "/etc/config/dropbear_1") - -try: - ret = child.expect('notify', timeout=65) -except: - print("FAIL: Schema updater notification") - -if ret == 0: - try: - ret = child.expect('bbfdm.DelObj') - except: - print("FAIL: Schema updater notification") - -# Revert back uci changes -os.rename("/etc/config/dropbear_1", "/etc/config/dropbear") - -if ret == 0: - print("PASS: Schema updater notification") - -exit(ret) diff --git a/tools/bbf_common.py b/tools/bbf_common.py index cbba641b..a0f8c336 100755 --- a/tools/bbf_common.py +++ b/tools/bbf_common.py @@ -324,7 +324,7 @@ def fill_list_supported_dm(): DB[:] = remove_duplicate_elements(DB) def clone_git_repository(repo, version=None): - repo_path='.repo/'+os.path.basename(repo).replace('.git','') + repo_path='/tmp/repo/'+os.path.basename(repo).replace('.git','') if os.path.exists(repo_path): print(f' {repo} already exists at {repo_path} !') return True @@ -354,7 +354,7 @@ def download_and_build_plugins(plugins, vendor_prefix): print("Generating data models from defined plugins...") - remove_folder(".repo") + remove_folder("/tmp/repo") for plugin_index, plugin in enumerate(plugins): @@ -375,7 +375,7 @@ def download_and_build_plugins(plugins, vendor_prefix): print(f' - Processing plugin: MS({is_microservice}) {plugin}') if proto == "git": - repo_path = ".repo/"+name + repo_path = "/tmp/repo/"+name version = get_option_value(plugin, "version") @@ -394,9 +394,9 @@ def download_and_build_plugins(plugins, vendor_prefix): BBF_ERROR_CODE += 1 continue - create_folder(".repo/dm_info") + create_folder("/tmp/repo/dm_info") if dm_desc_file.endswith('.json'): - dest_file = ".repo/dm_info/" + os.path.basename(dm_desc_file).replace('.json', f"_{plugin_index}.json") + dest_file = "/tmp/repo/dm_info/" + os.path.basename(dm_desc_file).replace('.json', f"_{plugin_index}.json") rename_file(repo_path + "/" + dm_desc_file, dest_file) LIST_FILES = [] diff --git a/tools/generate_dm.py b/tools/generate_dm.py index a0653adf..a34c41fc 100755 --- a/tools/generate_dm.py +++ b/tools/generate_dm.py @@ -100,7 +100,7 @@ else: print("Dumping default DM_JSON_FILES") print(DM_JSON_FILES) - DM_JSON_FILES.extend(glob.glob('.repo/dm_info/*.json')) + DM_JSON_FILES.extend(glob.glob('/tmp/repo/dm_info/*.json')) print("Dumping all") print(DM_JSON_FILES) diff --git a/utilities/files/usr/libexec/rpcd/bbf.config b/utilities/files/usr/libexec/rpcd/bbf.config index 2cd169c7..6d3646dc 100755 --- a/utilities/files/usr/libexec/rpcd/bbf.config +++ b/utilities/files/usr/libexec/rpcd/bbf.config @@ -2,8 +2,10 @@ . /usr/share/libubox/jshn.sh -BBFDM_DMMAP_CONFIG="/etc/bbfdm/dmmap" -BBFDM_DMMAP_SAVEDIR="/tmp/.bbfdm" +BBFDM_CONFIG_CONFDIR="/etc/config" +BBFDM_DMMAP_CONFDIR="/etc/bbfdm/dmmap" +BBFDM_CONFIG_SAVEDIR="/tmp/bbfdm/.bbfdm/config" +BBFDM_DMMAP_SAVEDIR="/tmp/bbfdm/.bbfdm/dmmap" LOGLEVEL="$(uci -q get bbfdm.bbfdmd.loglevel)" @@ -30,6 +32,7 @@ check_result() { apply_config_changes() { local service="$1" local action="$3" + local reload="$4" # Check if either service or action is empty if [ -z "$service" ] || [ -z "$action" ]; then @@ -37,15 +40,22 @@ apply_config_changes() { fi log "Applying $action configuration for service: $service" - + # Commit/Revert config changes - ubus -t 1 call uci ${action} "{'config': '${service}'}" + log "Applying ${action} configuration for file: ${service}" + uci -q -c "${BBFDM_CONFIG_CONFDIR}" -t "${BBFDM_CONFIG_SAVEDIR}" "${action}" "${service}" check_result "$?" "${service}" "${action}" + + if [ "${reload}" == "1" ]; then + # Reload service + ubus -t 1 call uci "${action}" "{'config': '${service}'}" + check_result "$?" "${service}" "${action}" + fi } case "$1" in list) - echo '{ "commit": { "services": [] }, "revert": { "services": [] } }' + echo '{ "commit": { "services": [], "proto": "str", "monitor": true, "reload": true }, "revert": { "services": [], "proto": "str", "monitor": true, "reload": true }, "changes": { "proto": "str" } }' ;; call) # Read input JSON from standard input @@ -54,33 +64,81 @@ case "$1" in # Parse input JSON json_load "${input}" - # Check if 'services' array is provided - json_get_type type "services" - if [ -z "${type}" ]; then - echo '{ "error": "Services array should be defined !!!" }' - exit 1 + # Get the 'proto' value from the input JSON + json_get_var proto proto + + if [ "${proto}" == "cwmp" ]; then + BBFDM_CONFIG_SAVEDIR="/tmp/bbfdm/.cwmp/config" + BBFDM_DMMAP_SAVEDIR="/tmp/bbfdm/.cwmp/dmmap" + elif [ "${proto}" == "usp" ]; then + BBFDM_CONFIG_SAVEDIR="/tmp/bbfdm/.usp/config" + BBFDM_DMMAP_SAVEDIR="/tmp/bbfdm/.usp/dmmap" fi - # Check if 'services' is array - if [ "${type}" != "array" ]; then - echo '{ "error": "Services argument should be array of strings !!!" }' - exit 1 - fi + case "$2" in + commit|revert) - # Iterate over each service and apply config changes - json_for_each_item "apply_config_changes" "services" "$2" - - # Commit/Revert bbfdm dmmap config changes - for file in "${BBFDM_DMMAP_CONFIG}"/*; do - file_name=$(basename "${file}") - log "Applying $2 configuration for file: $file_name" - uci -q -c "${BBFDM_DMMAP_CONFIG}" -t "${BBFDM_DMMAP_SAVEDIR}" "$2" "${file_name}" - check_result "$?" "${file_name}" "$2" - done + # Get the 'reload' value from the input JSON + json_get_var reload reload + json_get_var monitor monitor - # Send 'bbf.config.change' event to run refresh instances - ubus send bbf.config.change + if [ -z "${reload}" ]; then + reload=1 + else + if [ "${reload}" != "0" ] && [ "${reload}" != "1" ]; then + echo '{ "error": "Reload should be boolean type !!!" }' + exit 1 + fi + fi - echo '{ "status": "ok" }' + # Check if 'services' array is provided + json_get_type type "services" + if [ -z "${type}" ]; then + # Iterate over all services and apply config changes + for config in $(uci -q -c "${BBFDM_CONFIG_CONFDIR}" -t "${BBFDM_CONFIG_SAVEDIR}" changes | awk -F'.' '{print $1}' | sort | uniq); do + apply_config_changes "${config}" "" "$2" "$reload" + done + else + # Check if 'services' is array + if [ "${type}" != "array" ]; then + echo '{ "error": "Services argument should be array of strings !!!" }' + exit 1 + fi + + # Iterate over each service and apply config changes + json_for_each_item "apply_config_changes" "services" "$2" "$reload" + fi + + if [ "${reload}" == "1" ]; then + # Commit/Revert bbfdm dmmap config changes + if [ -d "${BBFDM_DMMAP_SAVEDIR}" ] && [ "$(ls -A "${BBFDM_DMMAP_SAVEDIR}" 2>/dev/null)" ]; then + for file in "${BBFDM_DMMAP_SAVEDIR}"/*; do + file_name=$(basename "${file}") + log "Applying $2 configuration for file: $file_name" + uci -q -c "${BBFDM_DMMAP_CONFDIR}" -t "${BBFDM_DMMAP_SAVEDIR}" "$2" "${file_name}" + check_result "$?" "${file_name}" "$2" + done + fi + fi + + if [ "${monitor}" -eq "1" ]; then + sleep 3 + fi + + # Send 'bbf.config.change' event to run refresh instances + ubus send bbf.config.change + + echo '{ "status": "ok" }' + ;; + changes) + json_init + json_add_array "configs" + for config in $(uci -q -c "${BBFDM_CONFIG_CONFDIR}" -t "${BBFDM_CONFIG_SAVEDIR}" changes | awk -F'.' '{print $1}' | sort | uniq); do + json_add_string "" "${config}" + done + json_close_array + json_dump + ;; + esac ;; esac diff --git a/utilities/src/ubus/bbf_config.c b/utilities/src/ubus/bbf_config.c index 9ad7a075..60ddb0a2 100644 --- a/utilities/src/ubus/bbf_config.c +++ b/utilities/src/ubus/bbf_config.c @@ -23,8 +23,34 @@ #define MAX_INSTANCE_NUM 32 #define NAME_LENGTH 64 -#define DM_DMMAP_CONFIG "/etc/bbfdm/dmmap" -#define DM_DMMAP_SAVEDIR "/tmp/.bbfdm" +#define CONFIG_CONFDIR "/etc/config/" +#define DMMAP_CONFDIR "/etc/bbfdm/dmmap/" + +uint8_t g_log_level = 0; + +void print_log(const char *format, ...); + +#define LOG(fmt, args...) \ + print_log(fmt, ##args) + +struct proto_args { + const char *name; + const char *config_savedir; + const char *dmmap_savedir; + unsigned char index; +}; + +static struct proto_args supported_protocols[] = { + { + "both", "/tmp/bbfdm/.bbfdm/config/", "/tmp/bbfdm/.bbfdm/dmmap/", 0 + }, + { + "cwmp", "/tmp/bbfdm/.cwmp/config/", "/tmp/bbfdm/.cwmp/dmmap/", 1 + }, + { + "usp", "/tmp/bbfdm/.usp/config/", "/tmp/bbfdm/.usp/dmmap/", 2 + }, +}; // Structure to represent an instance of a service struct instance { @@ -48,13 +74,41 @@ struct config_package { enum { SERVICES_NAME, + SERVICES_PROTO, + SERVICES_MONITOR, + SERVICES_RELOAD, __MAX }; static const struct blobmsg_policy bbf_config_policy[] = { [SERVICES_NAME] = { .name = "services", .type = BLOBMSG_TYPE_ARRAY }, + [SERVICES_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, + [SERVICES_MONITOR] = { .name = "monitor", .type = BLOBMSG_TYPE_BOOL }, + [SERVICES_RELOAD] = { .name = "reload", .type = BLOBMSG_TYPE_BOOL }, }; +void print_log(const char *format, ...) +{ + va_list arglist; + + if (g_log_level < 1) + return; + + va_start(arglist, format); + vsyslog(LOG_INFO, format, arglist); + va_end(arglist); +} + +static unsigned char get_idx_by_proto(const char *proto) +{ + for (int i = 0; i < ARRAY_SIZE(supported_protocols); i++) { + if (strcmp(supported_protocols[i].name, proto) == 0) + return supported_protocols[i].index; + } + + return 0; +} + static int find_config_idx(struct config_package *package, const char *config_name) { if (!config_name) @@ -289,6 +343,7 @@ static void fill_service_info(struct ubus_context *ctx, struct config_package *p { struct blob_buf ubus_bb = {0}; + memset(&ubus_bb, 0 , sizeof(struct blob_buf)); blob_buf_init(&ubus_bb, 0); if (name) blobmsg_add_string(&ubus_bb, "name", name); @@ -365,13 +420,24 @@ wait: sleep(TIME_TO_WAIT_FOR_RELOAD); } -static void send_bbf_config_change_event(struct ubus_context *ctx) +static void send_bbf_config_change_event() { + struct ubus_context *ctx; struct blob_buf bb = {0}; + ctx = ubus_connect(NULL); + if (ctx == NULL) { + LOG("Can't create UBUS context for event"); + return; + } + + LOG("Sending bbf.config.change event"); + + memset(&bb, 0, sizeof(struct blob_buf)); blob_buf_init(&bb, 0); ubus_send_event(ctx, "bbf.config.change", bb.head); blob_buf_free(&bb); + ubus_free(ctx); } static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), @@ -381,7 +447,10 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec struct blob_attr *tb[__MAX]; struct blob_buf bb = {0}; struct config_package package[MAX_PACKAGE_NUM]; + unsigned char idx = 0; + bool monitor = true, reload = true; + LOG("Commit handler called"); memset(package, 0, sizeof(struct config_package) * MAX_PACKAGE_NUM); memset(&bb, 0, sizeof(struct blob_buf)); @@ -392,33 +461,45 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec goto end; } - struct blob_attr *services = tb[SERVICES_NAME]; - - if (!services) { - blobmsg_add_string(&bb, "error", "Services array should be defined !!!"); - goto end; + if (tb[SERVICES_PROTO]) { + char *proto = blobmsg_get_string(tb[SERVICES_PROTO]); + idx = get_idx_by_proto(proto); } - // Commit all uci dmmap changes - uci_apply_changes(DM_DMMAP_CONFIG, DM_DMMAP_SAVEDIR, true); + if (tb[SERVICES_MONITOR]) + monitor = blobmsg_get_bool(tb[SERVICES_MONITOR]); - size_t arr_len = blobmsg_len(services); + if (tb[SERVICES_RELOAD]) + reload = blobmsg_get_bool(tb[SERVICES_RELOAD]); - if (arr_len) { + if (monitor) { // Get all configs information before calling ubus call uci commit fill_service_info(ctx, package, NULL, true, _get_service_list_cb); + } - // Commit uci config changes for the required configs - reload_services(ctx, services, true); + if (reload) { + // Commit all uci dmmap changes + uci_apply_changes(DMMAP_CONFDIR, supported_protocols[idx].dmmap_savedir, true); + } + struct blob_attr *services = tb[SERVICES_NAME]; + + size_t arr_len = (services) ? blobmsg_len(services) : 0; + + if (arr_len) { + // Commit uci config changes for the required configs and reload services + reload_specified_services(ctx, CONFIG_CONFDIR, supported_protocols[idx].config_savedir, services, true, reload); + } else { + // Commit uci config changes for all configs and reload services + reload_all_services(ctx, CONFIG_CONFDIR, supported_protocols[idx].config_savedir, true, reload); + } + + if (monitor) { // Wait at least 2 seconds to reload the services sleep(2); // Check if the required services are really reloaded validate_required_services(ctx, package, services); - - // Send 'bbf.config.change' event to run refresh instances - send_bbf_config_change_event(ctx); } blobmsg_add_string(&bb, "status", "ok"); @@ -427,6 +508,10 @@ end: ubus_send_reply(ctx, req, bb.head); blob_buf_free(&bb); + // Send 'bbf.config.change' event to run refresh instances + send_bbf_config_change_event(); + LOG("Commit handler exit"); + return 0; } @@ -436,6 +521,57 @@ static int bbf_config_revert_handler(struct ubus_context *ctx, struct ubus_objec { struct blob_attr *tb[__MAX]; struct blob_buf bb = {0}; + unsigned char idx = 0; + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + + LOG("Revert handler called"); + if (blobmsg_parse(bbf_config_policy, __MAX, tb, blob_data(msg), blob_len(msg))) { + blobmsg_add_string(&bb, "error", "Failed to parse blob"); + goto end; + } + + if (tb[SERVICES_PROTO]) { + char *proto = blobmsg_get_string(tb[SERVICES_PROTO]); + idx = get_idx_by_proto(proto); + } + + struct blob_attr *services = tb[SERVICES_NAME]; + + size_t arr_len = (services) ? blobmsg_len(services) : 0; + + if (arr_len) { + // Revert uci config changes for the required configs and reload services + reload_specified_services(ctx, CONFIG_CONFDIR, supported_protocols[idx].config_savedir, services, false, false); + } else { + // Revert uci config changes for all configs and reload services + reload_all_services(ctx, CONFIG_CONFDIR, supported_protocols[idx].config_savedir, false, false); + } + + // Revert all uci dmmap changes + uci_apply_changes(DMMAP_CONFDIR, supported_protocols[idx].dmmap_savedir, false); + + blobmsg_add_string(&bb, "status", "ok"); + +end: + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + + // Send 'bbf.config.change' event to run refresh instances + send_bbf_config_change_event(); + LOG("revert handler exit"); + + return 0; +} + +static int bbf_config_changes_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), + struct ubus_request_data *req, const char *method __attribute__((unused)), + struct blob_attr *msg) +{ + struct blob_attr *tb[__MAX]; + struct blob_buf bb = {0}; + unsigned char idx = 0; memset(&bb, 0, sizeof(struct blob_buf)); blob_buf_init(&bb, 0); @@ -445,27 +581,16 @@ static int bbf_config_revert_handler(struct ubus_context *ctx, struct ubus_objec goto end; } - struct blob_attr *services = tb[SERVICES_NAME]; - - if (!services) { - blobmsg_add_string(&bb, "error", "Services array should be defined !!!"); - goto end; + if (tb[SERVICES_PROTO]) { + char *proto = blobmsg_get_string(tb[SERVICES_PROTO]); + idx = get_idx_by_proto(proto); } - // Revert all uci dmmap changes - uci_apply_changes(DM_DMMAP_CONFIG, DM_DMMAP_SAVEDIR, false); + void *array = blobmsg_open_array(&bb, "configs"); - size_t arr_len = blobmsg_len(services); + uci_config_changes(CONFIG_CONFDIR, supported_protocols[idx].config_savedir, &bb); - if (arr_len) { - // Revert uci config changes for the required configs - reload_services(ctx, services, false); - - // Send 'bbf.config.change' event to run refresh instances - send_bbf_config_change_event(ctx); - } - - blobmsg_add_string(&bb, "status", "ok"); + blobmsg_close_array(&bb, array); end: ubus_send_reply(ctx, req, bb.head); @@ -478,6 +603,7 @@ end: static const struct ubus_method bbf_config_methods[] = { UBUS_METHOD("commit", bbf_config_commit_handler, bbf_config_policy), UBUS_METHOD("revert", bbf_config_revert_handler, bbf_config_policy), + UBUS_METHOD("changes", bbf_config_changes_handler, bbf_config_policy), }; static struct ubus_object_type bbf_config_object_type = UBUS_OBJECT_TYPE("bbf.config", bbf_config_methods); @@ -489,9 +615,20 @@ static struct ubus_object bbf_config_object = { .n_methods = ARRAY_SIZE(bbf_config_methods), }; +static void usage(char *prog) +{ + fprintf(stderr, "Usage: %s [options]\n", prog); + fprintf(stderr, "\n"); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -d Use multiple time to get more verbose debug logs\n"); + fprintf(stderr, " -h Displays this help\n"); + fprintf(stderr, "\n"); +} + int main(int argc, char **argv) { struct ubus_context *uctx; + int ch; openlog("bbf.config", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); @@ -501,6 +638,19 @@ int main(int argc, char **argv) return -1; } + while ((ch = getopt(argc, argv, "hd")) != -1) { + switch (ch) { + case 'd': + g_log_level += 1; + break; + case 'h': + usage(argv[0]); + exit(0); + default: + break; + } + } + uloop_init(); ubus_add_uloop(uctx); diff --git a/utilities/src/ubus/utils.c b/utilities/src/ubus/utils.c index d8a9eb24..ecb92d48 100644 --- a/utilities/src/ubus/utils.c +++ b/utilities/src/ubus/utils.c @@ -69,22 +69,54 @@ static void reload_service(struct ubus_context *ctx, const char *config_name, bo blob_buf_free(&bb); } -void reload_services(struct ubus_context *ctx, struct blob_attr *services, bool is_commit) +void reload_specified_services(struct ubus_context *ctx, const char *conf_dir, const char *save_dir, struct blob_attr *services, bool is_commit, bool reload) { + struct uci_context *uci_ctx = NULL; struct blob_attr *service = NULL; size_t rem = 0; - blobmsg_for_each_attr(service, services, rem) { - char *config_name = blobmsg_get_string(service); - reload_service(ctx, config_name, is_commit); + uci_ctx = uci_alloc_context(); + if (!uci_ctx) { + return; } + + if (conf_dir) { + uci_set_confdir(uci_ctx, conf_dir); + } + + if (save_dir) { + uci_set_savedir(uci_ctx, save_dir); + } + + blobmsg_for_each_attr(service, services, rem) { + struct uci_ptr ptr = {0}; + + char *config_name = blobmsg_get_string(service); + + if (uci_lookup_ptr(uci_ctx, &ptr, config_name, true) != UCI_OK) + continue; + + if (is_commit) { + if (uci_commit(uci_ctx, &ptr.p, false) != UCI_OK) + continue; + } else { + if (uci_revert(uci_ctx, &ptr) != UCI_OK) { + continue; + } + } + + if (reload) { + reload_service(ctx, config_name, is_commit); + } + } + + uci_free_context(uci_ctx); } -void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commit) +void reload_all_services(struct ubus_context *ctx, const char *conf_dir, const char *save_dir, bool is_commit, bool reload) { struct uci_context *uci_ctx = NULL; char **configs = NULL, **p = NULL; - struct uci_ptr ptr = {0}; uci_ctx = uci_alloc_context(); if (!uci_ctx) { @@ -104,6 +136,59 @@ void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commi } for (p = configs; p && *p; p++) { + struct uci_ptr ptr = {0}; + + if (uci_lookup_ptr(uci_ctx, &ptr, *p, true) != UCI_OK) + continue; + + if (uci_list_empty(&ptr.p->saved_delta)) + continue; + + if (is_commit) { + if (uci_commit(uci_ctx, &ptr.p, false) != UCI_OK) + continue; + } else { + if (uci_revert(uci_ctx, &ptr) != UCI_OK) { + continue; + } + } + + if (reload) { + reload_service(ctx, *p, is_commit); + } + } + + free(configs); + +exit: + uci_free_context(uci_ctx); +} + +void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commit) +{ + struct uci_context *uci_ctx = NULL; + char **configs = NULL, **p = NULL; + + uci_ctx = uci_alloc_context(); + if (!uci_ctx) { + return; + } + + if (conf_dir) { + uci_set_confdir(uci_ctx, conf_dir); + } + + if (save_dir) { + uci_set_savedir(uci_ctx, save_dir); + } + + if (uci_list_configs(uci_ctx, &configs) != UCI_OK) { + goto exit; + } + + for (p = configs; p && *p; p++) { + struct uci_ptr ptr = {0}; + if (uci_lookup_ptr(uci_ctx, &ptr, *p, true) != UCI_OK) continue; @@ -123,3 +208,43 @@ void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commi exit: uci_free_context(uci_ctx); } + +void uci_config_changes(const char *conf_dir, const char *save_dir, struct blob_buf *bb) +{ + struct uci_context *uci_ctx = NULL; + char **configs = NULL, **p = NULL; + + uci_ctx = uci_alloc_context(); + if (!uci_ctx) { + return; + } + + if (conf_dir) { + uci_set_confdir(uci_ctx, conf_dir); + } + + if (save_dir) { + uci_set_savedir(uci_ctx, save_dir); + } + + if (uci_list_configs(uci_ctx, &configs) != UCI_OK) { + goto exit; + } + + for (p = configs; p && *p; p++) { + struct uci_ptr ptr = {0}; + + if (uci_lookup_ptr(uci_ctx, &ptr, *p, true) != UCI_OK) + continue; + + if (uci_list_empty(&ptr.p->saved_delta)) + continue; + + blobmsg_add_string(bb, NULL, *p); + } + + free(configs); + +exit: + uci_free_context(uci_ctx); +} diff --git a/utilities/src/ubus/utils.h b/utilities/src/ubus/utils.h index cac60236..6d50d1f1 100644 --- a/utilities/src/ubus/utils.h +++ b/utilities/src/ubus/utils.h @@ -11,14 +11,22 @@ #ifndef __UTILS_H__ #define __UTILS_H__ +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + void dbg_printf(const char *format, ...); void strncpyt(char *dst, const char *src, size_t n); int bbf_config_call(struct ubus_context *ctx, const char *object, const char *method, struct blob_buf *data, ubus_data_handler_t callback, void *arg); +void reload_specified_services(struct ubus_context *ctx, const char *conf_dir, const char *save_dir, struct blob_attr *services, bool is_commit, bool reload); + +void reload_all_services(struct ubus_context *ctx, const char *conf_dir, const char *save_dir, bool is_commit, bool reload); + void uci_apply_changes(const char *conf_dir, const char *save_dir, bool is_commit); -void reload_services(struct ubus_context *ctx, struct blob_attr *services, bool is_commit); +void uci_config_changes(const char *conf_dir, const char *save_dir, struct blob_buf *bb); #endif //__UTILS_H__