mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Support multiple DM paths for the same UBUS event
This commit is contained in:
parent
8c1517dab6
commit
16ed3a79e3
2 changed files with 124 additions and 87 deletions
|
|
@ -29,13 +29,6 @@ struct bbfdm_context {
|
|||
struct list_head event_handlers;
|
||||
};
|
||||
|
||||
struct ev_handler_node {
|
||||
char *dm_path;
|
||||
char *ev_name;
|
||||
struct ubus_event_handler *ev_handler;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
typedef struct bbfdm_data {
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data *req;
|
||||
|
|
|
|||
|
|
@ -19,16 +19,28 @@ struct event_args {
|
|||
char method_name[256];
|
||||
};
|
||||
|
||||
static char *get_events_dm_path(struct list_head *ev_list, const char *event)
|
||||
struct dm_path_node {
|
||||
char *dm_path;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct ev_handler_node {
|
||||
char *ev_name;
|
||||
struct ubus_event_handler *ev_handler;
|
||||
struct list_head dm_paths_list; // For dm path list
|
||||
struct list_head list; // For event list
|
||||
};
|
||||
|
||||
static struct ev_handler_node *get_event_node(struct list_head *ev_list, const char *event_name)
|
||||
{
|
||||
struct ev_handler_node *iter = NULL;
|
||||
|
||||
if (ev_list == NULL || event == NULL)
|
||||
if (!ev_list || !event_name)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(iter, ev_list, list) {
|
||||
if (iter->ev_name && strcmp(iter->ev_name, event) == 0)
|
||||
return iter->dm_path;
|
||||
if (iter->ev_name && strcmp(iter->ev_name, event_name) == 0)
|
||||
return iter;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
@ -60,7 +72,9 @@ static void bbfdm_event_handler(struct ubus_context *ctx, struct ubus_event_hand
|
|||
const char *type, struct blob_attr *msg)
|
||||
{
|
||||
(void)ev;
|
||||
struct bbfdm_context *u;
|
||||
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) {
|
||||
|
|
@ -71,83 +85,120 @@ static void bbfdm_event_handler(struct ubus_context *ctx, struct ubus_event_hand
|
|||
if (!msg || !type)
|
||||
return;
|
||||
|
||||
char *event_dm_path = get_events_dm_path(&u->event_handlers, type);
|
||||
if (event_dm_path == NULL)
|
||||
ev_node = get_event_node(&u->event_handlers, type);
|
||||
if (!ev_node)
|
||||
return;
|
||||
|
||||
char dm_path[MAX_DM_PATH];
|
||||
list_for_each_entry(dp_iter, &ev_node->dm_paths_list, list) {
|
||||
char dm_path[MAX_DM_PATH];
|
||||
|
||||
replace_str(event_dm_path, ".{i}.", ".*.", dm_path, sizeof(dm_path));
|
||||
if (strlen(dm_path) == 0)
|
||||
return;
|
||||
replace_str(dp_iter->dm_path, ".{i}.", ".*.", dm_path, sizeof(dm_path));
|
||||
if (strlen(dm_path) == 0)
|
||||
return;
|
||||
|
||||
char *str = blobmsg_format_json(msg, true);
|
||||
char *str = blobmsg_format_json(msg, true);
|
||||
|
||||
struct dmctx bbf_ctx = {
|
||||
.in_param = dm_path,
|
||||
.in_value = str,
|
||||
.nextlevel = false,
|
||||
.iscommand = false,
|
||||
.isevent = true,
|
||||
.isinfo = false,
|
||||
.dm_type = BBFDM_USP
|
||||
};
|
||||
struct dmctx bbf_ctx = {
|
||||
.in_param = dm_path,
|
||||
.in_value = str,
|
||||
.nextlevel = false,
|
||||
.iscommand = false,
|
||||
.isevent = true,
|
||||
.isinfo = false,
|
||||
.dm_type = BBFDM_USP
|
||||
};
|
||||
|
||||
bbf_init(&bbf_ctx);
|
||||
bbf_init(&bbf_ctx);
|
||||
|
||||
int ret = bbfdm_cmd_exec(&bbf_ctx, BBF_EVENT);
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
size_t blob_data_len = blob_raw_len(bbf_ctx.bb.head);
|
||||
|
||||
if (blob_data_len) {
|
||||
struct event_args *e_args = (struct event_args *)calloc(1, sizeof(struct event_args));
|
||||
if (!e_args)
|
||||
int ret = bbfdm_cmd_exec(&bbf_ctx, BBF_EVENT);
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
snprintf(e_args->method_name, sizeof(e_args->method_name), "%s.event", BBFDM_DEFAULT_UBUS_OBJ);
|
||||
size_t blob_data_len = blob_raw_len(bbf_ctx.bb.head);
|
||||
|
||||
e_args->blob_data = (struct blob_attr *)calloc(1, blob_data_len);
|
||||
if (blob_data_len) {
|
||||
struct event_args *e_args = (struct event_args *)calloc(1, sizeof(struct event_args));
|
||||
if (!e_args)
|
||||
goto end;
|
||||
|
||||
memcpy(e_args->blob_data, bbf_ctx.bb.head, blob_data_len);
|
||||
snprintf(e_args->method_name, sizeof(e_args->method_name), "%s.event", BBFDM_DEFAULT_UBUS_OBJ);
|
||||
|
||||
bbfdm_task_schedule(event_callback, NULL, e_args, 6);
|
||||
e_args->blob_data = (struct blob_attr *)calloc(1, blob_data_len);
|
||||
|
||||
memcpy(e_args->blob_data, bbf_ctx.bb.head, blob_data_len);
|
||||
|
||||
bbfdm_task_schedule(event_callback, NULL, e_args, 6);
|
||||
}
|
||||
|
||||
end:
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
FREE(str);
|
||||
}
|
||||
|
||||
end:
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
FREE(str);
|
||||
}
|
||||
|
||||
static void add_ubus_event_handler(struct ubus_event_handler *ev, const char *ev_name, const char *dm_path, struct list_head *ev_list)
|
||||
static void add_dm_path(struct ev_handler_node *node, const char *dm_path)
|
||||
{
|
||||
if (ev == NULL || ev_list == NULL)
|
||||
struct dm_path_node *dp_iter = NULL;
|
||||
|
||||
if (!node || !dm_path)
|
||||
return;
|
||||
|
||||
struct ev_handler_node *node = NULL;
|
||||
// Prevent duplicate dm_paths
|
||||
list_for_each_entry(dp_iter, &node->dm_paths_list, list) {
|
||||
if (strcmp(dp_iter->dm_path, dm_path) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
node = (struct ev_handler_node *)calloc(1, sizeof(struct ev_handler_node));
|
||||
if (!node) {
|
||||
BBF_ERR("Out of memory!");
|
||||
struct dm_path_node *dp_node = (struct dm_path_node *)calloc(1, sizeof(struct dm_path_node));
|
||||
if (!dp_node) {
|
||||
BBF_ERR("Out of memory adding DM path!");
|
||||
return;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&node->list);
|
||||
list_add_tail(&node->list, ev_list);
|
||||
INIT_LIST_HEAD(&dp_node->list);
|
||||
|
||||
node->ev_handler = ev;
|
||||
node->ev_name = ev_name ? strdup(ev_name) : NULL;
|
||||
node->dm_path = dm_path ? strdup(dm_path) : NULL;
|
||||
dp_node->dm_path = strdup(dm_path);
|
||||
|
||||
list_add_tail(&dp_node->list, &node->dm_paths_list);
|
||||
}
|
||||
|
||||
static void add_ubus_event_handler(struct ubus_context *ctx, const char *ev_name, const char *dm_path, struct list_head *ev_list)
|
||||
{
|
||||
struct ev_handler_node *node;
|
||||
|
||||
if (!ctx || !ev_name || !dm_path || !ev_list)
|
||||
return;
|
||||
|
||||
node = get_event_node(ev_list, ev_name);
|
||||
|
||||
if (!node) {
|
||||
// Create a new event node
|
||||
node = (struct ev_handler_node *)calloc(1, sizeof(struct ev_handler_node));
|
||||
if (!node) {
|
||||
BBF_ERR("Out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&node->list);
|
||||
INIT_LIST_HEAD(&node->dm_paths_list);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_dm_path(node, dm_path);
|
||||
}
|
||||
|
||||
int register_events_to_ubus(struct ubus_context *ctx, struct list_head *ev_list)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (ctx == NULL || ev_list == NULL)
|
||||
return -1;
|
||||
|
||||
struct dmctx bbf_ctx = {
|
||||
.in_param = ROOT_NODE,
|
||||
.nextlevel = false,
|
||||
|
|
@ -157,6 +208,9 @@ int register_events_to_ubus(struct ubus_context *ctx, struct list_head *ev_list)
|
|||
.dm_type = BBFDM_USP
|
||||
};
|
||||
|
||||
if (ctx == NULL || ev_list == NULL)
|
||||
return -1;
|
||||
|
||||
bbf_init(&bbf_ctx);
|
||||
|
||||
if (0 == bbfdm_cmd_exec(&bbf_ctx, BBF_SCHEMA)) {
|
||||
|
|
@ -178,50 +232,40 @@ int register_events_to_ubus(struct ubus_context *ctx, struct list_head *ev_list)
|
|||
if (!param_name || !event_name || !strlen(event_name))
|
||||
continue;
|
||||
|
||||
struct ubus_event_handler *ev = (struct ubus_event_handler *)calloc(1, sizeof(struct ubus_event_handler));
|
||||
if (!ev) {
|
||||
BBF_ERR("Out of memory!");
|
||||
err = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ev->cb = bbfdm_event_handler;
|
||||
|
||||
if (0 != ubus_register_event_handler(ctx, ev, event_name)) {
|
||||
BBF_ERR("Failed to register: %s", event_name);
|
||||
err = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
add_ubus_event_handler(ev, event_name, param_name, ev_list);
|
||||
add_ubus_event_handler(ctx, event_name, param_name, ev_list);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_ubus_event_handler(struct ubus_context *ctx, struct list_head *ev_list)
|
||||
{
|
||||
struct ev_handler_node *iter = NULL, *node = NULL;
|
||||
{
|
||||
struct ev_handler_node *iter = NULL, *tmp = NULL;
|
||||
struct dm_path_node *dp_iter = NULL, *dp_tmp = NULL;
|
||||
|
||||
if (ctx == NULL || ev_list == NULL)
|
||||
if (!ctx || !ev_list)
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(iter, node, ev_list, list) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (iter->dm_path)
|
||||
free(iter->dm_path);
|
||||
|
||||
if (iter->ev_name)
|
||||
free(iter->ev_name);
|
||||
|
||||
list_for_each_entry_safe(dp_iter, dp_tmp, &iter->dm_paths_list, list) {
|
||||
if (dp_iter->dm_path)
|
||||
free(dp_iter->dm_path);
|
||||
|
||||
list_del(&dp_iter->list);
|
||||
free(dp_iter);
|
||||
}
|
||||
|
||||
list_del(&iter->list);
|
||||
free(iter);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue