From 38d97ecc28736ceab5c32202393413e05a4f39c7 Mon Sep 17 00:00:00 2001 From: Xiaofeng Meng Date: Thu, 23 Oct 2025 15:27:46 +0200 Subject: [PATCH] commts from devel --- dm-service/dm_service.c | 7 +- docs/guide/libbbfdm-ubus.md | 8 +- libbbfdm-api/legacy/dmbbf.c | 10 ++- libbbfdm-ubus/bbfdm-ubus.c | 146 ++++++++++++++++++++---------------- libbbfdm-ubus/bbfdm-ubus.h | 12 ++- libbbfdm-ubus/events.c | 36 +++------ tools/bbf_common.py | 7 +- tools/tools_input.json | 18 +++++ 8 files changed, 141 insertions(+), 103 deletions(-) diff --git a/dm-service/dm_service.c b/dm-service/dm_service.c index e1d3b8fb..fa6375c9 100644 --- a/dm-service/dm_service.c +++ b/dm-service/dm_service.c @@ -71,8 +71,7 @@ int main(int argc, char **argv) bbfdm_ubus_set_log_level(log_level); bbfdm_ubus_load_data_model(NULL); - - err = bbfdm_ubus_regiter_init(&bbfdm_ctx); + err = bbfdm_ubus_register_init(&bbfdm_ctx); if (err != 0) goto exit; @@ -86,9 +85,7 @@ int main(int argc, char **argv) uloop_run(); exit: - if (err != -5) // Error code is not -5, indicating that ubus_ctx is connected, proceed with shutdown - bbfdm_ubus_regiter_free(&bbfdm_ctx); - + bbfdm_ubus_register_free(&bbfdm_ctx); closelog(); return err; diff --git a/docs/guide/libbbfdm-ubus.md b/docs/guide/libbbfdm-ubus.md index ed07a2fd..da4208dc 100644 --- a/docs/guide/libbbfdm-ubus.md +++ b/docs/guide/libbbfdm-ubus.md @@ -13,12 +13,12 @@ The `libbbfdm-ubus` library can be used by: The following APIs are provided by `libbbfdm-ubus` to expose the data model over ubus: -### bbfdm_ubus_regiter_init +### bbfdm_ubus_register_init This method initializes the `bbfdm_context` structure object and registers ubus data model methods. ```c -int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx) +int bbfdm_ubus_register_init(struct bbfdm_context *bbfdm_ctx) Inputs: struct bbfdm_context *bbfdm_ctx @@ -29,12 +29,12 @@ Returns: Returns 0 on success, or an error code if the registration fails. ``` -### bbfdm_ubus_regiter_free +### bbfdm_ubus_register_free This method frees the `bbfdm_context` structure object. ```c -int bbfdm_ubus_regiter_free(struct bbfdm_context *bbfdm_ctx) +int bbfdm_ubus_register_free(struct bbfdm_context *bbfdm_ctx) Inputs: struct bbfdm_context *bbfdm_ctx diff --git a/libbbfdm-api/legacy/dmbbf.c b/libbbfdm-api/legacy/dmbbf.c index 2d9ce4c1..56c0e78a 100644 --- a/libbbfdm-api/legacy/dmbbf.c +++ b/libbbfdm-api/legacy/dmbbf.c @@ -448,8 +448,16 @@ static void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *ent else dmasprintf(&(node.current_object), "%s%s.", parent_obj, entryobj->obj); - if (DM_STRCMP(parent_obj, ROOT_NODE) == 0) { + if (DM_STRCMP(parent_obj, ROOT_NODE) == 0) { // Case1: parent object is 'Device.' node.current_object_file = entryobj->obj; + } else if (parent_node->parent && DM_STRLEN(parent_node->parent->current_object) == 0) { // Case2: parent object is 'Device.X.X.' + size_t count = 0; + + char **parts = strsplit(parent_obj, ".", &count); + if (count < 2) + return; + + node.current_object_file = parts[1]; } if (dmctx->checkobj) { diff --git a/libbbfdm-ubus/bbfdm-ubus.c b/libbbfdm-ubus/bbfdm-ubus.c index 6365e096..002e5bc1 100644 --- a/libbbfdm-ubus/bbfdm-ubus.c +++ b/libbbfdm-ubus/bbfdm-ubus.c @@ -37,6 +37,13 @@ static void *deamon_lib_handle = NULL; static uint8_t s_log_level = 0xff; +static void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx) +{ + INIT_LIST_HEAD(&bbfdm_ctx->event_handlers); + INIT_LIST_HEAD(&bbfdm_ctx->config.apply_handlers); + INIT_LIST_HEAD(&bbfdm_ctx->changed_uci); +} + static void bbfdm_ctx_cleanup(struct bbfdm_context *u) { bbf_global_clean(DEAMON_DM_ROOT_OBJ); @@ -134,7 +141,7 @@ static int bbfdm_start_deferred(bbfdm_data_t *data, void (*EXEC_CB)(bbfdm_data_t BBF_ERR("fork error"); goto err_out; } else if (child == 0) { - u = container_of(data->ctx, struct bbfdm_context, ubus_ctx); + u = container_of(data->obj, struct bbfdm_context, ubus_obj); if (u == NULL) { BBF_ERR("{fork} Failed to get the bbfdm context"); exit(EXIT_FAILURE); @@ -142,7 +149,7 @@ static int bbfdm_start_deferred(bbfdm_data_t *data, void (*EXEC_CB)(bbfdm_data_t /* free fd's and memory inherited from parent */ uloop_done(); - ubus_shutdown(data->ctx); + ubus_free(data->ctx); async_req_free(r); fclose(stdin); fclose(stdout); @@ -221,7 +228,7 @@ static const struct blobmsg_policy dm_schema_policy[] = { [DM_SCHEMA_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE}, }; -static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), +static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg) { @@ -232,7 +239,7 @@ static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *ob memset(&data, 0, sizeof(bbfdm_data_t)); - u = container_of(ctx, struct bbfdm_context, ubus_ctx); + u = container_of(obj, struct bbfdm_context, ubus_obj); if (u == NULL) { BBF_ERR("Failed to get the bbfdm context"); return UBUS_STATUS_UNKNOWN_ERROR; @@ -401,7 +408,7 @@ static const struct blobmsg_policy dm_operate_policy[__DM_OPERATE_MAX] = { [DM_OPERATE_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, }; -static int bbfdm_operate_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), +static int bbfdm_operate_handler(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg) { @@ -424,6 +431,7 @@ static int bbfdm_operate_handler(struct ubus_context *ctx, struct ubus_object *o data.ctx = ctx; data.req = req; + data.obj = obj; data.bbf_ctx.in_param = path; data.bbf_ctx.linker = tb[DM_OPERATE_COMMAND_KEY] ? blobmsg_get_string(tb[DM_OPERATE_COMMAND_KEY]) : ""; @@ -612,34 +620,15 @@ static struct ubus_method bbf_methods[] = { static struct ubus_object_type bbf_type = UBUS_OBJECT_TYPE("", bbf_methods); -static struct ubus_object bbf_object = { - .name = "", - .type = &bbf_type, - .methods = bbf_methods, - .n_methods = ARRAY_SIZE(bbf_methods) -}; - -static int regiter_ubus_object(struct ubus_context *ctx) +static int regiter_ubus_object(struct bbfdm_context *bbfdm_ctx) { - struct bbfdm_context *u; + bbfdm_ctx->ubus_obj.name = bbfdm_ctx->config.out_name; + bbfdm_ctx->ubus_obj.type = &bbf_type; + bbfdm_ctx->ubus_obj.type->name = bbfdm_ctx->config.out_name; + bbfdm_ctx->ubus_obj.methods = bbf_methods; + bbfdm_ctx->ubus_obj.n_methods = ARRAY_SIZE(bbf_methods); - u = container_of(ctx, struct bbfdm_context, ubus_ctx); - if (u == NULL) { - BBF_ERR("failed to get the bbfdm context"); - return -1; - } - - bbf_object.name = u->config.out_name; - bbf_object.type->name = u->config.out_name; - - return ubus_add_object(ctx, &bbf_object); -} - -static void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx) -{ - INIT_LIST_HEAD(&bbfdm_ctx->event_handlers); - INIT_LIST_HEAD(&bbfdm_ctx->config.apply_handlers); - INIT_LIST_HEAD(&bbfdm_ctx->changed_uci); + return ubus_add_object(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->ubus_obj); } static void free_apply_handlers(bbfdm_config_t *config) @@ -897,15 +886,11 @@ int bbfdm_print_data_model_schema(struct bbfdm_context *bbfdm_ctx, const enum bb return err; } -static void perform_uci_sync_op(struct uloop_timeout *timeout) +static void perform_uci_sync_op(struct bbfdm_context *bbfdm_ctx) { DM_MAP_OBJ *dynamic_obj = INTERNAL_ROOT_TREE; - if (dynamic_obj == NULL) - return; - - struct bbfdm_context *bbfdm_ctx = container_of(timeout, struct bbfdm_context, sync_timer); - if (bbfdm_ctx == NULL) + if (dynamic_obj == NULL || bbfdm_ctx == NULL) return; for (int i = 0; dynamic_obj[i].path; i++) { @@ -918,7 +903,6 @@ static void perform_uci_sync_op(struct uloop_timeout *timeout) if (bbfdm_refresh_references(BBFDM_BOTH, bbfdm_ctx->config.out_name)) { BBF_ERR("Failed to refresh instance data base"); - return; } } @@ -993,41 +977,53 @@ static void bbfdm_apply_event_cb(struct ubus_context *ctx __attribute__((unused) } snprintf(bbfdm_ctx->uci_change_proto, sizeof(bbfdm_ctx->uci_change_proto), "%s", proto); - memset(&bbfdm_ctx->sync_timer, 0, sizeof(struct uloop_timeout)); - bbfdm_ctx->sync_timer.cb = perform_uci_sync_op; - uloop_timeout_set(&bbfdm_ctx->sync_timer, 0); + perform_uci_sync_op(bbfdm_ctx); } } -static void register_bbfdm_apply_event(struct bbfdm_context *bbfdm_ctx) +static int register_bbfdm_apply_event(struct bbfdm_context *bbfdm_ctx) { if (bbfdm_ctx == NULL) - return; + return -1; memset(&bbfdm_ctx->apply_event, 0, sizeof(struct ubus_event_handler)); bbfdm_ctx->apply_event.cb = bbfdm_apply_event_cb; - ubus_register_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event, "bbfdm.apply"); + ubus_register_event_handler(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event, "bbfdm.apply"); + return 0; } -int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx) +static int bbfdm_ubus_init(struct bbfdm_context *bbfdm_ctx) +{ + bbfdm_ctx->ubus_ctx = ubus_connect(NULL); + if (!bbfdm_ctx->ubus_ctx) { + BBF_ERR("Failed to connect to ubus"); + return -1; + } + + uloop_init(); + ubus_add_uloop(bbfdm_ctx->ubus_ctx); + bbfdm_ctx->internal_ubus_ctx = true; + return 0; +} + +int bbfdm_ubus_register_init(struct bbfdm_context *bbfdm_ctx) { int err = 0; - err = ubus_connect_ctx(&bbfdm_ctx->ubus_ctx, NULL); - if (err != UBUS_STATUS_OK) { - BBF_ERR("Failed to connect to ubus"); - return -5; // Error code -5 indicating that ubus_ctx is not connected - } - // Set the logmask with default, if not already set by api if (s_log_level == 0xff) { BBF_INFO("Log level not set, setting default value %d", LOG_ERR); bbfdm_ubus_set_log_level(LOG_ERR); } - uloop_init(); - ubus_add_uloop(&bbfdm_ctx->ubus_ctx); + if (bbfdm_ctx->ubus_ctx == NULL) { + err = bbfdm_ubus_init(bbfdm_ctx); + if (err) { + BBF_ERR("Failed to initialize ubus_ctx internally"); + return err; + } + } bbfdm_ctx_init(bbfdm_ctx); @@ -1043,7 +1039,7 @@ int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx) return err; } - err = regiter_ubus_object(&bbfdm_ctx->ubus_ctx); + err = regiter_ubus_object(bbfdm_ctx); if (err != UBUS_STATUS_OK) return -1; @@ -1053,22 +1049,42 @@ int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx) return -1; } - register_bbfdm_apply_event(bbfdm_ctx); + err = register_bbfdm_apply_event(bbfdm_ctx); + if (err) { + BBF_ERR("Failed to register bbfdm apply event"); + return -1; + } - return register_events_to_ubus(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers); + return register_events_to_ubus(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers); +} + +int bbfdm_ubus_register_free(struct bbfdm_context *bbfdm_ctx) +{ + free_apply_handlers(&bbfdm_ctx->config); + free_changed_uci(bbfdm_ctx); + + if (bbfdm_ctx->ubus_ctx) { + ubus_unregister_event_handler(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event); + free_ubus_event_handler(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers); + } + + if (bbfdm_ctx->ubus_ctx && bbfdm_ctx->internal_ubus_ctx) { + ubus_free(bbfdm_ctx->ubus_ctx); + uloop_done(); + } + bbfdm_ctx_cleanup(bbfdm_ctx); + + return 0; +} + +int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx) +{ + return bbfdm_ubus_register_init(bbfdm_ctx); } int bbfdm_ubus_regiter_free(struct bbfdm_context *bbfdm_ctx) { - free_apply_handlers(&bbfdm_ctx->config); - free_changed_uci(bbfdm_ctx); - ubus_unregister_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event); - free_ubus_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers); - bbfdm_ctx_cleanup(bbfdm_ctx); - uloop_done(); - ubus_shutdown(&bbfdm_ctx->ubus_ctx); - - return 0; + return bbfdm_ubus_register_free(bbfdm_ctx); } void bbfdm_ubus_set_service_name(struct bbfdm_context *bbfdm_ctx, const char *srv_name) diff --git a/libbbfdm-ubus/bbfdm-ubus.h b/libbbfdm-ubus/bbfdm-ubus.h index 9f065c63..8ddc1f0b 100644 --- a/libbbfdm-ubus/bbfdm-ubus.h +++ b/libbbfdm-ubus/bbfdm-ubus.h @@ -32,22 +32,30 @@ typedef struct bbfdm_config { struct bbfdm_context { bbfdm_config_t config; struct ubus_event_handler apply_event; - struct ubus_context ubus_ctx; + struct ubus_context *ubus_ctx; + struct ubus_object ubus_obj; struct list_head event_handlers; - struct uloop_timeout sync_timer; struct list_head changed_uci; + bool internal_ubus_ctx; char uci_change_proto[10]; }; typedef struct bbfdm_data { struct ubus_context *ctx; + struct ubus_object *obj; struct ubus_request_data *req; struct list_head *plist; struct dmctx bbf_ctx; struct blob_buf bb; } bbfdm_data_t; +int bbfdm_ubus_register_init(struct bbfdm_context *bbfdm_ctx); +int bbfdm_ubus_register_free(struct bbfdm_context *bbfdm_ctx); + +__attribute__((deprecated("Use bbfdm_ubus_register_init() instead of bbfdm_ubus_regiter_init()"))) int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx); + +__attribute__((deprecated("Use bbfdm_ubus_register_free() instead of bbfdm_ubus_regiter_free()"))) int bbfdm_ubus_regiter_free(struct bbfdm_context *bbfdm_ctx); int bbfdm_print_data_model_schema(struct bbfdm_context *bbfdm_ctx, const enum bbfdm_type_enum type); diff --git a/libbbfdm-ubus/events.c b/libbbfdm-ubus/events.c index f7b1838c..a737613b 100644 --- a/libbbfdm-ubus/events.c +++ b/libbbfdm-ubus/events.c @@ -26,7 +26,7 @@ struct dm_path_node { struct ev_handler_node { char *ev_name; - struct ubus_event_handler *ev_handler; + struct ubus_event_handler ev_handler; struct list_head dm_paths_list; // For dm path list struct list_head list; // For event list }; @@ -68,26 +68,22 @@ void event_callback(const void *arg1, void *arg2) free(e_args); } -static void bbfdm_event_handler(struct ubus_context *ctx, struct ubus_event_handler *ev, - const char *type, struct blob_attr *msg) +static void bbfdm_event_handler_cb(struct ubus_context *ctx __attribute__((unused)), struct ubus_event_handler *ev, + const char *type __attribute__((unused)), struct blob_attr *msg) { - (void)ev; struct ev_handler_node *ev_node = NULL; struct dm_path_node *dp_iter = NULL; - struct bbfdm_context *u = NULL; - u = container_of(ctx, struct bbfdm_context, ubus_ctx); - if (u == NULL) { - BBF_ERR("Failed to get the bbfdm context"); + ev_node = container_of(ev, struct ev_handler_node, ev_handler); + if (!ev_node) { + BBF_ERR("Failed to get event node"); return; } - if (!msg || !type) - return; - - ev_node = get_event_node(&u->event_handlers, type); - if (!ev_node) + if (!msg) { + BBF_ERR("Failed to get message from event"); return; + } list_for_each_entry(dp_iter, &ev_node->dm_paths_list, list) { char dm_path[MAX_DM_PATH]; @@ -185,13 +181,8 @@ static void add_ubus_event_handler(struct ubus_context *ctx, const char *ev_name list_add_tail(&node->list, ev_list); node->ev_name = strdup(ev_name); - node->ev_handler = (struct ubus_event_handler *)calloc(1, sizeof(struct ubus_event_handler)); - if (node->ev_handler) { - node->ev_handler->cb = bbfdm_event_handler; - if (ubus_register_event_handler(ctx, node->ev_handler, ev_name) != 0) { - BBF_ERR("Failed to register: %s", ev_name); - } - } + node->ev_handler.cb = bbfdm_event_handler_cb; + ubus_register_event_handler(ctx, &node->ev_handler, ev_name); } add_dm_path(node, dm_path); @@ -250,10 +241,7 @@ void free_ubus_event_handler(struct ubus_context *ctx, struct list_head *ev_list return; list_for_each_entry_safe(iter, tmp, ev_list, list) { - if (iter->ev_handler != NULL) { - ubus_unregister_event_handler(ctx, iter->ev_handler); - free(iter->ev_handler); - } + ubus_unregister_event_handler(ctx, &iter->ev_handler); if (iter->ev_name) free(iter->ev_name); diff --git a/tools/bbf_common.py b/tools/bbf_common.py index 4521a093..8dbd2028 100755 --- a/tools/bbf_common.py +++ b/tools/bbf_common.py @@ -113,19 +113,22 @@ def build_command(plugin, proto): service_name = get_option_value(plugin, "service_name") unified = get_option_value(plugin, "unified_daemon", False) daemon_name = get_option_value(plugin, "daemon_name", "") + schema_option = get_option_value(plugin, "schema_option", "d") # default stays 'd' if not service_name: return None # skip this plugin + # Start with base command if unified: base_cmd = f"{daemon_name}" else: base_cmd = f"dm-service -m {service_name}" + # Append protocol-specific schema options if proto == "cwmp": - base_cmd += " -d" + base_cmd += f" -{schema_option}" elif proto == "usp": - base_cmd += " -dd" + base_cmd += f" -{schema_option}{schema_option}" return base_cmd diff --git a/tools/tools_input.json b/tools/tools_input.json index 12e30b54..aa979a1b 100644 --- a/tools/tools_input.json +++ b/tools/tools_input.json @@ -113,6 +113,24 @@ "cp -f /opt/dev/iopsys/wifidmd/bbfdm_service.json /etc/bbfdm/services/wifidmd.json" ] }, + { + "repo": "https://dev.iopsys.eu/multi-ap/decollector.git", + "proto": "git", + "service_name": "decollector", + "unified_daemon": true, + "daemon_name": "/usr/sbin/decollector", + "schema_option": "c", + "compile": [ + "./gitlab-ci/install-dependencies.sh", + "rm -f /etc/supervisor/conf.d/iopsys-supervisord.conf", + "make -C src clean", + "make -C src DECOLLECTOR_BUILD_TR181_PLUGIN='y' CFLAGS+='-DEASYMESH_VERSION=6 -DDECOLLECTOR_BUILD_TR181_PLUGIN -DDECOLLECTOR_VENDOR_EXTENSIONS -DSERVICE_NAME=\\\"decollector\\\" -DCUSTOM_PREFIX=\\\"X_IOPSYS_EU_\\\"'" + ], + "post_install": [ + "cp -f src/decollector /usr/sbin/", + "cp -f /opt/dev/iopsys/decollector/bbfdm_service.json /etc/bbfdm/services/decollector.json" + ] + }, { "repo": "https://dev.iopsys.eu/hal/ethmngr.git", "proto": "git",