From bb85e2c7dff4a5a13371a47e7c043b13542c778d Mon Sep 17 00:00:00 2001 From: Xiaofeng Meng Date: Fri, 24 Oct 2025 11:09:02 +0000 Subject: [PATCH] adaption for dm-framework (cherry picked from commit a9074206cb0a86ed9130a8e821de2031115fb21c) Co-authored-by: Xiaofeng Meng --- bbfdmd/ubus/bbfdmd.c | 36 +++++++++-- bbfdmd/ubus/service.c | 20 ++++-- bbfdmd/ubus/service.h | 3 +- utilities/src/ubus/bbf_config.c | 107 ++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 9 deletions(-) diff --git a/bbfdmd/ubus/bbfdmd.c b/bbfdmd/ubus/bbfdmd.c index d7ce3ce5..07e2696d 100644 --- a/bbfdmd/ubus/bbfdmd.c +++ b/bbfdmd/ubus/bbfdmd.c @@ -25,6 +25,19 @@ #include "get.h" #include "cli.h" +/* Policy for services method (optional filter by service name and framework flag) */ +enum services_attr { + SERVICES_NAME, + SERVICES_FRAMEWORK_ONLY, + __SERVICES_MAX +}; + +static const struct blobmsg_policy services_policy[] = { + [SERVICES_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, + [SERVICES_FRAMEWORK_ONLY] = { .name = "dmf_only", .type = BLOBMSG_TYPE_BOOL }, +}; + + struct ubus_context g_ubus_ctx = {0}; extern struct list_head registered_services; @@ -367,16 +380,31 @@ static int bbfdm_handler_sync(struct ubus_context *ctx, struct ubus_object *obj, } static int bbfdm_services_handler(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, struct blob_attr *msg __attribute__((unused))) + struct ubus_request_data *req, const char *method, struct blob_attr *msg __attribute__((unused))) { - struct blob_buf bb; + struct blob_attr *tb[__SERVICES_MAX] = {0}; + struct blob_buf bb = {0}; + + if (msg) + blobmsg_parse(services_policy, __SERVICES_MAX, tb, blob_data(msg), blob_len(msg)); + + const char *filter_name = NULL; + if (tb[SERVICES_NAME]) + filter_name = blobmsg_get_string(tb[SERVICES_NAME]); + + bool framework_only = false; + if (tb[SERVICES_FRAMEWORK_ONLY]) + framework_only = blobmsg_get_bool(tb[SERVICES_FRAMEWORK_ONLY]); + + BBFDM_INFO("ubus method|%s|, name|%s|, filter|%s|, framework_only|%d|", method, obj->name, filter_name ? filter_name : "", framework_only); + BBFDM_INFO("ubus method|%s|, name|%s|", method, obj->name); memset(&bb, 0, sizeof(struct blob_buf)); blob_buf_init(&bb, 0); - list_registered_services(&bb); + list_registered_services(&bb, filter_name, framework_only); ubus_send_reply(ctx, req, bb.head); blob_buf_free(&bb); @@ -392,7 +420,7 @@ static struct ubus_method bbfdm_methods[] = { UBUS_METHOD("set", bbfdm_handler_sync, bbfdm_policy), UBUS_METHOD("add", bbfdm_handler_sync, bbfdm_policy), UBUS_METHOD("del", bbfdm_handler_sync, bbfdm_policy), - UBUS_METHOD_NOARG("services", bbfdm_services_handler) + UBUS_METHOD("services", bbfdm_services_handler, services_policy) }; static struct ubus_object_type bbfdm_object_type = UBUS_OBJECT_TYPE(BBFDM_UBUS_OBJECT, bbfdm_methods); diff --git a/bbfdmd/ubus/service.c b/bbfdmd/ubus/service.c index a914b654..2f65f500 100644 --- a/bbfdmd/ubus/service.c +++ b/bbfdmd/ubus/service.c @@ -23,7 +23,7 @@ LIST_HEAD(registered_services); static void add_service_to_list(const char *name, struct blob_buf *dm_schema, int service_proto, int service_timeout, - service_object_t *objects, size_t count, bool is_unified) + service_object_t *objects, size_t count, bool is_unified, bool dm_framework) { service_entry_t *service = NULL; @@ -47,6 +47,7 @@ static void add_service_to_list(const char *name, struct blob_buf *dm_schema, in service->objects = objects; service->object_count = count; service->is_unified = is_unified; + service->dm_framework = dm_framework; } static void receive_schema_result(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg) @@ -153,9 +154,13 @@ static int load_service_from_file(struct ubus_context *ubus_ctx, const char *fil fill_service_schema(ubus_ctx, 2000, service_name, &service_schema); json_object *unified_daemon_jobj = NULL; + json_object *dm_framework_jobj = NULL; json_object_object_get_ex(daemon_config, "unified_daemon", &unified_daemon_jobj); bool is_unified = unified_daemon_jobj ? json_object_get_boolean(unified_daemon_jobj) : false; + json_object_object_get_ex(daemon_config, "dm-framework", &dm_framework_jobj); + bool dm_framework = dm_framework_jobj ? json_object_get_boolean(dm_framework_jobj) : false; + json_object *proto_jobj = NULL; json_object_object_get_ex(daemon_config, "proto", &proto_jobj); int service_proto = get_proto_type(proto_jobj ? json_object_get_string(proto_jobj) : ""); @@ -204,8 +209,8 @@ static int load_service_from_file(struct ubus_context *ubus_ctx, const char *fil num_objs++; } - BBFDM_INFO("Registering [%s :: %lu :: %d]", service_name, num_objs, is_unified); - add_service_to_list(service_name, service_schema, service_proto, service_timeout, objects, num_objs, is_unified); + BBFDM_INFO("Registering [%s :: %lu :: %d :: %d]", service_name, num_objs, is_unified, dm_framework); + add_service_to_list(service_name, service_schema, service_proto, service_timeout, objects, num_objs, is_unified, dm_framework); json_object_put(json_root); return 0; } @@ -274,7 +279,7 @@ void unregister_services(void) } } -void list_registered_services(struct blob_buf *bb) +void list_registered_services(struct blob_buf *bb, const char *filter_name, bool framework_only) { service_entry_t *service = NULL; @@ -284,6 +289,12 @@ void list_registered_services(struct blob_buf *bb) void *array = blobmsg_open_array(bb, "registered_services"); list_for_each_entry(service, ®istered_services, list) { + if (filter_name && strlen(filter_name) > 0 && service->name && strcmp(filter_name, service->name) != 0) + continue; + + if (framework_only && !service->dm_framework) + continue; + void *table = blobmsg_open_table(bb, NULL); blobmsg_add_string(bb, "name", service->name ? service->name : ""); @@ -292,6 +303,7 @@ void list_registered_services(struct blob_buf *bb) service->protocol == BBFDMD_CWMP ? "cwmp" : "both"); blobmsg_add_u8(bb, "unified_daemon", service->is_unified); + blobmsg_add_u8(bb, "dm_framework", service->dm_framework); blobmsg_add_u8(bb, "blacklisted", service->is_blacklisted); blobmsg_add_u32(bb, "timeout", service->timeout); diff --git a/bbfdmd/ubus/service.h b/bbfdmd/ubus/service.h index 42530012..45e32938 100644 --- a/bbfdmd/ubus/service.h +++ b/bbfdmd/ubus/service.h @@ -24,6 +24,7 @@ typedef struct service_entry { char *name; enum bbfdmd_type_enum protocol; bool is_unified; + bool dm_framework; // Indicates if the service is managed by dm-framework size_t object_count; service_object_t *objects; int timeout; // Ubus timeout used to get data from lower layer @@ -33,7 +34,7 @@ typedef struct service_entry { int register_services(struct ubus_context *ctx); void unregister_services(void); -void list_registered_services(struct blob_buf *bb); +void list_registered_services(struct blob_buf *bb, const char *filter_name, bool framework_only); void fill_service_schema(struct ubus_context *ubus_ctx, int ubus_timeout, const char *service_name, struct blob_buf **service_schema); bool service_path_match(const char *requested_path, unsigned int requested_proto, service_entry_t *service); diff --git a/utilities/src/ubus/bbf_config.c b/utilities/src/ubus/bbf_config.c index 1ba26851..039922f4 100644 --- a/utilities/src/ubus/bbf_config.c +++ b/utilities/src/ubus/bbf_config.c @@ -19,6 +19,110 @@ #include "utils.h" +struct trans_ctx { + struct ubus_context *ctx; + const char *cmd; /* "commit" or "abort" */ + const char *proto; /* proto from commit/revert input */ +}; + + +/* ------------------------------------------------------------------ */ +/* DM-framework service transaction helpers */ +/* ------------------------------------------------------------------ */ +static void invoke_service_transaction(struct ubus_context *ctx, const char *service_name, + const char *cmd, const char *proto) +{ + if (!ctx || !service_name || !cmd) + return; + + struct blob_buf bb = {0}; + + blob_buf_init(&bb, 0); + blobmsg_add_string(&bb, "cmd", cmd); + + if (proto && strlen(proto)) { + void *tbl = blobmsg_open_table(&bb, "optional"); + blobmsg_add_string(&bb, "proto", proto); + blobmsg_close_table(&bb, tbl); + } + + if (bbf_config_call(ctx, service_name, "transaction", &bb, NULL, NULL)) { + ULOG_ERR("Failed '%s' transaction for service '%s'", cmd, service_name); + } else { + ULOG_INFO("Service '%s' transaction '%s' succeeded", service_name, cmd); + } + + blob_buf_free(&bb); +} + +/* Callback used when querying bbfdm 'services' */ +static void services_list_cb(struct ubus_request *req, int type __attribute__((unused)), struct blob_attr *msg) +{ + struct trans_ctx *tctx = (struct trans_ctx *)req->priv; + if (!tctx || !msg) + return; + + /* Expecting { "registered_services": [ {...}, ... ] } */ + struct blob_attr *rs_array = NULL; + struct blob_attr *cur; + int rem = blob_len(msg); + + /* Find the array first */ + blob_for_each_attr(cur, msg, rem) { + if (blobmsg_type(cur) == BLOBMSG_TYPE_ARRAY && strcmp(blobmsg_name(cur), "registered_services") == 0) { + rs_array = cur; + break; + } + } + + if (!rs_array) + return; + + const struct blobmsg_policy pol[] = { + { "name", BLOBMSG_TYPE_STRING }, + { "proto", BLOBMSG_TYPE_STRING }, + }; + + struct blob_attr *entry; + blobmsg_for_each_attr(entry, rs_array, rem) { + struct blob_attr *tb[2] = {0}; + blobmsg_parse(pol, 2, tb, blobmsg_data(entry), blobmsg_len(entry)); + + if (!tb[0]) + continue; + + const char *sname = blobmsg_get_string(tb[0]); + const char *proto = (tctx->proto) ? tctx->proto : "both"; + ULOG_ERR("Invoking service transaction for service: %s, cmd: %s, proto: %s", sname, tctx->cmd, proto); + invoke_service_transaction(tctx->ctx, sname, tctx->cmd, proto); + } +} + +static void trigger_dfm_service_transactions(struct ubus_context *ctx, const char *cmd, const char *proto) +{ + if (!ctx || !cmd) + return; + + ULOG_ERR("Triggering dm-framework service transactions cmd: %s, proto: %s", cmd, proto); + + struct blob_buf bb = {0}; + blob_buf_init(&bb, 0); + blobmsg_add_u8(&bb, "dmf_only", true); + + struct trans_ctx tctx = { + .ctx = ctx, + .cmd = cmd, + .proto = proto, + }; + + /* Query bbfdm -> services */ + if (bbf_config_call(ctx, "bbfdm", "services", &bb, services_list_cb, &tctx)) { + ULOG_ERR("Failed to retrieve dm-framework services list from bbfdm"); + } + + blob_buf_free(&bb); +} + #define TIME_TO_WAIT_FOR_RELOAD 5 #define MAX_PACKAGE_NUM 256 #define MAX_SERVICE_NUM 16 @@ -703,6 +807,7 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec #endif } + trigger_dfm_service_transactions(ctx, "commit", tb[SERVICES_PROTO] ? blobmsg_get_string(tb[SERVICES_PROTO]) : "both"); struct blob_attr *services = tb[SERVICES_NAME]; size_t arr_len = (services) ? blobmsg_len(services) : 0; @@ -802,6 +907,8 @@ static int bbf_config_revert_handler(struct ubus_context *ctx, struct ubus_objec ULOG_DEBUG("Protocol index determined as %d for protocol '%s'", idx, proto); } + trigger_dfm_service_transactions(ctx, "abort", tb[SERVICES_PROTO] ? blobmsg_get_string(tb[SERVICES_PROTO]) : "both"); + struct blob_attr *services = tb[SERVICES_NAME]; size_t arr_len = (services) ? blobmsg_len(services) : 0;