Compare commits

...

4 commits

Author SHA1 Message Date
Xiaofeng Meng
366e9a3799
Merge branch 'cherry-pick-a9074206' into 'devel'
adaption for dm-framework

See merge request bbf/bbfdm!1232
2025-11-26 15:50:09 +00:00
Vivek Kumar Dutta
a0347e59b6
Schedules: Fix setting alias 2025-11-25 19:24:45 +05:30
Amin Ben Romdhane
880a7583ca libbbfdm-ubus: fix crash on large Get output 2025-11-24 14:01:18 +01:00
Xiaofeng Meng
bb85e2c7df
adaption for dm-framework
(cherry picked from commit a9074206cb)

Co-authored-by: Xiaofeng Meng <x.meng@genexis.eu>
2025-10-24 11:09:02 +00:00
9 changed files with 172 additions and 22 deletions

View file

@ -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);

View file

@ -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, &registered_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);

View file

@ -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);

View file

@ -367,13 +367,13 @@ int bbfdm_set_handler(struct ubus_context *ctx, struct ubus_object *obj,
fault = fill_pvlist_set(path, value, type, tb[DM_SET_OBJ_PATH], &pv_list);
if (fault) {
BBF_ERR("Fault in fill pvlist set path |%s| : |%d|", data.bbf_ctx.in_param, fault);
fill_err_code_array(&data, fault);
fill_err_code_array(&data, &data.bb, fault);
goto end;
}
if (list_empty(&pv_list)) {
BBF_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);
fill_err_code_array(&data, &data.bb, USP_FAULT_INTERNAL_ERROR);
goto end;
}

View file

@ -20,7 +20,7 @@ bool validate_msglen(bbfdm_data_t *data)
BBF_ERR("Blob exceed max len(%d), data len(%zd)", DEF_IPC_DATA_LEN, data_len);
blob_buf_free(&data->bbf_ctx.bb);
blob_buf_init(&data->bbf_ctx.bb, 0);
fill_err_code_table(data, FAULT_9002);
fill_err_code_array(data, &data->bbf_ctx.bb, FAULT_9002);
return false;
}

View file

@ -167,13 +167,13 @@ void fill_err_code_table(bbfdm_data_t *data, int fault)
blobmsg_close_table(&data->bb, table);
}
void fill_err_code_array(bbfdm_data_t *data, int fault)
void fill_err_code_array(bbfdm_data_t *data, struct blob_buf *bb, int fault)
{
void *array = blobmsg_open_array(&data->bb, "results");
void *table = blobmsg_open_table(&data->bb, NULL);
bb_add_string(&data->bb, "path", data->bbf_ctx.in_param);
blobmsg_add_u32(&data->bb, "fault", bbf_fault_map(&data->bbf_ctx, fault));
bb_add_string(&data->bb, "fault_msg", data->bbf_ctx.fault_msg);
blobmsg_close_table(&data->bb, table);
blobmsg_close_array(&data->bb, array);
void *array = blobmsg_open_array(bb, "results");
void *table = blobmsg_open_table(bb, NULL);
bb_add_string(bb, "path", data->bbf_ctx.in_param);
blobmsg_add_u32(bb, "fault", bbf_fault_map(&data->bbf_ctx, fault));
bb_add_string(bb, "fault_msg", data->bbf_ctx.fault_msg);
blobmsg_close_table(bb, table);
blobmsg_close_array(bb, array);
}

View file

@ -34,7 +34,7 @@ void add_path_list(const char *param, struct list_head *plist);
void free_path_list(struct list_head *plist);
void fill_err_code_table(bbfdm_data_t *data, int fault);
void fill_err_code_array(bbfdm_data_t *data, int fault);
void fill_err_code_array(bbfdm_data_t *data, struct blob_buf *bb, int fault);
void bb_add_string(struct blob_buf *bb, const char *name, const char *value);

View file

@ -256,6 +256,7 @@ static int get_schedule_alias(char *refparam, struct dmctx *ctx, void *data, cha
static int set_schedule_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
int ret = 0;
char buffer[256] = {0};
switch (action) {
case VALUECHECK:
@ -278,7 +279,8 @@ static int set_schedule_alias(char *refparam, struct dmctx *ctx, void *data, cha
break;
case VALUESET:
dmuci_rename_section_by_section(((struct dm_data *)data)->config_section, value);
dmuci_set_value_by_section(((struct dm_data *)data)->dmmap_section, "__section_name__", value);
snprintf(buffer, sizeof(buffer), "schedules.%s", value);
dmuci_set_value_by_section(((struct dm_data *)data)->dmmap_section, "__section_name__", buffer);
dmuci_set_value_by_section(((struct dm_data *)data)->dmmap_section, "Alias", value);
break;
}

View file

@ -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;