mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Support loading plugins from microservices
This commit is contained in:
parent
6f7a1ae87e
commit
4ff4f09126
32 changed files with 242 additions and 455 deletions
|
|
@ -86,6 +86,7 @@ run_libbbfdm_memory_test:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
- output-report-device-get.txt
|
- output-report-device-get.txt
|
||||||
|
- memory-*.xml
|
||||||
|
|
||||||
run_bbfd_functional_test:
|
run_bbfd_functional_test:
|
||||||
stage: functional_test
|
stage: functional_test
|
||||||
|
|
@ -102,5 +103,5 @@ run_bbfd_functional_test:
|
||||||
paths:
|
paths:
|
||||||
- funl-result.log
|
- funl-result.log
|
||||||
- funl-test-coverage.xml
|
- funl-test-coverage.xml
|
||||||
- memory-report.xml
|
|
||||||
- report/
|
- report/
|
||||||
|
- memory-*.xml
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@ static int g_subprocess_level = BBF_SUBPROCESS_DEPTH;
|
||||||
static void *deamon_lib_handle = NULL;
|
static void *deamon_lib_handle = NULL;
|
||||||
|
|
||||||
char UBUS_MAIN_METHOD_NAME[32] = "bbfdm";
|
char UBUS_MAIN_METHOD_NAME[32] = "bbfdm";
|
||||||
|
char CONFIG_PLUGIN_PATH[256] = {0};
|
||||||
char UBUS_METHOD_NAME[32] = "bbfdm";
|
char UBUS_METHOD_NAME[32] = "bbfdm";
|
||||||
char PARENT_DM[512] = {0};
|
char PARENT_DM[512] = {0};
|
||||||
char MICRO_SERVICE_OBJ_NAME[64] = {0};
|
char MICRO_SERVICE_OBJ_NAME[64] = {0};
|
||||||
char *input_json = NULL;
|
|
||||||
|
|
||||||
static void sig_handler(int sig)
|
static void sig_handler(int sig)
|
||||||
{
|
{
|
||||||
|
|
@ -84,14 +84,15 @@ static void usage(char *prog)
|
||||||
|
|
||||||
static void bbfdm_cleanup(struct bbfdm_context *u)
|
static void bbfdm_cleanup(struct bbfdm_context *u)
|
||||||
{
|
{
|
||||||
bbf_global_clean(DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, DEAMON_DM_VENDOR_EXTENSION_EXCLUDE, input_json ? false : true);
|
bbf_global_clean(DEAMON_DM_ROOT_OBJ);
|
||||||
|
|
||||||
free_path_list(&u->instances);
|
free_path_list(&u->instances);
|
||||||
free_path_list(&u->old_instances);
|
free_path_list(&u->old_instances);
|
||||||
if (!input_json) { // It's not a micro-service instance
|
if (!is_micro_service) { // It's not a micro-service instance
|
||||||
free_services_from_list(&head_registered_service);
|
free_services_from_list(&head_registered_service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blob_buf_free(&u->dm_schema);
|
||||||
/* DotSo Plugin */
|
/* DotSo Plugin */
|
||||||
free_dotso_plugin(deamon_lib_handle);
|
free_dotso_plugin(deamon_lib_handle);
|
||||||
|
|
||||||
|
|
@ -146,8 +147,6 @@ static void fill_optional_data(bbfdm_data_t *data, struct blob_attr *msg)
|
||||||
data->is_raw = is_str_eq(blobmsg_get_string(attr), "raw") ? true : false;
|
data->is_raw = is_str_eq(blobmsg_get_string(attr), "raw") ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->bbf_ctx.enable_plugins = input_json ? false : true;
|
|
||||||
|
|
||||||
DEBUG("Proto:|%s|, Inst Mode:|%s|, Tran-id:|%d|, Format:|%s|",
|
DEBUG("Proto:|%s|, Inst Mode:|%s|, Tran-id:|%d|, Format:|%s|",
|
||||||
(data->bbf_ctx.dm_type == BBFDM_BOTH) ? "both" : (data->bbf_ctx.dm_type == BBFDM_CWMP) ? "cwmp" : "usp",
|
(data->bbf_ctx.dm_type == BBFDM_BOTH) ? "both" : (data->bbf_ctx.dm_type == BBFDM_CWMP) ? "cwmp" : "usp",
|
||||||
(data->bbf_ctx.instance_mode == 0) ? "Number" : "Alias",
|
(data->bbf_ctx.instance_mode == 0) ? "Number" : "Alias",
|
||||||
|
|
@ -269,7 +268,6 @@ static bool is_object_schema_update_available(struct bbfdm_context *u)
|
||||||
.bbf_ctx.iscommand = true,
|
.bbf_ctx.iscommand = true,
|
||||||
.bbf_ctx.isevent = true,
|
.bbf_ctx.isevent = true,
|
||||||
.bbf_ctx.isinfo = true,
|
.bbf_ctx.isinfo = true,
|
||||||
.bbf_ctx.enable_plugins = input_json ? false : true,
|
|
||||||
.bbf_ctx.dm_type = BBFDM_USP
|
.bbf_ctx.dm_type = BBFDM_USP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -969,8 +967,8 @@ static int bbfdm_service_handler(struct ubus_context *ctx, struct ubus_object *o
|
||||||
|
|
||||||
INFO("ubus method|%s|, name|%s|", method, obj->name);
|
INFO("ubus method|%s|, name|%s|", method, obj->name);
|
||||||
|
|
||||||
if (input_json) { // It's a micro-service instance
|
if (is_micro_service) { // It's a micro-service instance
|
||||||
blobmsg_add_string(&bb, "error", "you are not allowed to register a micro-service for another micro-service!!");
|
blobmsg_add_string(&bb, "error", "Its not allowed to register a micro-service for another micro-service!!");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1078,7 +1076,7 @@ static void run_schema_updater(struct bbfdm_context *u)
|
||||||
char method_name[45] = {0};
|
char method_name[45] = {0};
|
||||||
|
|
||||||
ret = is_object_schema_update_available(u);
|
ret = is_object_schema_update_available(u);
|
||||||
if (ret) {
|
if (ret && (is_micro_service == false)) {
|
||||||
struct blob_buf bb;
|
struct blob_buf bb;
|
||||||
|
|
||||||
memset(&bb, 0, sizeof(struct blob_buf));
|
memset(&bb, 0, sizeof(struct blob_buf));
|
||||||
|
|
@ -1135,7 +1133,6 @@ static void update_instances_list(struct list_head *inst)
|
||||||
struct dmctx bbf_ctx = {
|
struct dmctx bbf_ctx = {
|
||||||
.in_param = ROOT_NODE,
|
.in_param = ROOT_NODE,
|
||||||
.nextlevel = false,
|
.nextlevel = false,
|
||||||
.enable_plugins = input_json ? false : true,
|
|
||||||
.disable_mservice_browse = true,
|
.disable_mservice_browse = true,
|
||||||
.instance_mode = INSTANCE_MODE_NUMBER,
|
.instance_mode = INSTANCE_MODE_NUMBER,
|
||||||
.dm_type = BBFDM_USP
|
.dm_type = BBFDM_USP
|
||||||
|
|
@ -1311,9 +1308,9 @@ static bool register_service(struct ubus_context *ctx)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bbfdm_load_deamon_config(void)
|
static int bbfdm_load_deamon_config(const char *input)
|
||||||
{
|
{
|
||||||
const char *json_path = input_json ? input_json : BBF_JSON_INPUT;
|
const char *json_path = input ? input : BBF_JSON_INPUT;
|
||||||
char *opt_val = NULL;
|
char *opt_val = NULL;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
|
@ -1361,7 +1358,7 @@ static int bbfdm_load_deamon_config(void)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_json) {
|
if (input) {
|
||||||
opt_val = dmjson_get_value(deamon_obj, 2, "output", "parent_dm");
|
opt_val = dmjson_get_value(deamon_obj, 2, "output", "parent_dm");
|
||||||
if (opt_val && strlen(opt_val)) {
|
if (opt_val && strlen(opt_val)) {
|
||||||
strncpyt(PARENT_DM, opt_val, sizeof(PARENT_DM));
|
strncpyt(PARENT_DM, opt_val, sizeof(PARENT_DM));
|
||||||
|
|
@ -1384,6 +1381,11 @@ static int bbfdm_load_deamon_config(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opt_val = dmjson_get_value(deamon_obj, 2, "input", "plugin_dir");
|
||||||
|
if (opt_val && strlen(opt_val)) {
|
||||||
|
strncpyt(CONFIG_PLUGIN_PATH, opt_val, sizeof(CONFIG_PLUGIN_PATH));
|
||||||
|
}
|
||||||
|
|
||||||
opt_val = dmjson_get_value(deamon_obj, 2, "input", "type");
|
opt_val = dmjson_get_value(deamon_obj, 2, "input", "type");
|
||||||
if (opt_val && strlen(opt_val)) {
|
if (opt_val && strlen(opt_val)) {
|
||||||
char *file_path = dmjson_get_value(deamon_obj, 2, "input", "name");
|
char *file_path = dmjson_get_value(deamon_obj, 2, "input", "name");
|
||||||
|
|
@ -1408,7 +1410,7 @@ exit:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bbfdm_init(struct ubus_context *ctx)
|
static int bbfdm_regiter_ubus(struct ubus_context *ctx)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
@ -1480,10 +1482,19 @@ static void register_periodic_timers(struct ubus_context *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx)
|
||||||
|
{
|
||||||
|
memset(bbfdm_ctx, 0, sizeof(struct bbfdm_context));
|
||||||
|
blob_buf_init(&bbfdm_ctx->dm_schema, 0);
|
||||||
|
INIT_LIST_HEAD(&bbfdm_ctx->instances);
|
||||||
|
INIT_LIST_HEAD(&bbfdm_ctx->old_instances);
|
||||||
|
INIT_LIST_HEAD(&bbfdm_ctx->event_handlers);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct bbfdm_context bbfdm_ctx;
|
struct bbfdm_context bbfdm_ctx;
|
||||||
const char *ubus_socket = NULL;
|
const char *ubus_socket = NULL, *input_file = NULL;
|
||||||
int err = 0, ch;
|
int err = 0, ch;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "hs:m:c:")) != -1) {
|
while ((ch = getopt(argc, argv, "hs:m:c:")) != -1) {
|
||||||
|
|
@ -1492,10 +1503,11 @@ int main(int argc, char **argv)
|
||||||
ubus_socket = optarg;
|
ubus_socket = optarg;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
input_json = optarg;
|
input_file = optarg;
|
||||||
|
is_micro_service = input_file ? true : false;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
err = bbfdm_cli_exec_command(argc-optind+1, &argv[optind-1]);
|
err = bbfdm_cli_exec_command(input_file, argc-optind+1, &argv[optind-1]);
|
||||||
exit(err);
|
exit(err);
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
|
@ -1505,21 +1517,18 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is_micro_service = input_json ? true : false;
|
|
||||||
|
|
||||||
if (!input_json) // It's not a micro-service instance
|
if (is_micro_service == false) // It's not a micro-service instance
|
||||||
signal_init();
|
signal_init();
|
||||||
|
|
||||||
err = bbfdm_load_deamon_config();
|
err = bbfdm_load_deamon_config(input_file);
|
||||||
if (err != UBUS_STATUS_OK) {
|
if (err != UBUS_STATUS_OK) {
|
||||||
fprintf(stderr, "Failed to load %s config from json file (%s)\n", UBUS_METHOD_NAME, input_json ? input_json : BBF_JSON_INPUT);
|
fprintf(stderr, "Failed to load %s config from json file (%s)\n", UBUS_METHOD_NAME, input_file ? input_file : BBF_JSON_INPUT);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
openlog(UBUS_METHOD_NAME, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
openlog(UBUS_METHOD_NAME, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||||
|
bbfdm_ctx_init(&bbfdm_ctx);
|
||||||
memset(&bbfdm_ctx, 0, sizeof(struct bbfdm_context));
|
|
||||||
blob_buf_init(&bbfdm_ctx.dm_schema, 0);
|
|
||||||
|
|
||||||
err = ubus_connect_ctx(&bbfdm_ctx.ubus_ctx, ubus_socket);
|
err = ubus_connect_ctx(&bbfdm_ctx.ubus_ctx, ubus_socket);
|
||||||
if (err != UBUS_STATUS_OK) {
|
if (err != UBUS_STATUS_OK) {
|
||||||
|
|
@ -1527,22 +1536,17 @@ int main(int argc, char **argv)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_LIST_HEAD(&bbfdm_ctx.instances);
|
|
||||||
INIT_LIST_HEAD(&bbfdm_ctx.old_instances);
|
|
||||||
INIT_LIST_HEAD(&bbfdm_ctx.event_handlers);
|
|
||||||
|
|
||||||
uloop_init();
|
uloop_init();
|
||||||
ubus_add_uloop(&bbfdm_ctx.ubus_ctx);
|
ubus_add_uloop(&bbfdm_ctx.ubus_ctx);
|
||||||
run_schema_updater(&bbfdm_ctx);
|
|
||||||
periodic_instance_updater(&bbfdm_ctx.instance_timer);
|
periodic_instance_updater(&bbfdm_ctx.instance_timer);
|
||||||
|
|
||||||
err = bbfdm_init(&bbfdm_ctx.ubus_ctx);
|
err = bbfdm_regiter_ubus(&bbfdm_ctx.ubus_ctx);
|
||||||
if (err != UBUS_STATUS_OK)
|
if (err != UBUS_STATUS_OK)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
bbf_global_init(DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, DEAMON_DM_VENDOR_EXTENSION_EXCLUDE, CONFIG_PLUGIN_PATH);
|
||||||
|
run_schema_updater(&bbfdm_ctx);
|
||||||
if (is_micro_service == false) { // It's not a micro-service instance
|
if (is_micro_service == false) { // It's not a micro-service instance
|
||||||
|
|
||||||
bbf_global_init(DEAMON_DM_ROOT_OBJ, DEAMON_DM_VENDOR_EXTENSION, DEAMON_DM_VENDOR_EXTENSION_EXCLUDE, true);
|
|
||||||
err = register_events_to_ubus(&bbfdm_ctx.ubus_ctx, &bbfdm_ctx.event_handlers);
|
err = register_events_to_ubus(&bbfdm_ctx.ubus_ctx, &bbfdm_ctx.event_handlers);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,7 @@
|
||||||
extern struct list_head loaded_json_files;
|
extern struct list_head loaded_json_files;
|
||||||
extern struct list_head json_list;
|
extern struct list_head json_list;
|
||||||
extern struct list_head json_memhead;
|
extern struct list_head json_memhead;
|
||||||
|
extern const char *CONFIG_PLUGIN_PATH;
|
||||||
extern char *input_json;
|
|
||||||
|
|
||||||
#define UNUSED __attribute__((unused))
|
#define UNUSED __attribute__((unused))
|
||||||
|
|
||||||
|
|
@ -258,9 +257,8 @@ static int in_ubus_out_cli_exec_cmd(cli_data_t *cli_data, const char *path, cons
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bbfdm_load_cli_config(cli_data_t *cli_data)
|
static int bbfdm_load_cli_config(const char *json_path, cli_data_t *cli_data)
|
||||||
{
|
{
|
||||||
const char *json_path = input_json ? input_json : BBF_JSON_INPUT;
|
|
||||||
char *opt_val = NULL;
|
char *opt_val = NULL;
|
||||||
|
|
||||||
if (!json_path || !strlen(json_path)) {
|
if (!json_path || !strlen(json_path)) {
|
||||||
|
|
@ -642,13 +640,12 @@ static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
bbf_global_init(CLI_DM_ROOT_OBJ, CLI_DM_VENDOR_EXTENSION, CLI_DM_VENDOR_EXTENSION_EXCLUDE, input_json ? false : true);
|
bbf_global_init(CLI_DM_ROOT_OBJ, CLI_DM_VENDOR_EXTENSION, CLI_DM_VENDOR_EXTENSION_EXCLUDE, CONFIG_PLUGIN_PATH);
|
||||||
|
|
||||||
bbf_ctx_init(&cli_data->bbf_ctx, CLI_DM_ROOT_OBJ, CLI_DM_VENDOR_EXTENSION, CLI_DM_VENDOR_EXTENSION_EXCLUDE);
|
bbf_ctx_init(&cli_data->bbf_ctx, CLI_DM_ROOT_OBJ, CLI_DM_VENDOR_EXTENSION, CLI_DM_VENDOR_EXTENSION_EXCLUDE);
|
||||||
|
|
||||||
cli_data->bbf_ctx.dm_type = cli_data->proto;
|
cli_data->bbf_ctx.dm_type = cli_data->proto;
|
||||||
cli_data->bbf_ctx.instance_mode = cli_data->instance_mode;
|
cli_data->bbf_ctx.instance_mode = cli_data->instance_mode;
|
||||||
cli_data->bbf_ctx.enable_plugins = input_json ? false : true;
|
|
||||||
} else if (strcasecmp(cli_data->in_type, "UBUS") != 0) {
|
} else if (strcasecmp(cli_data->in_type, "UBUS") != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -681,13 +678,13 @@ end:
|
||||||
if (strcasecmp(cli_data->in_type, "DotSO") == 0) {
|
if (strcasecmp(cli_data->in_type, "DotSO") == 0) {
|
||||||
if (CLI_DM_ROOT_OBJ) {
|
if (CLI_DM_ROOT_OBJ) {
|
||||||
bbf_ctx_clean(&cli_data->bbf_ctx);
|
bbf_ctx_clean(&cli_data->bbf_ctx);
|
||||||
bbf_global_clean(CLI_DM_ROOT_OBJ, CLI_DM_VENDOR_EXTENSION, CLI_DM_VENDOR_EXTENSION_EXCLUDE, input_json ? false : true);
|
bbf_global_clean(CLI_DM_ROOT_OBJ);
|
||||||
}
|
}
|
||||||
free_dotso_plugin(cli_lib_handle);
|
free_dotso_plugin(cli_lib_handle);
|
||||||
} else if (strcasecmp(cli_data->in_type, "JSON") == 0) {
|
} else if (strcasecmp(cli_data->in_type, "JSON") == 0) {
|
||||||
if (CLI_DM_ROOT_OBJ) {
|
if (CLI_DM_ROOT_OBJ) {
|
||||||
bbf_ctx_clean(&cli_data->bbf_ctx);
|
bbf_ctx_clean(&cli_data->bbf_ctx);
|
||||||
bbf_global_clean(CLI_DM_ROOT_OBJ, CLI_DM_VENDOR_EXTENSION, CLI_DM_VENDOR_EXTENSION_EXCLUDE, input_json ? false : true);
|
bbf_global_clean(CLI_DM_ROOT_OBJ);
|
||||||
}
|
}
|
||||||
free_json_plugin();
|
free_json_plugin();
|
||||||
}
|
}
|
||||||
|
|
@ -695,14 +692,15 @@ end:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bbfdm_cli_exec_command(int argc, char *argv[])
|
int bbfdm_cli_exec_command(const char *input, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
cli_data_t cli_data = {0};
|
cli_data_t cli_data = {0};
|
||||||
int err = EXIT_SUCCESS;
|
int err = EXIT_SUCCESS;
|
||||||
|
const char *json_input = (input) ? input : BBF_JSON_INPUT;
|
||||||
|
|
||||||
memset(&cli_data, 0, sizeof(cli_data_t));
|
memset(&cli_data, 0, sizeof(cli_data_t));
|
||||||
|
|
||||||
err = bbfdm_load_cli_config(&cli_data);
|
err = bbfdm_load_cli_config(json_input, &cli_data);
|
||||||
if (err)
|
if (err)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,4 @@
|
||||||
* See LICENSE file for license related information.
|
* See LICENSE file for license related information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int bbfdm_cli_exec_command(int argc, char *argv[]);
|
int bbfdm_cli_exec_command(const char *input, int argc, char *argv[]);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
#include <libubus.h>
|
#include <libubus.h>
|
||||||
|
|
||||||
extern char UBUS_METHOD_NAME[32];
|
extern char UBUS_METHOD_NAME[32];
|
||||||
extern char *input_json;
|
|
||||||
|
|
||||||
static struct event_map_list ev_map_list[] = {
|
static struct event_map_list ev_map_list[] = {
|
||||||
/* { event name, DM Path, .arguments[] = { event_args, dm_args } } */
|
/* { event name, DM Path, .arguments[] = { event_args, dm_args } } */
|
||||||
|
|
@ -264,7 +263,6 @@ bool is_registered_event(char *name)
|
||||||
.iscommand = false,
|
.iscommand = false,
|
||||||
.isevent = true,
|
.isevent = true,
|
||||||
.isinfo = false,
|
.isinfo = false,
|
||||||
.enable_plugins = input_json ? false : true,
|
|
||||||
.instance_mode = INSTANCE_MODE_NUMBER,
|
.instance_mode = INSTANCE_MODE_NUMBER,
|
||||||
.dm_type = BBFDM_USP
|
.dm_type = BBFDM_USP
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@
|
||||||
|
|
||||||
#include <libubus.h>
|
#include <libubus.h>
|
||||||
|
|
||||||
extern char *input_json;
|
|
||||||
|
|
||||||
enum operation {
|
enum operation {
|
||||||
OPER_EQUAL_EQUAL,
|
OPER_EQUAL_EQUAL,
|
||||||
OPER_NOT_EQUAL,
|
OPER_NOT_EQUAL,
|
||||||
|
|
@ -724,7 +722,6 @@ static int append_all_instances(unsigned int dm_type, char *bPath, struct list_h
|
||||||
struct dmctx bbf_ctx = {
|
struct dmctx bbf_ctx = {
|
||||||
.in_param = bPath,
|
.in_param = bPath,
|
||||||
.nextlevel = true,
|
.nextlevel = true,
|
||||||
.enable_plugins = input_json ? false : true,
|
|
||||||
.instance_mode = INSTANCE_MODE_NUMBER,
|
.instance_mode = INSTANCE_MODE_NUMBER,
|
||||||
.dm_type = dm_type
|
.dm_type = dm_type
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
#include <libubus.h>
|
#include <libubus.h>
|
||||||
|
|
||||||
extern char *input_json;
|
|
||||||
|
|
||||||
int bbfdm_set_value(bbfdm_data_t *data)
|
int bbfdm_set_value(bbfdm_data_t *data)
|
||||||
{
|
{
|
||||||
struct pvNode *pv = NULL;
|
struct pvNode *pv = NULL;
|
||||||
|
|
@ -48,7 +46,6 @@ static int set_resolved_paths(unsigned int dm_type, char *path, char *value, str
|
||||||
{
|
{
|
||||||
int fault = 0;
|
int fault = 0;
|
||||||
struct dmctx bbf_ctx = {
|
struct dmctx bbf_ctx = {
|
||||||
.enable_plugins = input_json ? false : true,
|
|
||||||
.instance_mode = INSTANCE_MODE_NUMBER,
|
.instance_mode = INSTANCE_MODE_NUMBER,
|
||||||
.dm_type = dm_type
|
.dm_type = dm_type
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ exec_cmd pip3 install pexpect ubus
|
||||||
|
|
||||||
# compile and install libbbf
|
# compile and install libbbf
|
||||||
install_libbbf ${1}
|
install_libbbf ${1}
|
||||||
|
mkdir -p /etc/bbfdm/plugins
|
||||||
|
|
||||||
#compile and install libbbf_test dynamic extension library
|
#compile and install libbbf_test dynamic extension library
|
||||||
install_libbbf_test ${1}
|
install_libbbf_test ${1}
|
||||||
|
|
@ -23,10 +24,10 @@ if [ -z "${1}" ]; then
|
||||||
git clone --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@dev.iopsys.eu/feed/iopsys.git /opt/dev/iopsys
|
git clone --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@dev.iopsys.eu/feed/iopsys.git /opt/dev/iopsys
|
||||||
git clone --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@dev.iopsys.eu/bbf/bulkdata.git /opt/dev/bulkdata
|
git clone --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@dev.iopsys.eu/bbf/bulkdata.git /opt/dev/bulkdata
|
||||||
|
|
||||||
cp -f /opt/dev/iopsys/urlfilter/files/etc/bbfdm/json/urlfilter.json /etc/bbfdm/json
|
install_plugin /opt/dev/iopsys/urlfilter/files/etc/bbfdm/json/urlfilter.json
|
||||||
cp -f /opt/dev/iopsys/obuspa/files/etc/bbfdm/json/USPAgent.json /etc/bbfdm/json
|
install_plugin /opt/dev/iopsys/obuspa/files/etc/bbfdm/json/USPAgent.json
|
||||||
cp -f /opt/dev/iopsys/icwmp/files/etc/bbfdm/json/CWMPManagementServer.json /etc/bbfdm/json
|
install_plugin /opt/dev/iopsys/icwmp/files/etc/bbfdm/json/CWMPManagementServer.json
|
||||||
cp -f /opt/dev/iopsys/ponmngr/files/etc/bbfdm/json/xpon.json /etc/bbfdm/json
|
install_plugin /opt/dev/iopsys/ponmngr/files/etc/bbfdm/json/xpon.json
|
||||||
|
|
||||||
# install bulkdata micro-service
|
# install bulkdata micro-service
|
||||||
mkdir -p /etc/bulkdata
|
mkdir -p /etc/bulkdata
|
||||||
|
|
@ -47,4 +48,6 @@ if [ -z "${1}" ]; then
|
||||||
|
|
||||||
# install time micro-service
|
# install time micro-service
|
||||||
install_time_micro_service
|
install_time_micro_service
|
||||||
|
|
||||||
|
ls -l /etc/bbfdm/plugins/
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ cp ./gitlab-ci/bbfdm_services.conf /etc/supervisor/conf.d/
|
||||||
|
|
||||||
supervisorctl reread
|
supervisorctl reread
|
||||||
supervisorctl update
|
supervisorctl update
|
||||||
sleep 10
|
exec_cmd ubus wait_for bbfdm
|
||||||
|
sleep 20
|
||||||
|
|
||||||
supervisorctl status all
|
supervisorctl status all
|
||||||
exec_cmd ubus wait_for bbfdm
|
|
||||||
|
|
||||||
function run_valgrind()
|
function run_valgrind()
|
||||||
{
|
{
|
||||||
|
|
@ -34,16 +34,18 @@ function run_valgrind_redirect()
|
||||||
|
|
||||||
echo "Running memory check on datamodel"
|
echo "Running memory check on datamodel"
|
||||||
|
|
||||||
|
run_valgrind_redirect -c get Device.
|
||||||
|
|
||||||
|
run_valgrind_redirect -c schema Device.
|
||||||
|
|
||||||
|
run_valgrind_redirect -c instances Device.
|
||||||
|
|
||||||
run_valgrind -c get Device.
|
run_valgrind -c get Device.
|
||||||
|
|
||||||
run_valgrind -c instances Device.
|
run_valgrind -c instances Device.
|
||||||
|
|
||||||
run_valgrind -c schema Device.
|
run_valgrind -c schema Device.
|
||||||
|
|
||||||
run_valgrind_redirect -c get Device.
|
|
||||||
|
|
||||||
run_valgrind_redirect -c schema Device.
|
|
||||||
|
|
||||||
run_valgrind_verbose -c get Device.BulkData.
|
run_valgrind_verbose -c get Device.BulkData.
|
||||||
|
|
||||||
run_valgrind_verbose -c get Device.RootDataModelVersion
|
run_valgrind_verbose -c get Device.RootDataModelVersion
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ function check_ret()
|
||||||
ret=$1
|
ret=$1
|
||||||
if [ "$ret" -ne 0 ]; then
|
if [ "$ret" -ne 0 ]; then
|
||||||
echo "Validation of last command failed, ret(${ret})"
|
echo "Validation of last command failed, ret(${ret})"
|
||||||
|
cp /tmp/memory-*.xml .
|
||||||
exit $ret
|
exit $ret
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -17,10 +18,11 @@ function check_ret()
|
||||||
function exec_cmd()
|
function exec_cmd()
|
||||||
{
|
{
|
||||||
echo "executing $@"
|
echo "executing $@"
|
||||||
$@ >/dev/null 2>&1
|
$@ >/dev/null
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Failed to execute $@"
|
echo "Failed to execute $@"
|
||||||
|
cp /tmp/memory-*.xml .
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
@ -32,10 +34,16 @@ function exec_cmd_verbose()
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Failed to execute $@"
|
echo "Failed to execute $@"
|
||||||
|
cp /tmp/memory-*.xml .
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function install_plugin()
|
||||||
|
{
|
||||||
|
exec_cmd cp -f "${1}" /etc/bbfdm/plugins/
|
||||||
|
}
|
||||||
|
|
||||||
function install_libusermngr()
|
function install_libusermngr()
|
||||||
{
|
{
|
||||||
# clone and compile libusermngr
|
# clone and compile libusermngr
|
||||||
|
|
@ -52,7 +60,7 @@ function install_libusermngr()
|
||||||
exec_cmd_verbose make -C /opt/dev/usermngr/src/
|
exec_cmd_verbose make -C /opt/dev/usermngr/src/
|
||||||
|
|
||||||
echo "installing libusermngr"
|
echo "installing libusermngr"
|
||||||
cp -f /opt/dev/usermngr/src/libusermngr.so /usr/lib/bbfdm
|
install_plugin /opt/dev/usermngr/src/libusermngr.so
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_libbbf()
|
function install_libbbf()
|
||||||
|
|
@ -73,7 +81,7 @@ function install_libbbf()
|
||||||
|
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS " -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS -lm" -DWITH_OPENSSL=ON -DBBF_JSON_PLUGIN=ON -DBBF_DOTSO_PLUGIN=ON -DBBF_VENDOR_EXTENSION=ON -DBBF_WIFI_DATAELEMENTS=OFF -DBBF_VENDOR_LIST="$VENDOR_LIST" -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" -DBBF_MAX_OBJECT_INSTANCES=255 -DBBFDMD_MAX_MSG_LEN=1048576 -DCMAKE_INSTALL_PREFIX=/
|
cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS " -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS -lm" -DWITH_OPENSSL=ON -DBBF_VENDOR_EXTENSION=ON -DBBF_WIFI_DATAELEMENTS=OFF -DBBF_VENDOR_LIST="$VENDOR_LIST" -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" -DBBF_MAX_OBJECT_INSTANCES=255 -DBBFDMD_MAX_MSG_LEN=1048576 -DCMAKE_INSTALL_PREFIX=/
|
||||||
exec_cmd_verbose make
|
exec_cmd_verbose make
|
||||||
|
|
||||||
echo "installing libbbf"
|
echo "installing libbbf"
|
||||||
|
|
@ -93,7 +101,7 @@ function install_libbbf_test()
|
||||||
exec_cmd_verbose make -C test/bbf_test/
|
exec_cmd_verbose make -C test/bbf_test/
|
||||||
|
|
||||||
echo "installing libbbf_test"
|
echo "installing libbbf_test"
|
||||||
cp -f test/bbf_test/libbbf_test.so /usr/lib/bbfdm
|
install_plugin ./test/bbf_test/libbbf_test.so
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_libwifi_dataelements()
|
function install_libwifi_dataelements()
|
||||||
|
|
@ -149,7 +157,7 @@ function install_libcwmpdm()
|
||||||
exec_cmd_verbose make
|
exec_cmd_verbose make
|
||||||
|
|
||||||
echo "installing libcwmpdm"
|
echo "installing libcwmpdm"
|
||||||
cp -f /opt/dev/icwmp/libcwmpdm.so /usr/lib/bbfdm
|
install_plugin /opt/dev/icwmp/libcwmpdm.so
|
||||||
|
|
||||||
cd /builds/bbf/bbfdm
|
cd /builds/bbf/bbfdm
|
||||||
}
|
}
|
||||||
|
|
@ -202,6 +210,7 @@ function error_on_zero()
|
||||||
ret=$1
|
ret=$1
|
||||||
if [ "$ret" -eq 0 ]; then
|
if [ "$ret" -eq 0 ]; then
|
||||||
echo "Validation of last command failed, ret(${ret})"
|
echo "Validation of last command failed, ret(${ret})"
|
||||||
|
cp /tmp/memory-*.xml .
|
||||||
exit $ret
|
exit $ret
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,23 +23,23 @@ echo "Validate BBF TR-104 JSON Plugin"
|
||||||
check_ret $?
|
check_ret $?
|
||||||
|
|
||||||
echo "Validate X_IOPSYS_EU_Dropbear JSON Plugin"
|
echo "Validate X_IOPSYS_EU_Dropbear JSON Plugin"
|
||||||
./tools/validate_json_plugin.py test/files/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json
|
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/X_IOPSYS_EU_Dropbear.json
|
||||||
check_ret $?
|
check_ret $?
|
||||||
|
|
||||||
echo "Validate X_IOPSYS_EU_TEST JSON Plugin"
|
echo "Validate X_IOPSYS_EU_TEST JSON Plugin"
|
||||||
./tools/validate_json_plugin.py test/files/etc/bbfdm/json/X_IOPSYS_EU_TEST.json
|
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/X_IOPSYS_EU_TEST.json
|
||||||
check_ret $?
|
check_ret $?
|
||||||
|
|
||||||
echo "Validate X_IOPSYS_EU_WiFi JSON Plugin"
|
echo "Validate X_IOPSYS_EU_WiFi JSON Plugin"
|
||||||
./tools/validate_json_plugin.py test/files/etc/bbfdm/json/X_IOPSYS_EU_WiFi.json
|
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/X_IOPSYS_EU_WiFi.json
|
||||||
check_ret $?
|
check_ret $?
|
||||||
|
|
||||||
echo "Validate X_IOPSYS_EU_URLFilter JSON Plugin"
|
echo "Validate X_IOPSYS_EU_URLFilter JSON Plugin"
|
||||||
./tools/validate_json_plugin.py test/files/etc/bbfdm/json/urlfilter.json
|
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/urlfilter.json
|
||||||
check_ret $?
|
check_ret $?
|
||||||
|
|
||||||
echo "Validate CWMPManagementServer JSON Plugin"
|
echo "Validate CWMPManagementServer JSON Plugin"
|
||||||
./tools/validate_json_plugin.py test/files/etc/bbfdm/json/CWMPManagementServer.json
|
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/CWMPManagementServer.json
|
||||||
check_ret $?
|
check_ret $?
|
||||||
|
|
||||||
echo "Validate TR-181 JSON Plugin after generating from XML"
|
echo "Validate TR-181 JSON Plugin after generating from XML"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
},
|
},
|
||||||
"input": {
|
"input": {
|
||||||
"type": "DotSo",
|
"type": "DotSo",
|
||||||
"name": "/lib/libbbfdm.so"
|
"name": "/lib/libbbfdm.so",
|
||||||
|
"plugin_dir": "/etc/bbfdm/plugins/"
|
||||||
},
|
},
|
||||||
"output": {
|
"output": {
|
||||||
"type": "UBUS",
|
"type": "UBUS",
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,9 @@ IF(${BBF_MAX_OBJECT_INSTANCES})
|
||||||
ADD_DEFINITIONS(-DBBF_MAX_OBJECT_INSTANCES=${BBF_MAX_OBJECT_INSTANCES})
|
ADD_DEFINITIONS(-DBBF_MAX_OBJECT_INSTANCES=${BBF_MAX_OBJECT_INSTANCES})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
OPTION(BBF_DOTSO_PLUGIN "build with dotso plugin" ON)
|
|
||||||
OPTION(BBF_JSON_PLUGIN "build with json plugin" ON)
|
|
||||||
OPTION(BBF_VENDOR_EXTENSION "build with vendor extension enabled" ON)
|
OPTION(BBF_VENDOR_EXTENSION "build with vendor extension enabled" ON)
|
||||||
|
|
||||||
IF(BBF_DOTSO_PLUGIN)
|
SET(BBF_PLUGIN_SOURCES plugin/dotso_plugin.c plugin/json_plugin.c)
|
||||||
SET(BBF_DOTSO_PLUGIN_SOURCES plugin/dotso_plugin.c)
|
|
||||||
add_compile_definitions(BBFDM_ENABLE_DOTSO_PLUGIN)
|
|
||||||
ENDIF(BBF_DOTSO_PLUGIN)
|
|
||||||
|
|
||||||
IF(BBF_JSON_PLUGIN)
|
|
||||||
SET(BBF_JSON_PLUGIN_SOURCES plugin/json_plugin.c)
|
|
||||||
add_compile_definitions(BBFDM_ENABLE_JSON_PLUGIN)
|
|
||||||
endif(BBF_JSON_PLUGIN)
|
|
||||||
|
|
||||||
IF(BBF_VENDOR_EXTENSION)
|
IF(BBF_VENDOR_EXTENSION)
|
||||||
SET(BBF_VENDOR_EXTENSION_SOURCES plugin/vendor_plugin.c)
|
SET(BBF_VENDOR_EXTENSION_SOURCES plugin/vendor_plugin.c)
|
||||||
|
|
@ -34,7 +24,7 @@ ENDIF(BBF_VENDOR_EXTENSION)
|
||||||
|
|
||||||
FILE(GLOB BBF_API_SOURCES *.c)
|
FILE(GLOB BBF_API_SOURCES *.c)
|
||||||
|
|
||||||
ADD_LIBRARY(bbfdm-api SHARED ${BBF_API_SOURCES} ${BBF_DOTSO_PLUGIN_SOURCES} ${BBF_JSON_PLUGIN_SOURCES} ${BBF_VENDOR_EXTENSION_SOURCES})
|
ADD_LIBRARY(bbfdm-api SHARED ${BBF_API_SOURCES} ${BBF_PLUGIN_SOURCES} ${BBF_VENDOR_EXTENSION_SOURCES})
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(bbfdm-api uci ubus ubox json-c blobmsg_json dl)
|
TARGET_LINK_LIBRARIES(bbfdm-api uci ubus ubox json-c blobmsg_json dl)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,6 @@ struct dmctx {
|
||||||
bool iscommand;
|
bool iscommand;
|
||||||
bool isevent;
|
bool isevent;
|
||||||
bool isinfo;
|
bool isinfo;
|
||||||
bool enable_plugins;
|
|
||||||
bool disable_mservice_browse;
|
bool disable_mservice_browse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -208,10 +208,7 @@ int bbf_entry_method(struct dmctx *ctx, int cmd)
|
||||||
return bbf_fault_map(ctx, FAULT_9005);
|
return bbf_fault_map(ctx, FAULT_9005);
|
||||||
}
|
}
|
||||||
|
|
||||||
load_plugins(ctx->dm_entryobj, ctx->dm_vendor_extension, ctx->dm_vendor_extension_exclude, ctx->enable_plugins);
|
|
||||||
|
|
||||||
dmentry_instance_lookup_inparam(ctx);
|
dmentry_instance_lookup_inparam(ctx);
|
||||||
|
|
||||||
ctx->iswildcard = DM_STRCHR(ctx->in_param, '*') ? 1 : 0;
|
ctx->iswildcard = DM_STRCHR(ctx->in_param, '*') ? 1 : 0;
|
||||||
ctx->stop = false;
|
ctx->stop = false;
|
||||||
|
|
||||||
|
|
@ -252,14 +249,14 @@ int bbf_entry_method(struct dmctx *ctx, int cmd)
|
||||||
return bbf_fault_map(ctx, fault);
|
return bbf_fault_map(ctx, fault);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bbf_global_init(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, bool enable_plugins)
|
void bbf_global_init(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path)
|
||||||
{
|
{
|
||||||
load_plugins(dm_entryobj, dm_VendorExtension, dm_VendorExtensionExclude, enable_plugins);
|
load_plugins(dm_entryobj, dm_VendorExtension,dm_VendorExtensionExclude, plugin_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bbf_global_clean(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, bool enable_plugins)
|
void bbf_global_clean(DMOBJ *dm_entryobj)
|
||||||
{
|
{
|
||||||
free_plugins(dm_entryobj, dm_VendorExtension, dm_VendorExtensionExclude, enable_plugins);
|
free_plugins(dm_entryobj);
|
||||||
dm_dynamic_cleanmem(&global_memhead);
|
dm_dynamic_cleanmem(&global_memhead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ int bbf_fault_map(struct dmctx *ctx, int fault);
|
||||||
|
|
||||||
int bbf_entry_method(struct dmctx *ctx, int cmd);
|
int bbf_entry_method(struct dmctx *ctx, int cmd);
|
||||||
|
|
||||||
void bbf_global_init(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, bool enable_plugins);
|
void bbf_global_init(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path);
|
||||||
void bbf_global_clean(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, bool enable_plugins);
|
void bbf_global_clean(DMOBJ *dm_entryobj);
|
||||||
|
|
||||||
int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *objects[]);
|
int dm_entry_validate_allowed_objects(struct dmctx *ctx, char *value, char *objects[]);
|
||||||
int dm_entry_validate_external_linker_allowed_objects(struct dmctx *ctx, char *value, char *objects[]);
|
int dm_entry_validate_external_linker_allowed_objects(struct dmctx *ctx, char *value, char *objects[]);
|
||||||
|
|
|
||||||
|
|
@ -11,22 +11,13 @@
|
||||||
#include "dmapi.h"
|
#include "dmapi.h"
|
||||||
#include "dmplugin.h"
|
#include "dmplugin.h"
|
||||||
|
|
||||||
#ifdef BBFDM_ENABLE_JSON_PLUGIN
|
|
||||||
#include "plugin/json_plugin.h"
|
#include "plugin/json_plugin.h"
|
||||||
static char json_hash[64] = {0};
|
|
||||||
#endif /* BBFDM_ENABLE_JSON_PLUGIN */
|
|
||||||
|
|
||||||
#ifdef BBFDM_ENABLE_DOTSO_PLUGIN
|
|
||||||
#include "plugin/dotso_plugin.h"
|
#include "plugin/dotso_plugin.h"
|
||||||
static char library_hash[64] = {0};
|
|
||||||
#endif /* BBFDM_ENABLE_DOTSO_PLUGIN */
|
|
||||||
|
|
||||||
#ifdef BBF_VENDOR_EXTENSION
|
#ifdef BBF_VENDOR_EXTENSION
|
||||||
#include "plugin/vendor_plugin.h"
|
#include "plugin/vendor_plugin.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool first_boot = false;
|
|
||||||
|
|
||||||
extern struct list_head global_memhead;
|
extern struct list_head global_memhead;
|
||||||
|
|
||||||
struct service
|
struct service
|
||||||
|
|
@ -37,87 +28,6 @@ struct service
|
||||||
char *object;
|
char *object;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(BBFDM_ENABLE_JSON_PLUGIN) || defined(BBFDM_ENABLE_DOTSO_PLUGIN)
|
|
||||||
static char *get_folder_path(bool json_path)
|
|
||||||
{
|
|
||||||
if (json_path) {
|
|
||||||
#ifdef BBFDM_ENABLE_JSON_PLUGIN
|
|
||||||
return JSON_FOLDER_PATH;
|
|
||||||
#endif /* BBFDM_ENABLE_JSON_PLUGIN */
|
|
||||||
} else {
|
|
||||||
#ifdef BBFDM_ENABLE_DOTSO_PLUGIN
|
|
||||||
return LIBRARY_FOLDER_PATH;
|
|
||||||
#endif /* BBFDM_ENABLE_DOTSO_PLUGIN */
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_stats_folder(bool json_path, int *count, unsigned long *size)
|
|
||||||
{
|
|
||||||
const char *path = get_folder_path(json_path);
|
|
||||||
if (path == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (folder_exists(path)) {
|
|
||||||
struct dirent *entry = NULL;
|
|
||||||
struct stat stats;
|
|
||||||
int file_count = 0;
|
|
||||||
unsigned long file_size = 0;
|
|
||||||
char buf[512] = {0};
|
|
||||||
|
|
||||||
DIR *dirp = opendir(path);
|
|
||||||
while ((entry = readdir(dirp)) != NULL) {
|
|
||||||
if ((entry->d_type == DT_REG) && (strstr(entry->d_name, json_path ? ".json" : ".so"))) {
|
|
||||||
file_count++;
|
|
||||||
snprintf(buf, sizeof(buf), "%s/%s", path, entry->d_name);
|
|
||||||
if (!stat(buf, &stats))
|
|
||||||
file_size += stats.st_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dirp)
|
|
||||||
closedir(dirp);
|
|
||||||
|
|
||||||
*count = file_count;
|
|
||||||
*size = file_size;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool check_stats_folder(bool json_path)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
unsigned long size = 0;
|
|
||||||
char buf[64] = {0};
|
|
||||||
|
|
||||||
if (!get_stats_folder(json_path, &count, &size))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "count:%d,size:%lu", count, size);
|
|
||||||
|
|
||||||
if (json_path) {
|
|
||||||
#ifdef BBFDM_ENABLE_JSON_PLUGIN
|
|
||||||
if (DM_STRCMP(buf, json_hash) != 0) {
|
|
||||||
DM_STRNCPY(json_hash, buf, sizeof(json_hash));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif /* BBFDM_ENABLE_JSON_PLUGIN */
|
|
||||||
} else {
|
|
||||||
#ifdef BBFDM_ENABLE_DOTSO_PLUGIN
|
|
||||||
if (DM_STRCMP(buf, library_hash) != 0) {
|
|
||||||
DM_STRNCPY(library_hash, buf, sizeof(library_hash));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif /* BBFDM_ENABLE_DOTSO_PLUGIN */
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif /* (BBFDM_ENABLE_JSON_PLUGIN || BBFDM_ENABLE_DOTSO_PLUGIN) */
|
|
||||||
|
|
||||||
|
|
||||||
static void disable_srv_obj(DMOBJ *entryobj, char *srv_parent_dm, char *srv_obj)
|
static void disable_srv_obj(DMOBJ *entryobj, char *srv_parent_dm, char *srv_obj)
|
||||||
{
|
{
|
||||||
DMOBJ *dm_entryobj = NULL;
|
DMOBJ *dm_entryobj = NULL;
|
||||||
|
|
@ -422,50 +332,51 @@ int get_leaf_idx(DMLEAF **entryleaf)
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, bool enable_plugins)
|
int load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path)
|
||||||
{
|
{
|
||||||
if (enable_plugins) {
|
struct dirent *ent = NULL;
|
||||||
#ifdef BBFDM_ENABLE_JSON_PLUGIN
|
DIR *dir = NULL;
|
||||||
// Load dynamic objects and parameters exposed via JSON file plugin
|
|
||||||
if (check_stats_folder(true)) {
|
|
||||||
free_json_plugins();
|
|
||||||
free_specific_dynamic_node(dm_entryobj, INDX_JSON_MOUNT);
|
|
||||||
load_json_plugins(dm_entryobj);
|
|
||||||
}
|
|
||||||
#endif /* BBFDM_ENABLE_JSON_PLUGIN */
|
|
||||||
|
|
||||||
#ifdef BBFDM_ENABLE_DOTSO_PLUGIN
|
|
||||||
// Load dynamic objects and parameters exposed via a dotso plugin
|
|
||||||
if (check_stats_folder(false)) {
|
|
||||||
free_dotso_plugins();
|
|
||||||
free_specific_dynamic_node(dm_entryobj, INDX_LIBRARY_MOUNT);
|
|
||||||
load_dotso_plugins(dm_entryobj);
|
|
||||||
}
|
|
||||||
#endif /* BBFDM_ENABLE_DOTSO_PLUGIN */
|
|
||||||
|
|
||||||
#ifdef BBF_VENDOR_EXTENSION
|
#ifdef BBF_VENDOR_EXTENSION
|
||||||
// Load objects and parameters exposed via vendor extension plugin
|
// Load objects and parameters exposed via vendor extension plugin
|
||||||
if (first_boot == false) {
|
free_specific_dynamic_node(dm_entryobj, INDX_VENDOR_MOUNT);
|
||||||
free_specific_dynamic_node(dm_entryobj, INDX_VENDOR_MOUNT);
|
load_vendor_dynamic_arrays(dm_entryobj, dm_VendorExtension, dm_VendorExtensionExclude);
|
||||||
load_vendor_dynamic_arrays(dm_entryobj, dm_VendorExtension, dm_VendorExtensionExclude);
|
|
||||||
}
|
|
||||||
#endif /* BBF_VENDOR_EXTENSION */
|
#endif /* BBF_VENDOR_EXTENSION */
|
||||||
|
|
||||||
|
if (DM_STRLEN(plugin_path) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!folder_exists(plugin_path)) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
first_boot = true;
|
free_json_plugins();
|
||||||
|
free_specific_dynamic_node(dm_entryobj, INDX_JSON_MOUNT);
|
||||||
|
free_dotso_plugins();
|
||||||
|
free_specific_dynamic_node(dm_entryobj, INDX_LIBRARY_MOUNT);
|
||||||
|
|
||||||
|
sysfs_foreach_file(plugin_path, dir, ent) {
|
||||||
|
char buf[512] = {0};
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s/%s", plugin_path, ent->d_name);
|
||||||
|
|
||||||
|
if (strstr(ent->d_name, ".json")) {
|
||||||
|
load_json_plugins(dm_entryobj, buf);
|
||||||
|
} else if (strstr(ent->d_name, ".so")) {
|
||||||
|
load_dotso_plugins(dm_entryobj, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir) {
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, bool enable_plugins)
|
void free_plugins(DMOBJ *dm_entryobj)
|
||||||
{
|
{
|
||||||
free_all_dynamic_nodes(dm_entryobj);
|
free_all_dynamic_nodes(dm_entryobj);
|
||||||
|
|
||||||
if (enable_plugins) {
|
free_json_plugins();
|
||||||
#ifdef BBFDM_ENABLE_JSON_PLUGIN
|
free_dotso_plugins();
|
||||||
free_json_plugins();
|
|
||||||
#endif /* BBFDM_ENABLE_JSON_PLUGIN */
|
|
||||||
|
|
||||||
#ifdef BBFDM_ENABLE_DOTSO_PLUGIN
|
|
||||||
free_dotso_plugins();
|
|
||||||
#endif /* BBFDM_ENABLE_DOTSO_PLUGIN */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ int get_entry_idx(DMOBJ *entryobj);
|
||||||
int get_obj_idx(DMOBJ **entryobj);
|
int get_obj_idx(DMOBJ **entryobj);
|
||||||
int get_leaf_idx(DMLEAF **entryleaf);
|
int get_leaf_idx(DMLEAF **entryleaf);
|
||||||
|
|
||||||
void load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, bool enable_plugins);
|
int load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path);
|
||||||
void free_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, bool enable_plugins);
|
void free_plugins(DMOBJ *dm_entryobj);
|
||||||
|
|
||||||
#endif //__DMPLUGIN_H__
|
#endif //__DMPLUGIN_H__
|
||||||
|
|
|
||||||
|
|
@ -42,87 +42,75 @@ static void free_all_list_open_library(struct list_head *library_list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_dotso_plugins(DMOBJ *entryobj)
|
int load_dotso_plugins(DMOBJ *entryobj, const char *plugin_path)
|
||||||
{
|
{
|
||||||
struct dirent *ent = NULL;
|
void *handle = dlopen(plugin_path, RTLD_NOW|RTLD_LOCAL);
|
||||||
DIR *dir = NULL;
|
if (!handle) {
|
||||||
|
fprintf(stderr, "Plugin failed [%s]\n", dlerror());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (folder_exists(LIBRARY_FOLDER_PATH)) {
|
//Load Dynamic Object handler
|
||||||
sysfs_foreach_file(LIBRARY_FOLDER_PATH, dir, ent) {
|
DM_MAP_OBJ *dynamic_obj = NULL;
|
||||||
|
*(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj");
|
||||||
|
|
||||||
if (!strstr(ent->d_name, ".so"))
|
if (dynamic_obj == NULL) {
|
||||||
continue;
|
dlclose(handle);
|
||||||
|
TRACE("Plugin %s missing init symbol ...", plugin_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char buf[512] = {0};
|
for (int i = 0; dynamic_obj[i].path; i++) {
|
||||||
snprintf(buf, sizeof(buf), "%s/%s", LIBRARY_FOLDER_PATH, ent->d_name);
|
|
||||||
|
|
||||||
void *handle = dlopen(buf, RTLD_NOW|RTLD_LOCAL);
|
DMOBJ *dm_entryobj = NULL;
|
||||||
if (!handle) {
|
bool obj_exists = find_entry_obj(entryobj, dynamic_obj[i].path, &dm_entryobj);
|
||||||
fprintf(stderr, "Plugin failed [%s]\n", dlerror());
|
if (obj_exists == false || !dm_entryobj)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (dynamic_obj[i].root_obj) {
|
||||||
|
|
||||||
|
if (dm_entryobj->nextdynamicobj == NULL) {
|
||||||
|
dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj));
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Dynamic Object
|
if (dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj == NULL) {
|
||||||
DM_MAP_OBJ *dynamic_obj = NULL;
|
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj = calloc(2, sizeof(DMOBJ *));
|
||||||
*(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj");
|
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj[0] = dynamic_obj[i].root_obj;
|
||||||
if (dynamic_obj) {
|
} else {
|
||||||
|
int idx = get_obj_idx(dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj);
|
||||||
for (int i = 0; dynamic_obj[i].path; i++) {
|
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj = realloc(dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj, (idx + 2) * sizeof(DMOBJ *));
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj[idx] = dynamic_obj[i].root_obj;
|
||||||
DMOBJ *dm_entryobj = NULL;
|
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj[idx+1] = NULL;
|
||||||
bool obj_exists = find_entry_obj(entryobj, dynamic_obj[i].path, &dm_entryobj);
|
}
|
||||||
if (obj_exists == false || !dm_entryobj)
|
|
||||||
continue;
|
}
|
||||||
|
|
||||||
if (dynamic_obj[i].root_obj) {
|
if (dynamic_obj[i].root_leaf) {
|
||||||
|
|
||||||
if (dm_entryobj->nextdynamicobj == NULL) {
|
if (dm_entryobj->dynamicleaf == NULL) {
|
||||||
dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj));
|
dm_entryobj->dynamicleaf = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_leaf));
|
||||||
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
|
dm_entryobj->dynamicleaf[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
|
||||||
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
|
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
|
||||||
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
|
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj == NULL) {
|
if (dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf == NULL) {
|
||||||
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj = calloc(2, sizeof(DMOBJ *));
|
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf = calloc(2, sizeof(DMLEAF *));
|
||||||
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj[0] = dynamic_obj[i].root_obj;
|
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[0] = dynamic_obj[i].root_leaf;
|
||||||
} else {
|
} else {
|
||||||
int idx = get_obj_idx(dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj);
|
int idx = get_leaf_idx(dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf);
|
||||||
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj = realloc(dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj, (idx + 2) * sizeof(DMOBJ *));
|
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf = realloc(dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf, (idx + 2) * sizeof(DMLEAF *));
|
||||||
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj[idx] = dynamic_obj[i].root_obj;
|
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[idx] = dynamic_obj[i].root_leaf;
|
||||||
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].nextobj[idx+1] = NULL;
|
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[idx+1] = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dynamic_obj[i].root_leaf) {
|
|
||||||
|
|
||||||
if (dm_entryobj->dynamicleaf == NULL) {
|
|
||||||
dm_entryobj->dynamicleaf = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_leaf));
|
|
||||||
dm_entryobj->dynamicleaf[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
|
|
||||||
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
|
|
||||||
dm_entryobj->dynamicleaf[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf == NULL) {
|
|
||||||
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf = calloc(2, sizeof(DMLEAF *));
|
|
||||||
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[0] = dynamic_obj[i].root_leaf;
|
|
||||||
} else {
|
|
||||||
int idx = get_leaf_idx(dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf);
|
|
||||||
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf = realloc(dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf, (idx + 2) * sizeof(DMLEAF *));
|
|
||||||
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[idx] = dynamic_obj[i].root_leaf;
|
|
||||||
dm_entryobj->dynamicleaf[INDX_LIBRARY_MOUNT].nextleaf[idx+1] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_list_loaded_libraries(&loaded_library_list, handle);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (dir) closedir(dir);
|
|
||||||
}
|
}
|
||||||
|
add_list_loaded_libraries(&loaded_library_list, handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@
|
||||||
|
|
||||||
#include "../dmcommon.h"
|
#include "../dmcommon.h"
|
||||||
|
|
||||||
#define LIBRARY_FOLDER_PATH "/usr/lib/bbfdm"
|
int load_dotso_plugins(DMOBJ *entryobj, const char *path);
|
||||||
|
|
||||||
int load_dotso_plugins(DMOBJ *entryobj);
|
|
||||||
int free_dotso_plugins(void);
|
int free_dotso_plugins(void);
|
||||||
|
|
||||||
#endif //__DOTSO_PLUGIN_H__
|
#endif //__DOTSO_PLUGIN_H__
|
||||||
|
|
|
||||||
|
|
@ -1860,74 +1860,60 @@ void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json
|
||||||
FREE(full_obj);
|
FREE(full_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_json_plugins(DMOBJ *entryobj)
|
int load_json_plugins(DMOBJ *entryobj, const char *plugin_path)
|
||||||
{
|
{
|
||||||
struct dirent *ent = NULL;
|
int json_plugin_version = JSON_VERSION_0;
|
||||||
DIR *dir = NULL;
|
|
||||||
|
|
||||||
if (folder_exists(JSON_FOLDER_PATH)) {
|
json_object *json = json_object_from_file(plugin_path);
|
||||||
sysfs_foreach_file(JSON_FOLDER_PATH, dir, ent) {
|
if (!json)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!strstr(ent->d_name, ".json"))
|
json_object_object_foreach(json, key, jobj) {
|
||||||
continue;
|
if (!key)
|
||||||
|
break;
|
||||||
|
|
||||||
char buf[512] = {0};
|
if (strcmp(key, "json_plugin_version") == 0) {
|
||||||
int json_plugin_version = JSON_VERSION_0;
|
json_plugin_version = json_object_get_int(jobj);
|
||||||
|
continue;
|
||||||
snprintf(buf, sizeof(buf), "%s/%s", JSON_FOLDER_PATH, ent->d_name);
|
|
||||||
|
|
||||||
json_object *json = json_object_from_file(buf);
|
|
||||||
if (!json) continue;
|
|
||||||
|
|
||||||
json_object_object_foreach(json, key, jobj) {
|
|
||||||
if (!key)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (strcmp(key, "json_plugin_version") == 0) {
|
|
||||||
json_plugin_version = json_object_get_int(jobj);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DMOBJ *dm_entryobj = NULL;
|
|
||||||
char obj_prefix[MAX_DM_LENGTH] = {0};
|
|
||||||
|
|
||||||
char *obj_path = replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
|
|
||||||
find_prefix_obj(obj_path, obj_prefix, MAX_DM_LENGTH);
|
|
||||||
|
|
||||||
bool obj_exists = find_entry_obj(entryobj, obj_prefix, &dm_entryobj);
|
|
||||||
if (obj_exists == 0 || !dm_entryobj) {
|
|
||||||
FREE(obj_path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dm_entryobj->nextdynamicobj == NULL) {
|
|
||||||
dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj));
|
|
||||||
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
|
|
||||||
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
|
|
||||||
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
|
|
||||||
dm_entryobj->nextdynamicobj[INDX_SERVICE_MOUNT].idx_type = INDX_SERVICE_MOUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj == NULL) {
|
|
||||||
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj = calloc(2, sizeof(struct dm_obj_s *));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] == NULL) {
|
|
||||||
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] = dm_dynamic_calloc(&json_memhead, 2, sizeof(struct dm_obj_s));
|
|
||||||
parse_obj(obj_path, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], 0, json_plugin_version, &json_list);
|
|
||||||
} else {
|
|
||||||
int idx = get_entry_idx(dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0]);
|
|
||||||
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] = dm_dynamic_realloc(&json_memhead, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], (idx + 2) * sizeof(struct dm_obj_s));
|
|
||||||
memset(dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] + (idx + 1), 0, sizeof(struct dm_obj_s));
|
|
||||||
parse_obj(obj_path, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], idx, json_plugin_version, &json_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
FREE(obj_path);
|
|
||||||
}
|
|
||||||
save_loaded_json_files(&loaded_json_files, json);
|
|
||||||
}
|
}
|
||||||
if (dir) closedir(dir);
|
|
||||||
|
DMOBJ *dm_entryobj = NULL;
|
||||||
|
char obj_prefix[MAX_DM_LENGTH] = {0};
|
||||||
|
|
||||||
|
char *obj_path = replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
|
||||||
|
find_prefix_obj(obj_path, obj_prefix, MAX_DM_LENGTH);
|
||||||
|
|
||||||
|
bool obj_exists = find_entry_obj(entryobj, obj_prefix, &dm_entryobj);
|
||||||
|
if (obj_exists == 0 || !dm_entryobj) {
|
||||||
|
FREE(obj_path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dm_entryobj->nextdynamicobj == NULL) {
|
||||||
|
dm_entryobj->nextdynamicobj = calloc(__INDX_DYNAMIC_MAX, sizeof(struct dm_dynamic_obj));
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].idx_type = INDX_JSON_MOUNT;
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_LIBRARY_MOUNT].idx_type = INDX_LIBRARY_MOUNT;
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_VENDOR_MOUNT].idx_type = INDX_VENDOR_MOUNT;
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_SERVICE_MOUNT].idx_type = INDX_SERVICE_MOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj == NULL) {
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj = calloc(2, sizeof(struct dm_obj_s *));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] == NULL) {
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] = dm_dynamic_calloc(&json_memhead, 2, sizeof(struct dm_obj_s));
|
||||||
|
parse_obj(obj_path, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], 0, json_plugin_version, &json_list);
|
||||||
|
} else {
|
||||||
|
int idx = get_entry_idx(dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0]);
|
||||||
|
dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] = dm_dynamic_realloc(&json_memhead, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], (idx + 2) * sizeof(struct dm_obj_s));
|
||||||
|
memset(dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] + (idx + 1), 0, sizeof(struct dm_obj_s));
|
||||||
|
parse_obj(obj_path, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], idx, json_plugin_version, &json_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE(obj_path);
|
||||||
}
|
}
|
||||||
|
save_loaded_json_files(&loaded_json_files, json);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,11 @@
|
||||||
|
|
||||||
#include "../dmcommon.h"
|
#include "../dmcommon.h"
|
||||||
|
|
||||||
#define JSON_FOLDER_PATH "/etc/bbfdm/json"
|
|
||||||
|
|
||||||
void save_loaded_json_files(struct list_head *json_list, json_object *data);
|
void save_loaded_json_files(struct list_head *json_list, json_object *data);
|
||||||
void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json_version, struct list_head *list);
|
void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json_version, struct list_head *list);
|
||||||
void find_prefix_obj(char *full_obj, char *prefix_obj, size_t len);
|
void find_prefix_obj(char *full_obj, char *prefix_obj, size_t len);
|
||||||
|
|
||||||
int load_json_plugins(DMOBJ *entryobj);
|
int load_json_plugins(DMOBJ *entryobj, const char *path);
|
||||||
int free_json_plugins(void);
|
int free_json_plugins(void);
|
||||||
|
|
||||||
#endif //__DMENTRYJSON_H__
|
#endif //__DMENTRYJSON_H__
|
||||||
|
|
|
||||||
|
|
@ -93,8 +93,7 @@ INSTALL(TARGETS bbfdm
|
||||||
|
|
||||||
INSTALL(DIRECTORY DESTINATION etc/bbfdm)
|
INSTALL(DIRECTORY DESTINATION etc/bbfdm)
|
||||||
INSTALL(DIRECTORY DESTINATION etc/bbfdm/dmmap)
|
INSTALL(DIRECTORY DESTINATION etc/bbfdm/dmmap)
|
||||||
INSTALL(DIRECTORY DESTINATION etc/bbfdm/json)
|
INSTALL(DIRECTORY DESTINATION etc/bbfdm/plugins)
|
||||||
INSTALL(DIRECTORY DESTINATION usr/lib/bbfdm)
|
|
||||||
|
|
||||||
FILE(GLOB root_device dmtree/tr181/device.h dmtree/vendor/vendor.h)
|
FILE(GLOB root_device dmtree/tr181/device.h dmtree/vendor/vendor.h)
|
||||||
INSTALL(FILES ${root_device}
|
INSTALL(FILES ${root_device}
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,6 @@ static int setup(void **state)
|
||||||
|
|
||||||
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
||||||
|
|
||||||
// Enable Plugins
|
|
||||||
ctx->enable_plugins = true;
|
|
||||||
|
|
||||||
*state = ctx;
|
*state = ctx;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -46,13 +43,13 @@ static int teardown_commit(void **state)
|
||||||
|
|
||||||
static int group_init(void **state)
|
static int group_init(void **state)
|
||||||
{
|
{
|
||||||
bbf_global_init(TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, true);
|
bbf_global_init(TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, "/etc/bbfdm/plugins");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int group_teardown(void **state)
|
static int group_teardown(void **state)
|
||||||
{
|
{
|
||||||
bbf_global_clean(TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, true);
|
bbf_global_clean(TR181_ROOT_TREE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,6 @@ static DM_MAP_VENDOR *TR181_VENDOR_EXTENSION[2] = {
|
||||||
};
|
};
|
||||||
static DM_MAP_VENDOR_EXCLUDE *TR181_VENDOR_EXTENSION_EXCLUDE = tVendorExtensionExclude;
|
static DM_MAP_VENDOR_EXCLUDE *TR181_VENDOR_EXTENSION_EXCLUDE = tVendorExtensionExclude;
|
||||||
|
|
||||||
#define DROPBEAR_FILE_PATH "../files/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json"
|
|
||||||
#define DROPBEAR_JSON_PATH "/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json"
|
|
||||||
#define LIBBBF_TEST_PATH "../bbf_test/libbbf_test.so"
|
|
||||||
#define LIBBBF_TEST_BBFDM_PATH "/usr/lib/bbfdm/libbbf_test.so"
|
|
||||||
|
|
||||||
static int setup(void **state)
|
static int setup(void **state)
|
||||||
{
|
{
|
||||||
struct dmctx *ctx = calloc(1, sizeof(struct dmctx));
|
struct dmctx *ctx = calloc(1, sizeof(struct dmctx));
|
||||||
|
|
@ -30,9 +25,6 @@ static int setup(void **state)
|
||||||
|
|
||||||
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
||||||
|
|
||||||
// Enable Plugins
|
|
||||||
ctx->enable_plugins = true;
|
|
||||||
|
|
||||||
*state = ctx;
|
*state = ctx;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -62,13 +54,13 @@ static int teardown_revert(void **state)
|
||||||
|
|
||||||
static int group_init(void **state)
|
static int group_init(void **state)
|
||||||
{
|
{
|
||||||
bbf_global_init(TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, true);
|
bbf_global_init(TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, "/etc/bbfdm/plugins");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int group_teardown(void **state)
|
static int group_teardown(void **state)
|
||||||
{
|
{
|
||||||
bbf_global_clean(TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE, true);
|
bbf_global_clean(TR181_ROOT_TREE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -602,9 +594,6 @@ static void test_api_bbfdm_json_get_value(void **state)
|
||||||
bbf_ctx_clean_sub(ctx);
|
bbf_ctx_clean_sub(ctx);
|
||||||
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
||||||
|
|
||||||
// Enable Plugins
|
|
||||||
ctx->enable_plugins = true;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test of JSON Parameter Path
|
* Test of JSON Parameter Path
|
||||||
*/
|
*/
|
||||||
|
|
@ -617,38 +606,6 @@ static void test_api_bbfdm_json_get_value(void **state)
|
||||||
|
|
||||||
bbf_ctx_clean_sub(ctx);
|
bbf_ctx_clean_sub(ctx);
|
||||||
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
||||||
|
|
||||||
// Enable Plugins
|
|
||||||
ctx->enable_plugins = true;
|
|
||||||
|
|
||||||
remove(DROPBEAR_JSON_PATH);
|
|
||||||
|
|
||||||
ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.";
|
|
||||||
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
|
|
||||||
assert_int_equal(fault, FAULT_9005);
|
|
||||||
|
|
||||||
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
|
|
||||||
assert_true(&first_entry->list == &ctx->list_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_api_bbfdm_json_set_value(void **state)
|
|
||||||
{
|
|
||||||
struct dmctx *ctx = (struct dmctx *) *state;
|
|
||||||
int fault = 0;
|
|
||||||
|
|
||||||
dmcmd("/bin/cp", 2, DROPBEAR_FILE_PATH, DROPBEAR_JSON_PATH);
|
|
||||||
|
|
||||||
ctx->in_param = "Device.UserInterface.Enable";
|
|
||||||
ctx->in_value = "true";
|
|
||||||
|
|
||||||
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
|
|
||||||
assert_int_equal(fault, 0);
|
|
||||||
|
|
||||||
ctx->in_param = "Device.X_IOPSYS_EU_Dropbear.1.Port";
|
|
||||||
ctx->in_value = "9856";
|
|
||||||
|
|
||||||
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
|
|
||||||
assert_int_equal(fault, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_api_bbfdm_json_add_object(void **state)
|
static void test_api_bbfdm_json_add_object(void **state)
|
||||||
|
|
@ -698,9 +655,6 @@ static void test_api_bbfdm_library_get_value(void **state)
|
||||||
bbf_ctx_clean_sub(ctx);
|
bbf_ctx_clean_sub(ctx);
|
||||||
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
||||||
|
|
||||||
// Enable Plugins
|
|
||||||
ctx->enable_plugins = true;
|
|
||||||
|
|
||||||
ctx->in_param = "Device.WiFi.SSID.1.Enable";
|
ctx->in_param = "Device.WiFi.SSID.1.Enable";
|
||||||
|
|
||||||
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
|
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
|
||||||
|
|
@ -710,40 +664,6 @@ static void test_api_bbfdm_library_get_value(void **state)
|
||||||
assert_true(&first_entry->list != &ctx->list_parameter);
|
assert_true(&first_entry->list != &ctx->list_parameter);
|
||||||
|
|
||||||
bbf_ctx_clean_sub(ctx);
|
bbf_ctx_clean_sub(ctx);
|
||||||
bbf_ctx_init(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
|
|
||||||
|
|
||||||
// Enable Plugins
|
|
||||||
ctx->enable_plugins = true;
|
|
||||||
|
|
||||||
remove(LIBBBF_TEST_BBFDM_PATH);
|
|
||||||
|
|
||||||
ctx->in_param = "Device.X_IOPSYS_EU_Syslog.";
|
|
||||||
|
|
||||||
fault = bbf_entry_method(ctx, BBF_GET_VALUE);
|
|
||||||
assert_int_equal(fault, FAULT_9005);
|
|
||||||
|
|
||||||
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
|
|
||||||
assert_true(&first_entry->list == &ctx->list_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_api_bbfdm_library_set_value(void **state)
|
|
||||||
{
|
|
||||||
struct dmctx *ctx = (struct dmctx *) *state;
|
|
||||||
int fault = 0;
|
|
||||||
|
|
||||||
dmcmd("/bin/cp", 2, LIBBBF_TEST_PATH, LIBBBF_TEST_BBFDM_PATH);
|
|
||||||
|
|
||||||
ctx->in_param = "Device.WiFi.SSID.1.Enable";
|
|
||||||
ctx->in_value = "true";
|
|
||||||
|
|
||||||
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
|
|
||||||
assert_int_equal(fault, 0);
|
|
||||||
|
|
||||||
ctx->in_param = "Device.X_IOPSYS_EU_Syslog.ServerPort";
|
|
||||||
ctx->in_value = "9856";
|
|
||||||
|
|
||||||
fault = bbf_entry_method(ctx, BBF_SET_VALUE);
|
|
||||||
assert_int_equal(fault, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_api_bbfdm_library_add_object(void **state)
|
static void test_api_bbfdm_library_add_object(void **state)
|
||||||
|
|
@ -839,9 +759,6 @@ int main(void)
|
||||||
// JSON: Get Value method test cases
|
// JSON: Get Value method test cases
|
||||||
cmocka_unit_test_setup_teardown(test_api_bbfdm_json_get_value, setup, teardown_commit),
|
cmocka_unit_test_setup_teardown(test_api_bbfdm_json_get_value, setup, teardown_commit),
|
||||||
|
|
||||||
// JSON: Set Value method test cases
|
|
||||||
cmocka_unit_test_setup_teardown(test_api_bbfdm_json_set_value, setup, teardown_commit),
|
|
||||||
|
|
||||||
// JSON: Add Object method test cases
|
// JSON: Add Object method test cases
|
||||||
cmocka_unit_test_setup_teardown(test_api_bbfdm_json_add_object, setup, teardown_commit),
|
cmocka_unit_test_setup_teardown(test_api_bbfdm_json_add_object, setup, teardown_commit),
|
||||||
|
|
||||||
|
|
@ -851,9 +768,6 @@ int main(void)
|
||||||
// Library: Get Value method test cases
|
// Library: Get Value method test cases
|
||||||
cmocka_unit_test_setup_teardown(test_api_bbfdm_library_get_value, setup, teardown_commit),
|
cmocka_unit_test_setup_teardown(test_api_bbfdm_library_get_value, setup, teardown_commit),
|
||||||
|
|
||||||
// Library: Set Value method test cases
|
|
||||||
cmocka_unit_test_setup_teardown(test_api_bbfdm_library_set_value, setup, teardown_commit),
|
|
||||||
|
|
||||||
// Library: Add Object method test cases
|
// Library: Add Object method test cases
|
||||||
cmocka_unit_test_setup_teardown(test_api_bbfdm_library_add_object, setup, teardown_commit),
|
cmocka_unit_test_setup_teardown(test_api_bbfdm_library_add_object, setup, teardown_commit),
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue