From 3d83590251ff97d65d58ecafb41fbc91a463b27b Mon Sep 17 00:00:00 2001 From: Vivek Kumar Dutta Date: Wed, 6 Mar 2024 04:17:26 +0000 Subject: [PATCH] microservice: add support to register multiple objects --- bbfdmd/ubus/bbfdmd.c | 56 ++++++++++++++++++++++++++++----- bbfdmd/ubus/bbfdmd.h | 3 ++ bbfdmd/ubus/plugin.c | 68 ++++++++++++++++++++++++++++------------- libbbfdm-api/dmplugin.c | 8 +++-- 4 files changed, 103 insertions(+), 32 deletions(-) diff --git a/bbfdmd/ubus/bbfdmd.c b/bbfdmd/ubus/bbfdmd.c index cb5d7013..c766bff8 100644 --- a/bbfdmd/ubus/bbfdmd.c +++ b/bbfdmd/ubus/bbfdmd.c @@ -950,6 +950,7 @@ enum { BBF_SERVICE_NAME, BBF_SERVICE_PARENT_DM, BBF_SERVICE_OBJECT, + BBF_SERVICE_MULTI_OBJECTS, __BBF_SERVICE_MAX, }; @@ -958,6 +959,7 @@ static const struct blobmsg_policy service_policy[] = { [BBF_SERVICE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, [BBF_SERVICE_PARENT_DM] = { .name = "parent_dm", .type = BLOBMSG_TYPE_STRING }, [BBF_SERVICE_OBJECT] = { .name = "object", .type = BLOBMSG_TYPE_STRING }, + [BBF_SERVICE_MULTI_OBJECTS] = { .name = "multiple_objects", .type = BLOBMSG_TYPE_ARRAY }, }; static void service_list(struct blob_buf *bb) @@ -1026,16 +1028,31 @@ static int bbfdm_service_handler(struct ubus_context *ctx, struct ubus_object *o goto end; } - if (!tb[BBF_SERVICE_OBJECT]) { - blobmsg_add_string(&bb, "error", "service object should be defined!!"); + if (!tb[BBF_SERVICE_OBJECT] && !tb[BBF_SERVICE_MULTI_OBJECTS]) { + blobmsg_add_string(&bb, "error", "service object/multiple_objects should be defined!!"); goto end; } char *srv_name = blobmsg_get_string(tb[BBF_SERVICE_NAME]); char *srv_parent_dm = blobmsg_get_string(tb[BBF_SERVICE_PARENT_DM]); - char *srv_obj = blobmsg_get_string(tb[BBF_SERVICE_OBJECT]); + char *srv_obj = NULL; + bool res = true; - bool res = load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj); + if (tb[BBF_SERVICE_MULTI_OBJECTS]) { + struct blob_attr *objs = tb[BBF_SERVICE_MULTI_OBJECTS]; + struct blob_attr *obj = NULL; + size_t rem; + + blobmsg_for_each_attr(obj, objs, rem) { + srv_obj = blobmsg_get_string(obj); + res |= load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj); + } + } else if (tb[BBF_SERVICE_OBJECT]) { + srv_obj = blobmsg_get_string(tb[BBF_SERVICE_OBJECT]); + res = load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj); + } else { + res = false; + } blobmsg_add_u8(&bb, "status", res); run_schema_updater(u); @@ -1345,7 +1362,7 @@ static void periodic_instance_updater(struct uloop_timeout *t) static bool register_service(struct ubus_context *ctx) { - struct blob_buf bb; + struct blob_buf bb = {0}; uint32_t ubus_id; struct bbfdm_context *u; @@ -1365,7 +1382,15 @@ static bool register_service(struct ubus_context *ctx) blobmsg_add_string(&bb, "cmd", "register"); blobmsg_add_string(&bb, "name", u->config.out_name); blobmsg_add_string(&bb, "parent_dm", u->config.out_parent_dm); - blobmsg_add_string(&bb, "object", u->config.out_object); + + if (DM_STRLEN(u->config.multi_object[0]) != 0) { + void *arr = blobmsg_open_array(&bb, "multiple_objects"); + for (int i = 0; i < MAX_MULTI_OBJS && DM_STRLEN(u->config.multi_object[i]) != 0; i++) + blobmsg_add_string(&bb, NULL, u->config.multi_object[i]); + blobmsg_close_array(&bb, arr); + } else { + blobmsg_add_string(&bb, "object", u->config.out_object); + } ubus_invoke(ctx, ubus_id, "service", bb.head, NULL, NULL, 5000); blob_buf_free(&bb); @@ -1435,6 +1460,19 @@ static int bbfdm_load_deamon_config(bbfdm_config_t *config, const char *json_pat replace_str(opt_val, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, config->out_object, sizeof(config->out_object)); } + json_object *arr_obj = NULL; + char *mem_obj = NULL; + int i = 0; + + dmjson_foreach_value_in_array(deamon_obj, arr_obj, mem_obj, i, 2, "output", "multiple_objects") { + if (i < MAX_MULTI_OBJS) { + replace_str(mem_obj, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, config->multi_object[i], sizeof(config->multi_object[i])); + } else { + WARNING("More multiple_object defined, can handle only %d ...", MAX_MULTI_OBJS); + break; + } + } + opt_val = dmjson_get_value(deamon_obj, 2, "output", "root_obj"); if (DM_STRLEN(opt_val)) { strncpyt(config->out_root_obj, opt_val, sizeof(config->out_root_obj)); @@ -1637,10 +1675,12 @@ int daemon_load_datamodel(struct bbfdm_context *daemon_ctx) ERR("output parent dm not defined"); return -1; } - if (DM_STRLEN(daemon_ctx->config.out_object) == 0) { - ERR("output object not defined"); + + if (DM_STRLEN(daemon_ctx->config.out_object) == 0 && DM_STRLEN(daemon_ctx->config.multi_object[0]) == 0) { + ERR("output object and multiple_objects both are not defined"); return -1; } + if (DM_STRLEN(daemon_ctx->config.out_root_obj) == 0) { ERR("output root obj not defined"); return -1; diff --git a/bbfdmd/ubus/bbfdmd.h b/bbfdmd/ubus/bbfdmd.h index 1aa9be23..f1df904f 100644 --- a/bbfdmd/ubus/bbfdmd.h +++ b/bbfdmd/ubus/bbfdmd.h @@ -7,6 +7,8 @@ #include "dmbbf.h" +#define MAX_MULTI_OBJS 5 + struct bbfdm_async_req { struct ubus_context *ctx; struct ubus_request_data req; @@ -28,6 +30,7 @@ typedef struct bbfdm_config { char out_name[32]; char out_parent_dm[32]; char out_object[32]; + char multi_object[MAX_MULTI_OBJS][32]; char out_root_obj[32]; char cli_in_type[32]; char cli_in_name[128]; diff --git a/bbfdmd/ubus/plugin.c b/bbfdmd/ubus/plugin.c index 6eb3a854..eea90d0c 100644 --- a/bbfdmd/ubus/plugin.c +++ b/bbfdmd/ubus/plugin.c @@ -18,6 +18,20 @@ extern struct list_head global_memhead; +static uint8_t find_number_of_objects(DM_MAP_OBJ *dynamic_obj) +{ + if (!dynamic_obj) + return 0; + + uint8_t len = 0; + + while (dynamic_obj[len].path) + len++; + + return len; +} + + int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_entry) { if (!lib_handle || !file_path || !strlen(file_path) || !main_entry) @@ -35,27 +49,35 @@ int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_ent DM_MAP_OBJ *dynamic_obj = NULL; *(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj"); if (dynamic_obj) { - char *node_obj = dm_dynamic_strdup(&global_memhead, dynamic_obj[0].path); - unsigned int len = strlen(node_obj); - - if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') { - ERR("Object (%s) not valid\n", node_obj); + uint8_t obj_num = find_number_of_objects(dynamic_obj); + if (obj_num == 0) { + ERR("No Object defined in the required DotSo Plugin\n"); return -1; } - DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&global_memhead, 2, sizeof(DMOBJ)); + DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&global_memhead, obj_num + 1, sizeof(DMOBJ)); if (dm_entryobj == NULL) { ERR("No Memory exists\n"); return -1; } - node_obj[len-1] = 0; + for (int i = 0; dynamic_obj[i].path; i++) { + char *node_obj = dm_dynamic_strdup(&global_memhead, dynamic_obj[i].path); + unsigned int len = strlen(node_obj); - dm_entryobj[0].obj = node_obj; - dm_entryobj[0].permission = &DMREAD; - dm_entryobj[0].nextobj = dynamic_obj[0].root_obj; - dm_entryobj[0].leaf = dynamic_obj[0].root_leaf; - dm_entryobj[0].bbfdm_type = BBFDM_BOTH; + if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') { + ERR("Object (%s) not valid\n", node_obj); + return -1; + } + + node_obj[len-1] = 0; + + dm_entryobj[i].obj = node_obj; + dm_entryobj[i].permission = &DMREAD; + dm_entryobj[i].nextobj = dynamic_obj[i].root_obj; + dm_entryobj[i].leaf = dynamic_obj[i].root_leaf; + dm_entryobj[i].bbfdm_type = BBFDM_BOTH; + } *main_entry = dm_entryobj; } else { @@ -76,7 +98,9 @@ int free_dotso_plugin(void *lib_handle) int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path, DMOBJ **main_entry) { + DMOBJ *dm_entryobj = NULL; int json_plugin_version = JSON_VERSION_0; + uint8_t idx = 0; if (!file_path || !strlen(file_path) || !main_entry) return -1; @@ -119,24 +143,26 @@ int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, if (obj_prefix[obj_prefix_len - 1] == '.') obj_prefix[obj_prefix_len - 1] = 0; - DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ)); + dm_entryobj = (DMOBJ *)dm_dynamic_realloc(json_memhead, dm_entryobj, (idx + 2) * sizeof(DMOBJ)); if (dm_entryobj == NULL) { ERR("ERROR: No Memory exists\n"); return -1; } - *main_entry = dm_entryobj; + memset(&dm_entryobj[idx + 1], 0, sizeof(DMOBJ)); - dm_entryobj[0].obj = dm_dynamic_strdup(json_memhead, obj_prefix); - dm_entryobj[0].permission = &DMREAD; - dm_entryobj[0].nextobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ)); - dm_entryobj[0].leaf = NULL; - dm_entryobj[0].bbfdm_type = BBFDM_BOTH; + dm_entryobj[idx].obj = dm_dynamic_strdup(json_memhead, obj_prefix); + dm_entryobj[idx].permission = &DMREAD; + dm_entryobj[idx].nextobj = (DMOBJ *)dm_dynamic_calloc(json_memhead, 2, sizeof(DMOBJ)); + dm_entryobj[idx].leaf = NULL; + dm_entryobj[idx].bbfdm_type = BBFDM_BOTH; - parse_obj(node_obj, jobj, dm_entryobj[0].nextobj, 0, json_plugin_version, json_list); - break; + parse_obj(node_obj, jobj, dm_entryobj[idx].nextobj, 0, json_plugin_version, json_list); + + idx++; } + *main_entry = dm_entryobj; return 0; } diff --git a/libbbfdm-api/dmplugin.c b/libbbfdm-api/dmplugin.c index f81f1739..c027c098 100644 --- a/libbbfdm-api/dmplugin.c +++ b/libbbfdm-api/dmplugin.c @@ -59,12 +59,14 @@ static bool add_service_to_main_tree(DMOBJ *main_dm, char *srv_name, char *srv_p return true; } -static bool is_service_registered(struct list_head *srvlist, char *srv_name) +static bool is_service_registered(struct list_head *srvlist, char *srv_name, char *srv_parent_dm, char *srv_obj) { struct service *srv = NULL; list_for_each_entry(srv, srvlist, list) { - if (DM_STRCMP(srv->name, srv_name) == 0) + if (DM_STRCMP(srv->name, srv_name) == 0 && + DM_STRCMP(srv->parent_dm, srv_parent_dm) == 0 && + DM_STRCMP(srv->object, srv_obj) == 0) return true; } @@ -102,7 +104,7 @@ bool load_service(DMOBJ *main_dm, struct list_head *srv_list, char *srv_name, ch if (!main_dm || !srv_list || !srv_name || !srv_parent_dm || !srv_obj) return false; - if (is_service_registered(srv_list, srv_name)) + if (is_service_registered(srv_list, srv_name, srv_parent_dm, srv_obj)) return false; if (!add_service_to_main_tree(main_dm, srv_name, srv_parent_dm, srv_obj))