Split 'bbfdmd' into two binaries: 'bbfdmd' (main tree) and 'dm-service' (micro-service tree)

This commit is contained in:
Amin Ben Romdhane 2024-09-10 09:30:50 +00:00 committed by IOPSYS Dev
parent ebdb414e09
commit 9a6dfdfe3e
No known key found for this signature in database
49 changed files with 629 additions and 1159 deletions

View file

@ -2,7 +2,7 @@ variables:
DEBUG: 'TRUE'
SOURCE_FOLDER: "."
FLAWFINDER_OPTIONS: "-m 4 --error-level=5"
CPPCHECK_OPTIONS: "--enable=all --suppress=variableScope --suppress=unusedFunction --suppress=constParameter --suppress=knownConditionTrueFalse -DBBF_VENDOR_PREFIX=X_IOPSYS_EU_ -DBBFDM_ENABLE_DOTSO_PLUGIN -DBBFDM_ENABLE_DOTSO_PLUGIN -DBBF_TR181 -DBBF_VENDOR_IOPSYS -i test/"
CPPCHECK_OPTIONS: "--enable=all --suppress=variableScope --suppress=unusedFunction --suppress=constParameter --suppress=knownConditionTrueFalse -DBBF_VENDOR_PREFIX=X_IOPSYS_EU_ -i test/"
include:
- project: 'iopsys/gitlab-ci-pipeline'

View file

@ -6,6 +6,7 @@ add_subdirectory(libbbfdm-api)
add_subdirectory(libbbfdm-ubus)
add_subdirectory(libbbfdm)
add_subdirectory(bbfdmd)
add_subdirectory(dm-service)
# Capture the environment variables
set(MY_CC "$ENV{CC}")

View file

@ -8,5 +8,5 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/
FILE(GLOB BBF_SOURCES *.c)
ADD_EXECUTABLE(bbfdmd ${BBF_SOURCES})
TARGET_LINK_LIBRARIES(bbfdmd bbfdm-ubus)
TARGET_LINK_LIBRARIES(bbfdmd bbfdm-ubus bbfdm)
INSTALL(TARGETS bbfdmd DESTINATION usr/sbin)

View file

@ -15,91 +15,43 @@
#include "bbfdm-ubus.h"
#include "cli.h"
#include "libbbfdm/device.h"
static void usage(char *prog)
{
fprintf(stderr, "Usage: %s [options]\n", prog);
fprintf(stderr, "\n");
fprintf(stderr, "options:\n");
fprintf(stderr, " -s <socket path> ubus socket\n");
fprintf(stderr, " -m <json path> json input configuration for micro services\n");
fprintf(stderr, " -c <command input> Run cli command\n");
fprintf(stderr, " -h Displays this help\n");
fprintf(stderr, " -l <loglevel> log verbosity value as per standard syslog\n");
fprintf(stderr, " -h Displays this help\n");
fprintf(stderr, "\n");
}
static int parse_input_cli_options(bbfdm_config_t *config, json_object *json_obj)
{
char *opt_val = NULL;
if (!config || !json_obj) {
fprintf(stderr, "Invalid input options \n");
return -1;
}
opt_val = dmjson_get_value(json_obj, 3, "cli", "config", "proto");
if (DM_STRLEN(opt_val)) {
config->proto = get_proto_type(opt_val);
} else {
config->proto = BBFDM_BOTH;
}
opt_val = dmjson_get_value(json_obj, 3, "cli", "input", "type");
if (DM_STRLEN(opt_val)) {
snprintf(config->cli_in_type, sizeof(config->cli_in_type), "%s", opt_val);
}
opt_val = dmjson_get_value(json_obj, 3, "cli", "input", "name");
if (DM_STRLEN(opt_val)) {
snprintf(config->cli_in_name, sizeof(config->cli_in_name), "%s", opt_val);
}
opt_val = dmjson_get_value(json_obj, 3, "cli", "input", "plugin_dir");
if (DM_STRLEN(opt_val)) {
snprintf(config->cli_in_plugin_dir, sizeof(config->cli_in_plugin_dir), "%s", opt_val);
}
opt_val = dmjson_get_value(json_obj, 3, "cli", "output", "type");
if (DM_STRLEN(opt_val)) {
snprintf(config->cli_out_type, sizeof(config->cli_out_type), "%s", opt_val);
}
return 0;
}
static int load_cli_config(bbfdm_config_t *config)
{
json_object *json_obj = NULL;
json_obj = json_object_from_file(BBFDM_JSON_INPUT);
if (!json_obj) {
fprintf(stderr, "Failed to read input %s file \n", BBFDM_JSON_INPUT);
return -1;
}
parse_input_cli_options(config, json_obj);
json_object_put(json_obj);
return 0;
}
int main(int argc, char **argv)
{
struct bbfdm_context bbfdm_ctx = {0};
char *cli_argv[4] = {0};
int log_level = 3; // Default is LOG_ERR
int err = 0, ch, cli_argc = 0, i;
memset(&bbfdm_ctx, 0, sizeof(struct bbfdm_context));
while ((ch = getopt(argc, argv, "hs:m:c:")) != -1) {
while ((ch = getopt(argc, argv, "hc:l:")) != -1) {
switch (ch) {
case 'm':
bbfdm_ubus_set_service_name(&bbfdm_ctx, optarg);
break;
case 'c':
cli_argc = argc-optind+1;
for (i = 0; i < cli_argc; i++) {
cli_argv[i] = argv[optind - 1 + i];
}
break;
case 'l':
if (optarg) {
log_level = (int)strtod(optarg, NULL);
if (log_level < 0 || log_level > 7)
log_level = 3;
}
break;
case 'h':
usage(argv[0]);
exit(0);
@ -109,41 +61,25 @@ int main(int argc, char **argv)
}
if (cli_argc) {
if (dm_is_micro_service() == true) {
fprintf(stderr, "Failed to run cli with micro-service\n");
return -1;
}
err = load_cli_config(&bbfdm_ctx.config);
if (err) {
fprintf(stderr, "Failed to load cli config from json file (%s)\n", BBFDM_JSON_INPUT);
return err;
}
return bbfdm_cli_exec_command(&bbfdm_ctx.config, cli_argc, cli_argv);
return bbfdm_cli_exec_command(cli_argc, cli_argv);
}
openlog("bbfdm", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
bbfdm_ubus_set_log_level(log_level);
bbfdm_ubus_load_data_model(tDynamicObj);
openlog(BBFDM_DEFAULT_UBUS_OBJ, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
err = bbfdm_ubus_regiter_init(&bbfdm_ctx);
if (err != 0)
goto exit;
if (dm_is_micro_service() == true) {
char proc_name[32] = {0};
// Create process name using service name and prefix "dm_"
snprintf(proc_name, sizeof(proc_name), "dm_%s", bbfdm_ctx.config.service_name);
// Set process name for the current process
prctl(PR_SET_NAME, proc_name, NULL, NULL, NULL);
}
BBF_INFO("Waiting on uloop....");
uloop_run();
exit:
bbfdm_ubus_regiter_free(&bbfdm_ctx);
if (err != -5) // Error code is not -5, indicating that ubus_ctx is connected, proceed with shutdown
bbfdm_ubus_regiter_free(&bbfdm_ctx);
closelog();
return err;

View file

@ -14,23 +14,9 @@
#include "common.h"
#include "plugin.h"
extern struct list_head loaded_json_files;
extern struct list_head json_list;
extern struct list_head json_memhead;
#define UNUSED __attribute__((unused))
static DMOBJ *CLI_DM_ROOT_OBJ = NULL;
static void *cli_lib_handle = NULL;
typedef struct {
struct dmctx bbf_ctx;
unsigned int proto;
char in_name[128];
char in_plugin_dir[128];
char in_type[32];
char out_type[32];
char *cmd;
bool ubus_status;
} cli_data_t;
@ -38,27 +24,22 @@ typedef struct {
typedef struct {
char *name;
int num_args;
int (*exec_cmd)(cli_data_t *cli_data, char *argv[]);
int (*exec_cmd)(cli_data_t *cli_data, const char *path, const char *value);
char *usage;
} cli_cmd_t;
static int cli_exec_help(cli_data_t *cli_data UNUSED, char *argv[] UNUSED);
static int cli_exec_get(cli_data_t *cli_data, char *argv[]);
static int cli_exec_set(cli_data_t *cli_data, char *argv[]);
static int cli_exec_add(cli_data_t *cli_data, char *argv[]);
static int cli_exec_del(cli_data_t *cli_data, char *argv[]);
static int cli_exec_instances(cli_data_t *cli_data, char *argv[]);
static int cli_exec_schema(cli_data_t *cli_data, char *argv[]);
static int cli_exec_help(cli_data_t *cli_data UNUSED, const char *path UNUSED, const char *value UNUSED);
static int cli_exec_cmd(cli_data_t *cli_data, const char *path, const char *value);
cli_cmd_t cli_commands[] = {
// Name NumArgs Exec callback Usage String
{ "help", 0, cli_exec_help, "help" },
{ "get", 1, cli_exec_get, "get [path-expr]" },
{ "set", 2, cli_exec_set, "set [path-expr] [value]"},
{ "add", 1, cli_exec_add, "add [object]"},
{ "del", 1, cli_exec_del, "del [path-expr]"},
{ "instances", 1, cli_exec_instances, "instances [path-expr]" },
{ "schema", 1, cli_exec_schema, "schema [path-expr]"},
{ "get", 1, cli_exec_cmd, "get [path-expr]" },
{ "set", 2, cli_exec_cmd, "set [path-expr] [value]"},
{ "add", 1, cli_exec_cmd, "add [object]"},
{ "del", 1, cli_exec_cmd, "del [path-expr]"},
{ "instances", 1, cli_exec_cmd, "instances [path-expr]" },
{ "schema", 1, cli_exec_cmd, "schema [path-expr]"},
};
typedef void (*__ubus_cb)(struct ubus_request *req, int type, struct blob_attr *msg);
@ -167,7 +148,7 @@ static void __ubus_callback(struct ubus_request *req, int msgtype __attribute__(
}
}
static int in_ubus_out_cli_exec_cmd(cli_data_t *cli_data, const char *path, const char *value)
static int cli_exec_cmd(cli_data_t *cli_data, const char *path, const char *value)
{
struct blob_buf b = {0};
void *table = NULL;
@ -181,19 +162,18 @@ static int in_ubus_out_cli_exec_cmd(cli_data_t *cli_data, const char *path, cons
if (value) blobmsg_add_string(&b, "value", value);
table = blobmsg_open_table(&b, "optional");
blobmsg_add_string(&b, "proto", (cli_data->proto == BBFDM_CWMP) ? "cwmp" : (cli_data->proto == BBFDM_USP) ? "usp" : "both");
blobmsg_add_string(&b, "format", "raw");
blobmsg_close_table(&b, table);
int e = bbfdm_ubus_invoke(cli_data->in_name, cli_data->cmd, b.head, __ubus_callback, cli_data);
int e = bbfdm_ubus_invoke(BBFDM_DEFAULT_UBUS_OBJ, cli_data->cmd, b.head, __ubus_callback, cli_data);
if (e < 0) {
printf("ERROR: ubus invoke for [object:%s method:%s] exit with error(%d)\n", cli_data->in_name, cli_data->cmd, e);
printf("ERROR: ubus invoke for [object:%s method:%s] exit with error(%d)\n", BBFDM_DEFAULT_UBUS_OBJ, cli_data->cmd, e);
err = EXIT_FAILURE;
}
if (cli_data->ubus_status == false) {
printf("ERROR: ubus call for [object:%s method:%s] exit with error\n", cli_data->in_name, cli_data->cmd);
printf("ERROR: ubus call for [object:%s method:%s] exit with error\n", BBFDM_DEFAULT_UBUS_OBJ, cli_data->cmd);
err = EXIT_FAILURE;
}
@ -202,45 +182,7 @@ static int in_ubus_out_cli_exec_cmd(cli_data_t *cli_data, const char *path, cons
return err;
}
static int bbfdm_load_cli_config(bbfdm_config_t *bbf_config, cli_data_t *cli_data)
{
char *opt_val = NULL;
cli_data->proto = bbf_config->proto;
opt_val = bbf_config->cli_in_type;
if (opt_val && strlen(opt_val)) {
snprintf(cli_data->in_type, sizeof(cli_data->in_type), "%s", opt_val);
} else {
printf("ERROR: [cli.input.type] not specified\n");
return -1;
}
opt_val = bbf_config->cli_in_name;
if (opt_val && strlen(opt_val)) {
snprintf(cli_data->in_name, sizeof(cli_data->in_name), "%s", opt_val);
} else {
printf("ERROR: [cli.input.name] not specified\n");
return -1;
}
opt_val = bbf_config->cli_in_plugin_dir;
if (opt_val && strlen(opt_val)) {
snprintf(cli_data->in_plugin_dir, sizeof(cli_data->in_plugin_dir), "%s", opt_val);
}
opt_val = bbf_config->cli_out_type;
if (opt_val && strlen(opt_val)) {
snprintf(cli_data->out_type, sizeof(cli_data->out_type), "%s", opt_val);
} else {
printf("ERROR: [cli.output.type] not specified\n");
return -1;
}
return 0;
}
static int cli_exec_help(cli_data_t *cli_data UNUSED, char *argv[] UNUSED)
static int cli_exec_help(cli_data_t *cli_data UNUSED, const char *path UNUSED, const char *value UNUSED)
{
cli_cmd_t *cli_cmd;
@ -255,285 +197,6 @@ static int cli_exec_help(cli_data_t *cli_data UNUSED, char *argv[] UNUSED)
return EXIT_SUCCESS;
}
static int in_dotso_out_cli_exec_get(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_GET_VALUE);
if (!err) {
struct blob_attr *cur = NULL;
size_t rem = 0;
blobmsg_for_each_attr(cur, cli_data->bbf_ctx.bb.head, rem) {
struct blob_attr *tb[2] = {0};
const struct blobmsg_policy p[2] = {
{ "path", BLOBMSG_TYPE_STRING },
{ "data", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 2, tb, blobmsg_data(cur), blobmsg_len(cur));
char *name = (tb[0]) ? blobmsg_get_string(tb[0]) : "";
char *data = (tb[1]) ? blobmsg_get_string(tb[1]) : "";
printf("%s => %s\n", name, data);
}
// Apply all bbfdm changes
dmuci_commit_bbfdm();
} else {
printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param);
dmuci_revert_bbfdm();
err = EXIT_FAILURE;
}
return err;
}
static int in_ubus_out_cli_exec_get(cli_data_t *cli_data, char *argv[])
{
return in_ubus_out_cli_exec_cmd(cli_data, argv[0], argv[1]);
}
static int cli_exec_get(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_get(cli_data, argv);
else if (strcasecmp(cli_data->in_type, "UBUS") == 0)
err = in_ubus_out_cli_exec_get(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_set(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
cli_data->bbf_ctx.in_value = argv[1];
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_SET_VALUE);
if (!err) {
printf("%s => Set value is successfully done\n", cli_data->bbf_ctx.in_param);
bbf_entry_services(cli_data->proto, true, true);
} else {
printf("Fault %d: %s\n", err, cli_data->bbf_ctx.fault_msg);
bbf_entry_services(cli_data->proto, false, true);
err = EXIT_FAILURE;
}
return err;
}
static int in_ubus_out_cli_exec_set(cli_data_t *cli_data, char *argv[])
{
return in_ubus_out_cli_exec_cmd(cli_data, argv[0], argv[1]);
}
static int cli_exec_set(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_set(cli_data, argv);
else if (strcasecmp(cli_data->in_type, "UBUS") == 0)
err = in_ubus_out_cli_exec_set(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_add(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_ADD_OBJECT);
if (!err) {
printf("Added %s%s.\n", cli_data->bbf_ctx.in_param, cli_data->bbf_ctx.addobj_instance);
bbf_entry_services(cli_data->proto, true, false);
} else {
printf("Fault %d: %s\n", err, cli_data->bbf_ctx.fault_msg);
bbf_entry_services(cli_data->proto, false, false);
err = EXIT_FAILURE;
}
return err;
}
static int in_ubus_out_cli_exec_add(cli_data_t *cli_data, char *argv[])
{
return in_ubus_out_cli_exec_cmd(cli_data, argv[0], argv[1]);
}
static int cli_exec_add(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_add(cli_data, argv);
else if (strcasecmp(cli_data->in_type, "UBUS") == 0)
err = in_ubus_out_cli_exec_add(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_del(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_DEL_OBJECT);
if (!err) {
printf("Deleted %s\n", cli_data->bbf_ctx.in_param);
bbf_entry_services(cli_data->proto, true, true);
} else {
printf("Fault %d: %s\n", err, cli_data->bbf_ctx.fault_msg);
bbf_entry_services(cli_data->proto, false, true);
err = EXIT_FAILURE;
}
return err;
}
static int in_ubus_out_cli_exec_del(cli_data_t *cli_data, char *argv[])
{
return in_ubus_out_cli_exec_cmd(cli_data, argv[0], argv[1]);
}
static int cli_exec_del(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_del(cli_data, argv);
else if (strcasecmp(cli_data->in_type, "UBUS") == 0)
err = in_ubus_out_cli_exec_del(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_instances(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
cli_data->bbf_ctx.nextlevel = false;
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_INSTANCES);
if (!err) {
struct blob_attr *cur = NULL;
size_t rem = 0;
blobmsg_for_each_attr(cur, cli_data->bbf_ctx.bb.head, rem) {
struct blob_attr *tb[1] = {0};
const struct blobmsg_policy p[1] = {
{ "path", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 1, tb, blobmsg_data(cur), blobmsg_len(cur));
printf("%s\n", (tb[0]) ? blobmsg_get_string(tb[0]) : "");
}
} else {
printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param);
err = EXIT_FAILURE;
}
return err;
}
static int in_ubus_out_cli_exec_instances(cli_data_t *cli_data, char *argv[])
{
return in_ubus_out_cli_exec_cmd(cli_data, argv[0], argv[1]);
}
static int cli_exec_instances(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_instances(cli_data, argv);
else if (strcasecmp(cli_data->in_type, "UBUS") == 0)
err = in_ubus_out_cli_exec_instances(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int in_dotso_out_cli_exec_schema(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
cli_data->bbf_ctx.in_param = argv[0];
cli_data->bbf_ctx.nextlevel = false;
cli_data->bbf_ctx.iscommand = true;
cli_data->bbf_ctx.isevent = true;
cli_data->bbf_ctx.isinfo = true;
err = bbf_entry_method(&cli_data->bbf_ctx, BBF_SCHEMA);
if (!err) {
struct blob_attr *cur = NULL;
size_t rem = 0;
blobmsg_for_each_attr(cur, cli_data->bbf_ctx.bb.head, rem) {
struct blob_attr *tb[3] = {0};
const struct blobmsg_policy p[3] = {
{ "path", BLOBMSG_TYPE_STRING },
{ "data", BLOBMSG_TYPE_STRING },
{ "type", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
char *name = (tb[0]) ? blobmsg_get_string(tb[0]) : "";
char *data = (tb[1]) ? blobmsg_get_string(tb[1]) : "";
char *type = (tb[2]) ? blobmsg_get_string(tb[2]) : "";
int cmd = get_dm_type(type);
printf("%s %s %s\n", name, type, (cmd != DMT_EVENT && cmd != DMT_COMMAND) ? data : "0");
}
} else {
printf("ERROR: %d retrieving %s\n", err, cli_data->bbf_ctx.in_param);
err = EXIT_FAILURE;
}
return err;
}
static int in_ubus_out_cli_exec_schema(cli_data_t *cli_data, char *argv[])
{
return in_ubus_out_cli_exec_cmd(cli_data, argv[0], argv[1]);
}
static int cli_exec_schema(cli_data_t *cli_data, char *argv[])
{
int err = EXIT_SUCCESS;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0)
err = in_dotso_out_cli_exec_schema(cli_data, argv);
else if (strcasecmp(cli_data->in_type, "UBUS") == 0)
err = in_ubus_out_cli_exec_schema(cli_data, argv);
else
err = EXIT_FAILURE;
return err;
}
static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
{
cli_cmd_t *cli_cmd = NULL;
@ -544,34 +207,6 @@ static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
if (!cli_data->cmd || strlen(cli_data->cmd) == 0)
return EXIT_FAILURE;
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0) {
if (strcasecmp(cli_data->in_type, "DotSO") == 0) {
if (load_dotso_plugin(&cli_lib_handle, cli_data->in_name, NULL, &CLI_DM_ROOT_OBJ) != 0) {
err = EXIT_FAILURE;
goto end;
}
} else {
if (load_json_plugin(&loaded_json_files, &json_list, &json_memhead, cli_data->in_name, NULL, &CLI_DM_ROOT_OBJ) != 0) {
err = EXIT_FAILURE;
goto end;
}
}
if (CLI_DM_ROOT_OBJ == NULL) {
err = EXIT_FAILURE;
goto end;
}
bbf_global_init(CLI_DM_ROOT_OBJ, cli_data->in_plugin_dir);
bbf_ctx_init(&cli_data->bbf_ctx, CLI_DM_ROOT_OBJ);
cli_data->bbf_ctx.dm_type = cli_data->proto;
} else if (strcasecmp(cli_data->in_type, "UBUS") != 0) {
return -1;
}
for (size_t i = 0; i < ARRAY_SIZE(cli_commands); i++) {
cli_cmd = &cli_commands[i];
@ -579,12 +214,12 @@ static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
if (argc-1 < cli_cmd->num_args) {
printf("ERROR: Number of arguments for %s method is wrong(%d), it should be %d\n", cli_cmd->name, argc-1, cli_cmd->num_args);
cli_commands[0].exec_cmd(cli_data, NULL);
cli_commands[0].exec_cmd(cli_data, NULL, NULL);
err = EXIT_FAILURE;
goto end;
}
err = cli_cmd->exec_cmd(cli_data, &argv[1]);
err = cli_cmd->exec_cmd(cli_data, argv[1], argv[2]);
registred_command = true;
break;
}
@ -592,33 +227,18 @@ static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
if (!registred_command) {
printf("ERROR: Unknown command: %s\n", cli_data->cmd);
cli_commands[0].exec_cmd(cli_data, NULL);
cli_commands[0].exec_cmd(cli_data, NULL, NULL);
err = EXIT_FAILURE;
}
end:
if (strcasecmp(cli_data->in_type, "DotSO") == 0) {
if (CLI_DM_ROOT_OBJ) {
bbf_ctx_clean(&cli_data->bbf_ctx);
bbf_global_clean(CLI_DM_ROOT_OBJ);
}
free_dotso_plugin(cli_lib_handle);
cli_lib_handle = NULL;
} else if (strcasecmp(cli_data->in_type, "JSON") == 0) {
if (CLI_DM_ROOT_OBJ) {
bbf_ctx_clean(&cli_data->bbf_ctx);
bbf_global_clean(CLI_DM_ROOT_OBJ);
}
free_json_plugin();
}
return err;
}
int bbfdm_cli_exec_command(bbfdm_config_t *bbf_config, int argc, char *argv[])
int bbfdm_cli_exec_command(int argc, char *argv[])
{
cli_data_t cli_data = {0};
int err = EXIT_SUCCESS;
// Exit if no command specified
if (argc < 1) {
@ -628,12 +248,5 @@ int bbfdm_cli_exec_command(bbfdm_config_t *bbf_config, int argc, char *argv[])
memset(&cli_data, 0, sizeof(cli_data_t));
err = bbfdm_load_cli_config(bbf_config, &cli_data);
if (err) {
printf("ERROR: required cli config missing\n");
return EXIT_FAILURE;
}
err = cli_exec_command(&cli_data, argc, argv);
return err;
return cli_exec_command(&cli_data, argc, argv);
}

View file

@ -8,4 +8,4 @@
* See LICENSE file for license related information.
*/
int bbfdm_cli_exec_command(bbfdm_config_t *bbf_config, int argc, char *argv[]);
int bbfdm_cli_exec_command(int argc, char *argv[]);

12
dm-service/CMakeLists.txt Normal file
View file

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.0)
PROJECT(dm-service C)
ADD_DEFINITIONS(-fstrict-aliasing -Wall -Wextra -Werror -Wformat -Wformat-signedness -fPIC -D_GNU_SOURCE)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/libbbfdm-api/ -I${CMAKE_SOURCE_DIR}/libbbfdm-ubus/")
FILE(GLOB BBF_SOURCES *.c)
ADD_EXECUTABLE(dm-service ${BBF_SOURCES})
TARGET_LINK_LIBRARIES(dm-service bbfdm-ubus)
INSTALL(TARGETS dm-service DESTINATION usr/sbin)

85
dm-service/dm_service.c Normal file
View file

@ -0,0 +1,85 @@
/*
* dm_service.c: dm-service deamon
*
* Copyright (C) 2024 IOPSYS Software Solutions AB. All rights reserved.
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
* See LICENSE file for license related information.
*/
#include <sys/prctl.h>
#include "common.h"
#include "bbfdm-ubus.h"
static void usage(char *prog)
{
fprintf(stderr, "Usage: %s [options]\n", prog);
fprintf(stderr, "\n");
fprintf(stderr, "options:\n");
fprintf(stderr, " -m <ms name> micro-service name\n");
fprintf(stderr, " -l <loglevel> log verbosity value as per standard syslog\n");
fprintf(stderr, " -h Displays this help\n");
fprintf(stderr, "\n");
}
int main(int argc, char **argv)
{
struct bbfdm_context bbfdm_ctx = {0};
char proc_name[32] = {0};
int log_level = 3; // Default is LOG_ERR
int err = 0, ch;
memset(&bbfdm_ctx, 0, sizeof(struct bbfdm_context));
while ((ch = getopt(argc, argv, "hl:m:")) != -1) {
switch (ch) {
case 'm':
bbfdm_ubus_set_service_name(&bbfdm_ctx, optarg);
break;
case 'l':
if (optarg) {
log_level = (int)strtod(optarg, NULL);
if (log_level < 0 || log_level > 7)
log_level = 3;
}
break;
case 'h':
usage(argv[0]);
exit(0);
default:
break;
}
}
if (dm_is_micro_service() == false) {
fprintf(stderr, "Failed to start micro-service without providing the name using '-m' option\n");
exit(-1);
}
bbfdm_ubus_set_log_level(log_level);
openlog(bbfdm_ctx.config.service_name, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
err = bbfdm_ubus_regiter_init(&bbfdm_ctx);
if (err != 0)
goto exit;
// Create process name using service name and prefix "dm_"
snprintf(proc_name, sizeof(proc_name), "dm_%s", bbfdm_ctx.config.service_name);
// Set process name for the current process
prctl(PR_SET_NAME, proc_name, NULL, NULL, NULL);
BBF_INFO("Waiting on uloop....");
uloop_run();
exit:
if (err != -5) // Error code is not -5, indicating that ubus_ctx is connected, proceed with shutdown
bbfdm_ubus_regiter_free(&bbfdm_ctx);
closelog();
return err;
}

View file

@ -25,27 +25,6 @@
"required": "no",
"default": "",
"description": "Path for ubus socket to register bbfdmd services"
},
{
"name": "loglevel",
"type": "integer",
"required": "no",
"default": "3",
"description": "Internal loglevel for debugging {0: No Logs; 1: Alert; 2: Critical; 3: Error; 4: Warning; 5: Notice; 6: Info; 7: Debug}"
},
{
"name": "subprocess_level",
"type": "integer",
"required": "no",
"default": "2",
"description": "This parameter configures when subprocess can be used for get operation. Level here denotes the Datamodel object depth up-to which subprocess will be used to collect the get data. For example, if this is configured to 1, then only get for 'Device.' shall be called within the subprocess. If configured as level 2, then all the get with up-to depth 2 like 'Device.WiFi.', 'Device.IP.' shall be called in subprocess."
},
{
"name": "refresh_time",
"type": "integer",
"required": "no",
"default": "5",
"description": "The time period in seconds after which bbfdmd will refresh the datamodel instances in a periodic manner. If configured to '0' then instance updater will be disabled. If not configured at all then after every 5 seconds datamodel instances will be refreshed."
}
]
},

View file

@ -84,57 +84,6 @@
<div class="td_row_even">Path for ubus socket to register bbfdmd services</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">loglevel</div>
</td>
<td class="td_row_even">
<div class="td_row_even">integer</div>
</td>
<td class="td_row_even">
<div class="td_row_even">no</div>
</td>
<td class="td_row_even">
<div class="td_row_even">1</div>
</td>
<td class="td_row_even">
<div class="td_row_even">Internal loglevel for debugging {0: No Logs; 1: Alert; 2: Critical; 3: Error; 4: Warning; 5: Notice; 6: Info; 7: Debug}</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">subprocess_level</div>
</td>
<td class="td_row_even">
<div class="td_row_even">integer</div>
</td>
<td class="td_row_even">
<div class="td_row_even">no</div>
</td>
<td class="td_row_even">
<div class="td_row_even">2</div>
</td>
<td class="td_row_even">
<div class="td_row_even">This parameter configures when subprocess can be used for get operation. Level here denotes the Datamodel object depth up-to which subprocess will be used to collect the get data. For example, if this is configured to 1, then only get for 'Device.' shall be called within the subprocess. If configured as level 2, then all the get with up-to depth 2 like 'Device.WiFi.', 'Device.IP.' shall be called in subprocess.</div>
</td>
</tr>
<tr>
<td class="td_row_even">
<div class="td_row_even">refresh_time</div>
</td>
<td class="td_row_even">
<div class="td_row_even">integer</div>
</td>
<td class="td_row_even">
<div class="td_row_even">no</div>
</td>
<td class="td_row_even">
<div class="td_row_even">5</div>
</td>
<td class="td_row_even">
<div class="td_row_even">The time period in seconds after which bbfdmd will refresh the datamodel instances in a periodic manner. If configured to '0' then instance updater will be disabled. If not configured at all then after every 5 seconds datamodel instances will be refreshed.</div>
</td>
</tr>
</tbody>
</table>
</td>

View file

@ -30,7 +30,7 @@ As per TR181, the root of the tree is 'Device.', which can be defined by using b
```bash
DM_MAP_OBJ tDynamicObj[] = {
{"Device.", tDeviceObj, tDeviceParams},
{"Device.", tDMRootObj, tDMRootParams},
{0}
};
```
@ -74,7 +74,7 @@ Each object in the **DMOBJ** table contains the following arguments:
example:
```bash
/* *** Device. *** */
DMOBJ tDeviceObj[] = {
DMOBJ tDMRootObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type*/
{"DeviceInfo", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceInfoObj, tDeviceInfoParams, NULL, BBFDM_BOTH, NULL},
{0}
@ -209,7 +209,7 @@ DMLEAF tWiFiDataElementsAssociationEventParams[] = {
More leaf Example(s):
```bash
DMLEAF tDeviceParams[] = {
DMLEAF tDMRootParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"RootDataModelVersion", &DMREAD, DMT_STRING, get_Device_RootDataModelVersion, NULL, BBFDM_BOTH},
{"Reboot()", &DMSYNC, DMT_COMMAND, NULL, operate_Device_Reboot, BBFDM_USP},

View file

@ -2,7 +2,7 @@
`bbfdm` provides tools to convert Broadband-forum's xml datamodel definition for cwmp and usp to a combined JSON file.
JSON definition of datamodel with latest release available in [datamodel.json](../../libbbfdm/dmtree/json/datamodel.json)
JSON definition of datamodel with latest release available in [datamodel.json](../../tools/datamodel.json)
Now, a partial node from this file can be used to create a JSON datamodel definition, provided user adds a mapping to all LEAF parameters and multi-instance object.

View file

@ -12,13 +12,8 @@
{
"daemon": {
"config": {
"loglevel": "1",
"refresh_time": "120",
"subprocess_level": "2"
},
"input": {
"type": "DotSo",
"name": "/usr/share/bbfdm/libbbfdm.so",
"plugin_dir": "/usr/share/bbfdm/plugins"
},
"output": {
@ -260,8 +255,6 @@ Some datamodel operations takes less time to execute compared to other, like
executing/serializing operations simplifies the code from developer perspective, but its not suitable for deployments. To make it suitable `bbfdmd` support parallel calls.
- All datamodel `operate` commands are running in parallel
- `get` calls depends on uci option 'bbfdm.bbfdmd.subprocess_level' (default: 2)
example(s):

View file

@ -55,7 +55,6 @@ function install_libbbf()
COV_LDFLAGS='--coverage'
fi
VENDOR_LIST='iopsys'
VENDOR_PREFIX='X_IOPSYS_EU_'
echo "Compiling libbbf"
@ -65,7 +64,7 @@ function install_libbbf()
mkdir -p build
cd build
cmake ../ -DCMAKE_C_FLAGS="$COV_CFLAGS " -DCMAKE_EXE_LINKER_FLAGS="$COV_LDFLAGS -lm" -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" -DBBF_VENDOR_PREFIX="$VENDOR_PREFIX" -DBBF_MAX_OBJECT_INSTANCES=255 -DBBFDMD_MAX_MSG_LEN=1048576 -DCMAKE_INSTALL_PREFIX=/
exec_cmd_verbose make
echo "installing libbbf"

View file

@ -15,7 +15,7 @@ exec_cmd_verbose pylint -d R,C,W0603 tools/*.py
echo "********* Validate JSON Plugin *********"
echo "Validate BBF Data Model JSON Plugin"
./tools/validate_json_plugin.py libbbfdm/dmtree/json/datamodel.json
./tools/validate_json_plugin.py tools/datamodel.json
check_ret $?
echo "Validating plugins"

View file

@ -28,14 +28,10 @@
#include "get_helper.h"
#include "plugin.h"
#define BBFDM_DEFAULT_MICROSERVICE_INPUT_PATH "/etc/bbfdm/micro_services"
#define BBFDM_DEFAULT_MODULES_PATH "/usr/share/bbfdm"
#define BBFDM_DEFAULT_PLUGINS_PATH BBFDM_DEFAULT_MODULES_PATH"/plugins"
#define BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH BBFDM_DEFAULT_MODULES_PATH"/micro_services"
#define BBFDM_DEFAULT_UBUS_OBJ "bbfdm"
extern struct list_head loaded_json_files;
extern struct list_head json_list;
extern struct list_head json_memhead;
LIST_HEAD(head_registered_service);
@ -51,6 +47,7 @@ static void bbfdm_ctx_cleanup(struct bbfdm_context *u)
free_path_list(&u->instances);
free_path_list(&u->old_instances);
free_path_list(&u->config.list_objs);
/* Main daemon */
if (dm_is_micro_service() == false) {
@ -58,11 +55,10 @@ static void bbfdm_ctx_cleanup(struct bbfdm_context *u)
}
/* DotSo Plugin */
free_dotso_plugin(deamon_lib_handle);
deamon_lib_handle = NULL;
bbfdm_free_dotso_plugin(&deamon_lib_handle);
/* JSON Plugin */
free_json_plugin();
bbfdm_free_json_plugin();
}
static bool is_sync_operate_cmd(bbfdm_data_t *data __attribute__((unused)))
@ -70,21 +66,6 @@ static bool is_sync_operate_cmd(bbfdm_data_t *data __attribute__((unused)))
return false;
}
static bool is_subprocess_required(int subprocess_level, const char *path)
{
bool ret = false;
size_t len = DM_STRLEN(path);
if (len == 0)
return ret;
if (count_delim(path) < subprocess_level) {
if (path[len - 1] == '.')
ret = true;
}
return ret;
}
static void fill_optional_data(bbfdm_data_t *data, struct blob_attr *msg)
{
struct blob_attr *attr;
@ -269,7 +250,6 @@ static int bbfdm_get_handler(struct ubus_context *ctx, struct ubus_object *obj _
LIST_HEAD(paths_list);
bbfdm_data_t data;
uint8_t maxdepth = 0;
bool is_subprocess_needed = false;
struct bbfdm_context *u;
u = container_of(ctx, struct bbfdm_context, ubus_ctx);
@ -291,7 +271,6 @@ static int bbfdm_get_handler(struct ubus_context *ctx, struct ubus_object *obj _
if (tb[DM_GET_PATH]) {
char *path = blobmsg_get_string(tb[DM_GET_PATH]);
add_path_list(path, &paths_list);
is_subprocess_needed = is_subprocess_required(u->config.subprocess_level, path);
}
if (tb[DM_GET_PATHS]) {
@ -303,8 +282,6 @@ static int bbfdm_get_handler(struct ubus_context *ctx, struct ubus_object *obj _
char *path_str = blobmsg_get_string(path);
add_path_list(path_str, &paths_list);
if (!is_subprocess_needed)
is_subprocess_needed = is_subprocess_required(u->config.subprocess_level, path_str);
}
}
@ -318,12 +295,7 @@ static int bbfdm_get_handler(struct ubus_context *ctx, struct ubus_object *obj _
fill_optional_data(&data, tb[DM_GET_OPTIONAL]);
if (is_subprocess_needed) {
BBF_INFO("Creating subprocess for get method");
bbfdm_start_deferred(&data, bbfdm_get_value, false);
} else {
bbfdm_get_value(&data, NULL);
}
bbfdm_get_value(&data, NULL);
free_path_list(&paths_list);
return 0;
@ -1059,6 +1031,7 @@ static int register_service(struct ubus_context *ctx)
struct blob_buf bb = {0};
uint32_t ubus_id;
struct bbfdm_context *u;
struct pathNode *pn = NULL;
u = container_of(ctx, struct bbfdm_context, ubus_ctx);
if (u == NULL) {
@ -1078,8 +1051,11 @@ static int register_service(struct ubus_context *ctx)
blobmsg_add_string(&bb, "parent_dm", u->config.out_parent_dm);
void *arr = blobmsg_open_array(&bb, "objects");
for (int i = 0; i < MAX_OBJS && DM_STRLEN(u->config.out_objects[i]) != 0; i++)
blobmsg_add_string(&bb, NULL, u->config.out_objects[i]);
list_for_each_entry(pn, &u->config.list_objs, list) {
blobmsg_add_string(&bb, NULL, pn->path);
}
blobmsg_close_array(&bb, arr);
ubus_invoke(ctx, ubus_id, "service", bb.head, NULL, NULL, 5000);
@ -1088,162 +1064,85 @@ static int register_service(struct ubus_context *ctx)
return 0;
}
static int _parse_daemon_config_options(bbfdm_config_t *config, json_object *daemon_obj)
{
char *opt_val = NULL;
if (!config || !daemon_obj) {
fprintf(stderr, "Invalid input options \n");
return -1;
}
opt_val = dmjson_get_value(daemon_obj, 2, "config", "loglevel");
if (DM_STRLEN(opt_val)) {
int log_level = (int) strtoul(opt_val, NULL, 10);
bbfdm_ubus_set_log_level(log_level);
} else {
bbfdm_ubus_set_log_level(LOG_ERR);
}
opt_val = dmjson_get_value(daemon_obj, 2, "config", "subprocess_level");
if (DM_STRLEN(opt_val)) {
config->subprocess_level = (unsigned int) strtoul(opt_val, NULL, 10);
} else {
config->subprocess_level = 0;
}
return 0;
}
static int _parse_daemon_input_options(bbfdm_config_t *config, json_object *daemon_obj)
{
char *opt_val = NULL;
if (!config || !daemon_obj) {
fprintf(stderr, "Invalid input options \n");
return -1;
}
opt_val = dmjson_get_value(daemon_obj, 2, "input", "plugin_dir");
if (DM_STRLEN(opt_val)) {
strncpyt(config->in_plugin_dir, opt_val, sizeof(config->in_plugin_dir));
} else if(dm_is_micro_service() == false) {
strncpyt(config->in_plugin_dir, BBFDM_DEFAULT_PLUGINS_PATH, sizeof(config->in_plugin_dir));
}
opt_val = dmjson_get_value(daemon_obj, 2, "input", "name");
if (DM_STRLEN(opt_val)) {
strncpyt(config->in_name, opt_val, sizeof(config->in_name));
opt_val = strrchr(opt_val, '/');
if (opt_val) {
strncpyt(config->service_name, opt_val + 1, sizeof(config->service_name));
}
} else if (dm_is_micro_service() == false) { // default value for main process
snprintf(config->in_name, sizeof(config->in_name), "%s/libbbfdm.so", BBFDM_DEFAULT_MODULES_PATH);
strncpyt(config->service_name, BBFDM_DEFAULT_UBUS_OBJ, sizeof(config->service_name));
}
return 0;
}
static int _fill_daemon_input_option(bbfdm_config_t *config, char *sname)
static int _fill_daemon_input_option(json_object *daemon_obj, bbfdm_config_t *config)
{
char opt_val[MAX_DM_PATH] = {0};
if (!config || !sname || strlen(sname) == 0) {
fprintf(stderr, "Invalid input options for service name \n");
if (!config || strlen(config->service_name) == 0) {
BBF_ERR("Invalid input options for service name \n");
return -1;
}
strncpyt(config->service_name, sname, sizeof(config->service_name));
if (strchr(config->service_name, '/')) { // absolute path
char *srv_name = dmjson_get_value(daemon_obj, 1, "service_name");
if (strlen(srv_name)) {
strncpyt(config->service_name, srv_name, sizeof(config->service_name));
}
}
// check if the service plugin is DotSO plugin
snprintf(opt_val, MAX_DM_PATH, "%s/%s.so", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, sname);
snprintf(opt_val, MAX_DM_PATH, "%s/%s.so", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, config->service_name);
if (!file_exists(opt_val)) {
snprintf(opt_val, MAX_DM_PATH, "%s/%s.json", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, sname);
snprintf(opt_val, MAX_DM_PATH, "%s/%s.json", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, config->service_name);
}
if (!file_exists(opt_val)) {
fprintf(stderr, "Failed to load service plugin %s opt_val=%s\n", sname, opt_val);
BBF_ERR("Failed to load service plugin %s opt_val=%s\n", config->service_name, opt_val);
return -1;
}
strncpyt(config->in_name, opt_val, sizeof(config->in_name));
snprintf(opt_val, MAX_DM_PATH, "%s/%s", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, sname);
if (folder_exists(opt_val)) {
strncpyt(config->in_plugin_dir, opt_val, sizeof(config->in_plugin_dir));
}
return 0;
}
static int _parse_daemon_output_options(bbfdm_config_t *config, json_object *daemon_obj)
{
char *opt_val = NULL;
if (!config || !daemon_obj) {
fprintf(stderr, "Invalid input options \n");
return -1;
}
opt_val = dmjson_get_value(daemon_obj, 2, "output", "root_obj");
if (DM_STRLEN(opt_val)) {
strncpyt(config->out_root_obj, opt_val, sizeof(config->out_root_obj));
} else if (dm_is_micro_service() == true) { // for main process, there is no root obj
strncpyt(config->out_root_obj, BBFDM_DEFAULT_UBUS_OBJ, sizeof(config->out_root_obj));
}
opt_val = dmjson_get_value(daemon_obj, 2, "output", "name");
if (strlen(opt_val)) {
snprintf(config->out_name, sizeof(config->out_name), "%s%s%s",
dm_is_micro_service() ? config->out_root_obj : opt_val,
dm_is_micro_service() ? "." : "",
dm_is_micro_service() ? opt_val : "");
} else {
snprintf(config->out_name, sizeof(config->out_name), "%s", dm_is_micro_service() ? "" : BBFDM_DEFAULT_UBUS_OBJ);
}
return 0;
}
static int _parse_daemon_internal_data_model(bbfdm_config_t *config)
{
char opt_val[MAX_DM_PATH] = {0};
if (!config || !strlen(config->service_name))
return -1;
strncpyt(config->in_name, "internal_dm.so", sizeof(config->in_name));
snprintf(opt_val, MAX_DM_PATH, "%s/%s", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, config->service_name);
if (folder_exists(opt_val)) {
strncpyt(config->in_plugin_dir, opt_val, sizeof(config->in_plugin_dir));
}
strncpyt(config->out_root_obj, BBFDM_DEFAULT_UBUS_OBJ, sizeof(config->out_root_obj));
return 0;
}
static int _fill_daemon_output_options(json_object *daemon_obj, bbfdm_config_t *config)
{
char *opt_val = NULL;
if (!config || !daemon_obj) {
BBF_ERR("Invalid input options \n");
return -1;
}
opt_val = dmjson_get_value(daemon_obj, 2, "output", "root_obj");
if (DM_STRLEN(opt_val)) {
strncpyt(config->out_root_obj, opt_val, sizeof(config->out_root_obj));
} else { // for main process, there is no root obj
strncpyt(config->out_root_obj, BBFDM_DEFAULT_UBUS_OBJ, sizeof(config->out_root_obj));
}
opt_val = dmjson_get_value(daemon_obj, 2, "output", "name");
if (strlen(opt_val)) {
snprintf(config->out_name, sizeof(config->out_name), "%s.%s", BBFDM_DEFAULT_UBUS_OBJ, opt_val);
}
return 0;
}
static int bbfdm_load_deamon_config(bbfdm_config_t *config)
static int daemon_load_config_external_plugin(bbfdm_config_t *config)
{
json_object *json_obj = NULL;
char json_path[MAX_DM_PATH] = {0};
int err = 0;
if (INTERNAL_ROOT_TREE) { // internal data model
return _parse_daemon_internal_data_model(config);
}
if (!config || !strlen(config->service_name))
return -1;
if (dm_is_micro_service() == false) { // Main daemon
strncpyt(json_path, BBFDM_JSON_INPUT, MAX_DM_PATH);
} else { // Micro-services
if (strchr(config->service_name, '/')) { // absolute path
strncpyt(json_path, config->service_name, MAX_DM_PATH);
} else {
snprintf(json_path, MAX_DM_PATH, "%s/%s.json", BBFDM_DEFAULT_MICROSERVICE_INPUT_PATH, config->service_name);
}
json_obj = json_object_from_file(json_path);
if (!json_obj) {
fprintf(stderr, "Failed to read input %s file \n", json_path);
BBF_ERR("Failed to read input %s file \n", json_path);
return -1;
}
@ -1253,23 +1152,13 @@ static int bbfdm_load_deamon_config(bbfdm_config_t *config)
goto exit;
}
_parse_daemon_config_options(config, daemon_obj);
char *opt_val = dmjson_get_value(daemon_obj, 1, "service_name");
if (strlen(opt_val)) {
err = _fill_daemon_input_option(config, opt_val);
} else {
err = _parse_daemon_input_options(config, daemon_obj);
}
err = _fill_daemon_input_option(daemon_obj, config);
if (err == -1) {
goto exit;
}
_parse_daemon_output_options(config, daemon_obj);
err = _fill_daemon_output_options(daemon_obj, config);
json_object_put(json_obj);
return err;
exit:
if (json_obj) {
json_object_put(json_obj);
@ -1278,7 +1167,51 @@ exit:
return err;
}
static int bbfdm_regiter_ubus(struct ubus_context *ctx)
static int daemon_load_config_internal_plugin(bbfdm_config_t *config)
{
char opt_val[MAX_DM_PATH] = {0};
if (strlen(config->service_name) == 0 && dm_is_micro_service() == false) { // default value for main process
strncpyt(config->service_name, BBFDM_DEFAULT_UBUS_OBJ, sizeof(config->service_name));
}
if (!config || strlen(config->service_name) == 0) {
BBF_ERR("Invalid input options for service name \n");
return -1;
}
if(dm_is_micro_service() == false) {
strncpyt(config->in_plugin_dir, BBFDM_DEFAULT_PLUGINS_PATH, sizeof(config->in_plugin_dir));
snprintf(config->out_name, sizeof(config->out_name), "%s", BBFDM_DEFAULT_UBUS_OBJ);
} else {
snprintf(opt_val, MAX_DM_PATH, "%s/%s", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, config->service_name);
if (folder_exists(opt_val)) {
strncpyt(config->in_plugin_dir, opt_val, sizeof(config->in_plugin_dir));
}
strncpyt(config->out_root_obj, BBFDM_DEFAULT_UBUS_OBJ, sizeof(config->out_root_obj));
}
return 0;
}
static int daemon_load_config(bbfdm_config_t *config)
{
int err = -1;
if (INTERNAL_ROOT_TREE) {
err = daemon_load_config_internal_plugin(config);
BBF_INFO("Loading Config Internal plugin (%s)", config->service_name);
} else {
// This API will only be called with micro-services
err = daemon_load_config_external_plugin(config);
BBF_INFO("Loading Config External plugin (%s)", config->service_name);
}
return err;
}
static int regiter_ubus_object(struct ubus_context *ctx)
{
int ret;
struct bbfdm_context *u;
@ -1385,37 +1318,26 @@ static void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx)
INIT_LIST_HEAD(&bbfdm_ctx->instances);
INIT_LIST_HEAD(&bbfdm_ctx->old_instances);
INIT_LIST_HEAD(&bbfdm_ctx->event_handlers);
INIT_LIST_HEAD(&bbfdm_ctx->config.list_objs);
}
static int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
static int daemon_load_data_model(struct bbfdm_context *daemon_ctx)
{
int err = -1;
char *file_path = daemon_ctx->config.in_name;
if (DM_STRLEN(file_path) == 0) {
BBF_ERR("Input type/name not supported or defined");
return -1;
}
char *ext = strrchr(file_path, '.');
if (ext == NULL) {
BBF_ERR("Input file without extension");
} else if (strcasecmp(ext, ".json") == 0) {
BBF_INFO("Loading JSON plugin %s", file_path);
err = load_json_plugin(&loaded_json_files, &json_list, &json_memhead, file_path, &daemon_ctx->config, &DEAMON_DM_ROOT_OBJ);
} else if (strcasecmp(ext, ".so") == 0) {
BBF_INFO("Loading DotSo plugin %s", file_path);
err = load_dotso_plugin(&deamon_lib_handle, file_path, &daemon_ctx->config, &DEAMON_DM_ROOT_OBJ);
if (INTERNAL_ROOT_TREE) {
BBF_INFO("Loading Data Model Internal plugin (%s)", daemon_ctx->config.service_name);
err = bbfdm_load_internal_plugin(INTERNAL_ROOT_TREE, &daemon_ctx->config, &DEAMON_DM_ROOT_OBJ);
} else {
BBF_ERR("Input type %s not supported", ext);
BBF_INFO("Loading Data Model External plugin (%s)", daemon_ctx->config.service_name);
err = bbfdm_load_external_plugin(daemon_ctx->config.in_name, &deamon_lib_handle, &daemon_ctx->config, &DEAMON_DM_ROOT_OBJ);
}
if (!err) {
BBF_INFO("Loading sub-modules %s", daemon_ctx->config.in_plugin_dir);
bbf_global_init(DEAMON_DM_ROOT_OBJ, daemon_ctx->config.in_plugin_dir);
} else {
BBF_ERR("Failed loading %s", file_path);
}
if (err)
return err;
BBF_INFO("Loading sub-modules %s", daemon_ctx->config.in_plugin_dir);
bbf_global_init(DEAMON_DM_ROOT_OBJ, daemon_ctx->config.in_plugin_dir);
if (DM_STRLEN(daemon_ctx->config.out_name) == 0) {
BBF_ERR("output name not defined");
@ -1428,7 +1350,7 @@ static int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
return -1;
}
if (DM_STRLEN(daemon_ctx->config.out_objects[0]) == 0) {
if (list_empty(&daemon_ctx->config.list_objs)) {
BBF_ERR("output objects is not defined");
return -1;
}
@ -1437,14 +1359,9 @@ static int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
BBF_ERR("output root obj not defined");
return -1;
}
if (DM_STRLEN(daemon_ctx->config.out_name) == 0) {
BBF_ERR("output name obj not defined");
return -1;
}
}
return err;
return 0;
}
static struct ubus_event_handler add_event = { .cb = lookup_event_cb };
@ -1456,8 +1373,8 @@ int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx)
err = ubus_connect_ctx(&bbfdm_ctx->ubus_ctx, NULL);
if (err != UBUS_STATUS_OK) {
fprintf(stderr, "Failed to connect to ubus");
return err;
BBF_ERR("Failed to connect to ubus");
return -5; // Error code -5 indicating that ubus_ctx is connected
}
uloop_init();
@ -1465,19 +1382,19 @@ int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx)
bbfdm_ctx_init(bbfdm_ctx);
err = bbfdm_load_deamon_config(&bbfdm_ctx->config);
err = daemon_load_config(&bbfdm_ctx->config);
if (err) {
fprintf(stderr, "Failed to load %s deamon config\n", bbfdm_ctx->config.service_name);
BBF_ERR("Failed to load config");
return err;
}
err = daemon_load_datamodel(bbfdm_ctx);
err = daemon_load_data_model(bbfdm_ctx);
if (err) {
BBF_ERR("Failed to load datamodel");
BBF_ERR("Failed to load data_model");
return err;
}
err = bbfdm_regiter_ubus(&bbfdm_ctx->ubus_ctx);
err = regiter_ubus_object(&bbfdm_ctx->ubus_ctx);
if (err != UBUS_STATUS_OK)
return -1;

View file

@ -7,14 +7,7 @@
#include <libbbfdm-api/dmbbf.h>
#define BBFDM_DEFAULT_MICROSERVICE_INPUT_PATH "/etc/bbfdm/micro_services"
#define MAX_OBJS 7
#ifndef DAEMON_JSON_INPUT
#define BBFDM_JSON_INPUT "/tmp/bbfdm/input.json"
#else
#define BBFDM_JSON_INPUT DAEMON_JSON_INPUT
#endif
#define BBFDM_DEFAULT_UBUS_OBJ "bbfdm"
struct bbfdm_async_req {
struct ubus_context *ctx;
@ -25,21 +18,14 @@ struct bbfdm_async_req {
};
typedef struct bbfdm_config {
int proto; // Protocol identifier, Possible values: { '0'<both>, '1'<cwmp>, '2'<usp> }
int subprocess_level; // Subprocess level
uint32_t refresh_time; // Refresh time
struct list_head list_objs; // Micro-service list of objects to expose
char service_name[16]; // Service name for micro-service identification
char in_type[32]; // Input type, Possible values: { 'JSON', 'DotSo' }
char in_name[128]; // plugin path
char in_plugin_dir[128]; // extra plugin directory path
char out_name[128]; // Ubus name to use
char out_parent_dm[32]; // Parent device for micro-service
char out_objects[MAX_OBJS][32]; // Micro-service objects to expose
char out_root_obj[32]; // Ubus name to use as root data model
char cli_in_type[32]; // CLI input type, Possible values: { 'UBUS', 'JSON', 'DotSo' }
char cli_in_name[128]; // CLI input name
char cli_in_plugin_dir[128]; // CLI input plugin directory
char cli_out_type[32]; // CLI output type, Possible values: { 'CLI' }
} bbfdm_config_t;
struct bbfdm_context {

View file

@ -13,9 +13,14 @@
#include <dlfcn.h>
#include "common.h"
#include "get_helper.h"
#include "plugin/json_plugin.h"
extern struct list_head loaded_json_files;
extern struct list_head json_list;
extern struct list_head json_memhead;
static LIST_HEAD(plugin_mem);
static uint8_t find_number_of_objects(DM_MAP_OBJ *dynamic_obj)
@ -31,21 +36,18 @@ static uint8_t find_number_of_objects(DM_MAP_OBJ *dynamic_obj)
return len;
}
static void fill_dotso_micro_service_out_args(bbfdm_config_t *config, DMOBJ *entryobj, char *parent_dm, int *idx)
static void fill_dotso_micro_service_out_args(bbfdm_config_t *config, DMOBJ *entryobj, char *parent_dm)
{
char ms_name[128] = {0};
if (!config || !entryobj || !parent_dm || !idx || *idx >= MAX_OBJS)
if (!config || !entryobj || !parent_dm)
return;
strncpyt(config->out_parent_dm, parent_dm, sizeof(config->out_parent_dm));
for (; (entryobj && entryobj->obj); entryobj++) {
if (*idx >= MAX_OBJS)
break;
strncpyt(config->out_objects[(*idx)++], entryobj->obj, sizeof(config->out_objects[0]));
add_path_list(entryobj->obj, &config->list_objs);
int len = DM_STRLEN(ms_name);
if (len == 0) {
@ -59,93 +61,94 @@ static void fill_dotso_micro_service_out_args(bbfdm_config_t *config, DMOBJ *ent
strncpyt(config->out_name, ms_name, sizeof(config->out_name));
}
int load_dotso_plugin(void **lib_handle, const char *file_path, bbfdm_config_t *config, DMOBJ **main_entry)
int bbfdm_load_internal_plugin(DM_MAP_OBJ *dynamic_obj, bbfdm_config_t *config, DMOBJ **main_entry)
{
if (!lib_handle || !file_path || !strlen(file_path) || !main_entry) {
BBF_ERR("Input validation failed\n");
if (!dynamic_obj || !config || !main_entry) {
BBF_ERR("Input validation failed");
return -1;
}
uint8_t obj_num = find_number_of_objects(dynamic_obj);
if (obj_num == 0) {
BBF_ERR("No Object defined in the required DotSo Plugin\n");
return -1;
}
dm_dynamic_initmem(&plugin_mem);
DM_MAP_OBJ *dynamic_obj = NULL;
if (strcmp(file_path, "internal_dm.so") == 0) {
dynamic_obj = INTERNAL_ROOT_TREE;
} else {
void *handle = dlopen(file_path, RTLD_NOW|RTLD_LOCAL);
if (!handle) {
BBF_ERR("Plugin failed [%s]\n", dlerror());
return -1;
}
*lib_handle = handle;
//Dynamic Object
*(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj");
}
if (dynamic_obj) {
uint8_t obj_num = find_number_of_objects(dynamic_obj);
if (obj_num == 0) {
BBF_ERR("No Object defined in the required DotSo Plugin\n");
return -1;
}
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&plugin_mem, obj_num + 1, sizeof(DMOBJ));
if (dm_entryobj == NULL) {
BBF_ERR("No Memory exists\n");
return -1;
}
int out_obj_idx = 0;
for (int i = 0; dynamic_obj[i].path; i++) {
char *node_obj = dm_dynamic_strdup(&plugin_mem, dynamic_obj[i].path);
unsigned int len = strlen(node_obj);
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
BBF_ERR("Object (%s) not valid\n", node_obj);
return -1;
}
// Fill out arguments if it is running as micro-service
if (dm_is_micro_service() == true)
fill_dotso_micro_service_out_args(config, dynamic_obj[i].root_obj, node_obj, &out_obj_idx);
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 {
BBF_ERR("Main entry not available");
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&plugin_mem, obj_num + 1, sizeof(DMOBJ));
if (dm_entryobj == NULL) {
BBF_ERR("No Memory exists\n");
return -1;
}
for (int i = 0; dynamic_obj[i].path; i++) {
char *node_obj = dm_dynamic_strdup(&plugin_mem, dynamic_obj[i].path);
unsigned int len = strlen(node_obj);
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
BBF_ERR("Object (%s) not valid\n", node_obj);
return -1;
}
// Fill out arguments if it is running as micro-service
if (dm_is_micro_service() == true)
fill_dotso_micro_service_out_args(config, dynamic_obj[i].root_obj, node_obj);
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;
return 0;
}
int free_dotso_plugin(void *lib_handle)
int bbfdm_load_dotso_plugin(void **lib_handle, const char *file_path, bbfdm_config_t *config, DMOBJ **main_entry)
{
if (lib_handle)
dlclose(lib_handle);
if (!lib_handle || !file_path || !strlen(file_path) || !config || !main_entry) {
BBF_ERR("Input validation failed");
return -1;
}
DM_MAP_OBJ *dynamic_obj = NULL;
void *handle = dlopen(file_path, RTLD_NOW|RTLD_LOCAL);
if (!handle) {
BBF_ERR("Plugin failed [%s]\n", dlerror());
return -1;
}
*lib_handle = handle;
//Dynamic Object
*(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj");
return bbfdm_load_internal_plugin(dynamic_obj, config, main_entry);
}
int bbfdm_free_dotso_plugin(void **lib_handle)
{
if (*lib_handle) {
dlclose(*lib_handle);
*lib_handle = NULL;
}
dm_dynamic_cleanmem(&plugin_mem);
return 0;
}
static void fill_json_micro_service_out_args(bbfdm_config_t *config, char *parent_dm, char *obj, int idx, char *ms_name, size_t ms_name_len)
static void fill_json_micro_service_out_args(bbfdm_config_t *config, char *parent_dm, char *obj, char *ms_name, size_t ms_name_len)
{
if (!config || !obj || idx >= MAX_OBJS)
if (!config || !obj)
return;
strncpyt(config->out_parent_dm, parent_dm, sizeof(config->out_parent_dm));
strncpyt(config->out_objects[idx], obj, sizeof(config->out_objects[idx]));
add_path_list(obj, &config->list_objs);
int len = DM_STRLEN(ms_name);
if (len == 0) {
@ -155,7 +158,7 @@ static void fill_json_micro_service_out_args(bbfdm_config_t *config, char *paren
}
}
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead,
int bbfdm_load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead,
const char *file_path, bbfdm_config_t *config, DMOBJ **main_entry)
{
DMOBJ *dm_entryobj = NULL;
@ -213,7 +216,7 @@ int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list,
// Fill out arguments if it is running as micro-service
if (dm_is_micro_service() == true)
fill_json_micro_service_out_args(config, obj_prefix, obj_name, idx, ms_name, sizeof(ms_name));
fill_json_micro_service_out_args(config, obj_prefix, obj_name, ms_name, sizeof(ms_name));
// Remove '.' from object prefix
if (obj_prefix[obj_prefix_len - 1] == '.')
@ -248,7 +251,32 @@ int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list,
return 0;
}
int free_json_plugin(void)
int bbfdm_free_json_plugin(void)
{
return free_json_plugins();
}
int bbfdm_load_external_plugin(const char *file_path, void **lib_handle, bbfdm_config_t *config, DMOBJ **main_entry)
{
int err = -1;
if (DM_STRLEN(file_path) == 0) {
BBF_ERR("Input type/name not supported or defined");
return -1;
}
char *ext = strrchr(file_path, '.');
if (ext == NULL) {
BBF_ERR("Input file without extension");
} else if (strcasecmp(ext, ".json") == 0) {
BBF_INFO("Loading JSON plugin %s", file_path);
err = bbfdm_load_json_plugin(&loaded_json_files, &json_list, &json_memhead, file_path, config, main_entry);
} else if (strcasecmp(ext, ".so") == 0) {
BBF_INFO("Loading DotSo plugin %s", file_path);
err = bbfdm_load_dotso_plugin(lib_handle, file_path, config, main_entry);
} else {
BBF_ERR("Input type %s not supported", ext);
}
return err;
}

View file

@ -10,11 +10,14 @@
#ifndef PLUGIN_H
int load_dotso_plugin(void **lib_handle, const char *file_path, bbfdm_config_t *config, DMOBJ **main_entry);
int free_dotso_plugin(void *lib_handle);
int bbfdm_load_internal_plugin(DM_MAP_OBJ *Dynamic_Obj, bbfdm_config_t *config, DMOBJ **main_entry);
int bbfdm_load_external_plugin(const char *file_path, void **lib_handle, bbfdm_config_t *config, DMOBJ **main_entry);
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead,
int bbfdm_load_dotso_plugin(void **lib_handle, const char *file_path, bbfdm_config_t *config, DMOBJ **main_entry);
int bbfdm_free_dotso_plugin(void *lib_handle);
int bbfdm_load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead,
const char *file_path, bbfdm_config_t *config, DMOBJ **main_entry);
int free_json_plugin(void);
int bbfdm_free_json_plugin(void);
#endif /* PLUGIN_H */

View file

@ -2,40 +2,31 @@ cmake_minimum_required(VERSION 3.0)
PROJECT(libbbfdm)
ADD_DEFINITIONS(-Wall -Werror -D_GNU_SOURCE)
ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
OPTION(BBF_VENDOR_EXTENSION "build with vendor extension" ON)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/dmtree")
ADD_DEFINITIONS(-Wall -Werror -D_GNU_SOURCE -DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
OPTION(BBF_TR181 "build with tr181 datamodel" ON)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}")
FILE(GLOB BBF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.c)
IF(BBF_TR181)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/dmtree/tr181")
FILE(GLOB BBF_TR181_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/dmtree/tr181/*.c)
add_compile_definitions(BBF_TR181)
ENDIF(BBF_TR181)
ADD_LIBRARY(bbfdm SHARED ${BBF_TR181_SOURCES})
ADD_LIBRARY(bbfdm STATIC ${BBF_SOURCES})
TARGET_LINK_LIBRARIES(bbfdm uci ubus ubox json-c blobmsg_json m bbfdm-api ssl crypto)
INSTALL(TARGETS bbfdm
LIBRARY DESTINATION usr/share/bbfdm)
INSTALL(TARGETS bbfdm
LIBRARY DESTINATION usr/lib)
LIBRARY DESTINATION usr/lib
)
INSTALL(DIRECTORY DESTINATION etc/bbfdm)
INSTALL(DIRECTORY DESTINATION etc/bbfdm/dmmap)
INSTALL(DIRECTORY DESTINATION usr/share/bbfdm)
INSTALL(DIRECTORY DESTINATION usr/share/bbfdm/scripts)
INSTALL(DIRECTORY DESTINATION usr/share/bbfdm/plugins)
INSTALL(DIRECTORY DESTINATION usr/share/bbfdm/micro_services)
INSTALL(DIRECTORY DESTINATION usr/share/bbfdm)
INSTALL(DIRECTORY DESTINATION usr/libexec/rpcd)
string(REPLACE "," ";" VENDOR_LIST ${BBF_VENDOR_LIST})
foreach(VENDOR ${VENDOR_LIST})
add_subdirectory(dmtree/vendor/${VENDOR})
endforeach()
IF(BBF_VENDOR_EXTENSION)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/vendor.json
DESTINATION usr/share/bbfdm/plugins
)
ENDIF(BBF_VENDOR_EXTENSION)

View file

@ -48,12 +48,12 @@ static int operate_Device_FactoryReset(char *refparam, struct dmctx *ctx, void *
/* *** BBFDM *** */
DM_MAP_OBJ tDynamicObj[] = {
/* parentobj, nextobject, parameter */
{"Device.", tDeviceObj, tDeviceParams},
{"Device.", tDMRootObj, tDMRootParams},
{0}
};
/* *** Device. *** */
DMOBJ tDeviceObj[] = {
DMOBJ tDMRootObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
{"DeviceInfo", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceInfoObj, tDeviceInfoParams, NULL, BBFDM_BOTH, NULL},
{"LANConfigSecurity", &DMREAD, NULL, NULL, "file:/etc/config/users", NULL, NULL, NULL, NULL, tLANConfigSecurityParams, NULL, BBFDM_BOTH, NULL},
@ -63,7 +63,7 @@ DMOBJ tDeviceObj[] = {
{0}
};
DMLEAF tDeviceParams[] = {
DMLEAF tDMRootParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"RootDataModelVersion", &DMREAD, DMT_STRING, get_Device_RootDataModelVersion, NULL, BBFDM_BOTH},
{"Reboot()", &DMSYNC, DMT_COMMAND, NULL, operate_Device_Reboot, BBFDM_USP},

View file

@ -17,7 +17,7 @@
extern DM_MAP_OBJ tDynamicObj[];
extern DMOBJ tDeviceObj[];
extern DMLEAF tDeviceParams[];
extern DMOBJ tDMRootObj[];
extern DMLEAF tDMRootParams[];
#endif

View file

@ -1,13 +0,0 @@
cmake_minimum_required(VERSION 3.0)
PROJECT(libbbfdm_iopsys_ext)
ADD_DEFINITIONS(-Wall -Werror -D_GNU_SOURCE)
ADD_DEFINITIONS(-DBBF_VENDOR_PREFIX="${BBF_VENDOR_PREFIX}")
FILE(GLOB BBF_IOPSYS_VENDOR_EXTENSION_SOURCES ../../../dmlayer.c *.c)
ADD_LIBRARY(bbfdm_iopsys_ext SHARED ${BBF_IOPSYS_VENDOR_EXTENSION_SOURCES})
INSTALL(TARGETS bbfdm_iopsys_ext
LIBRARY DESTINATION usr/share/bbfdm/plugins)

View file

@ -1,27 +0,0 @@
/*
* Copyright (C) 2021 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#include "deviceinfo.h"
static int get_base_mac_addr(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
db_get_value_string("device", "deviceinfo", "BaseMACAddress", value);
return 0;
}
/**********************************************************************************************************************************
* OBJ & PARAM DEFINITION
***********************************************************************************************************************************/
DMLEAF tIOPSYS_DeviceInfoParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{BBF_VENDOR_PREFIX"BaseMACAddress", &DMREAD, DMT_STRING, get_base_mac_addr, NULL, BBFDM_BOTH},
{0}
};

View file

@ -1,19 +0,0 @@
/*
* Copyright (C) 2021 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __IOPSYS_DEVICEINFO_H
#define __IOPSYS_DEVICEINFO_H
#include "libbbfdm-api/dmcommon.h"
extern DMLEAF tIOPSYS_DeviceInfoParams[];
#endif //__IOPSYS_DEVICEINFO_H

View file

@ -1,19 +0,0 @@
/*
* Copyright (C) 2021 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#include "deviceinfo.h"
#include "extension.h"
DM_MAP_OBJ tDynamicObj[] = {
/* parentobj, nextobject, parameter */
{"Device.DeviceInfo.", NULL, tIOPSYS_DeviceInfoParams},
{0}
};

View file

@ -1,19 +0,0 @@
/*
* Copyright (C) 2021 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
*
*/
#ifndef __IOPSYS_VENDOR_H
#define __IOPSYS_VENDOR_H
#include "libbbfdm-api/dmcommon.h"
extern DM_MAP_OBJ tVendorExtensionIOPSYS[];
#endif //__IOPSYS_VENDOR_H

View file

@ -1,43 +0,0 @@
{
"Device.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"description": "The top-level object for a Device.",
"access": false,
"array": false,
"Device.DeviceInfo.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"description": "This object contains general device information.",
"access": false,
"array": false,
"{BBF_VENDOR_PREFIX}BaseMACAddress": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"description": "The MAC Address of the device.",
"datatype": "MACAddress",
"range": [
{
"max": 17
}
],
"pattern": [
"",
"([0-9A-Fa-f][0-9A-Fa-f]:){5}([0-9A-Fa-f][0-9A-Fa-f])"
]
}
}
}
}

47
libbbfdm/vendor/vendor.json vendored Normal file
View file

@ -0,0 +1,47 @@
{
"json_plugin_version": 2,
"Device.DeviceInfo.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"description": "This object contains general device information.",
"access": false,
"array": false,
"{BBF_VENDOR_PREFIX}BaseMACAddress": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"description": "The MAC Address of the device.",
"datatype": "MACAddress",
"range": [
{
"max": 17
}
],
"pattern": [
"",
"([0-9A-Fa-f][0-9A-Fa-f]:){5}([0-9A-Fa-f][0-9A-Fa-f])"
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "/etc/board-db/config/device",
"section": {
"name": "deviceinfo"
},
"option": {
"name":"BaseMACAddress"
}
}
}
]
}
}
}

View file

@ -1,6 +1,6 @@
CC = gcc
CFLAGS = -g -Wall -Werror
LDFLAGS = -lcmocka -lbbfdm-api -lbbfdm -lubox -lblobmsg_json
LDFLAGS = -lcmocka -lbbfdm-api -lbbfdm -lubox -lblobmsg_json -ljson-c -lssl -lcrypto --coverage
UNIT_TESTS = unit_test_bbfd
FUNCTIONAL_TESTS = functional_test_bbfd
FUNCTIONAL_API_TESTS = functional_api_test_bbfd

View file

@ -7,11 +7,11 @@
#include <libbbfdm-api/dmapi.h>
#include <libbbfdm-api/dmentry.h>
#include "../../libbbfdm/dmtree/tr181/device.h"
#include "../../libbbfdm/device.h"
static DMOBJ TR181_ROOT_TREE[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceObj, tDeviceParams, NULL, BBFDM_BOTH},
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDMRootObj, tDMRootParams, NULL, BBFDM_BOTH},
{0}
};
@ -1304,7 +1304,9 @@ static void test_api_bbfdm_valid_standard_list_operate(void **state)
if (DM_STRCMP(name, "Device.FactoryReset()") == 0) {
assert_string_equal(type, "xsd:command");
assert_string_equal(data, "sync");
assert_null(data);
assert_non_null(data);
assert_null(command_in);
assert_null(command_out);
}
if (DM_STRCMP(name, "Device.DeviceInfo.VendorLogFile.{i}.Upload()") == 0) {

View file

@ -7,11 +7,11 @@
#include <libbbfdm-api/dmapi.h>
#include <libbbfdm-api/dmentry.h>
#include "../../libbbfdm/dmtree/tr181/device.h"
#include "../../libbbfdm/device.h"
static DMOBJ TR181_ROOT_TREE[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDeviceObj, tDeviceParams, NULL, BBFDM_BOTH},
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDMRootObj, tDMRootParams, NULL, BBFDM_BOTH},
{0}
};

View file

@ -1,19 +1,4 @@
{
"daemon": {
"config": {
"loglevel": "3",
"subprocess_level": "2"
},
"input": {
"type": "DotSo",
"name": "/usr/share/bbfdm/libbbfdm.so",
"plugin_dir": "/usr/share/bbfdm/plugins"
},
"output": {
"type": "UBUS",
"name": "bbfdm"
}
},
"cli": {
"config": {
"proto": "both"

117
test/tools/dm-cli.c Normal file
View file

@ -0,0 +1,117 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <libubox/blobmsg.h>
#include "../../libbbfdm-api/dmapi.h"
#include "../../libbbfdm-ubus/bbfdm-ubus.h"
#include "../../libbbfdm-api/dmentry.h"
#include "../../libbbfdm-ubus/plugin.h"
#include "../../libbbfdm/device.h"
static int cli_exec_schema(struct dmctx *bbfdm_ctx, char *in_path)
{
int err = 0;
bbfdm_ctx->in_param = in_path;
bbfdm_ctx->nextlevel = false;
bbfdm_ctx->iscommand = true;
bbfdm_ctx->isevent = true;
bbfdm_ctx->isinfo = true;
err = bbf_entry_method(bbfdm_ctx, BBF_SCHEMA);
if (!err) {
struct blob_attr *cur = NULL;
size_t rem = 0;
blobmsg_for_each_attr(cur, bbfdm_ctx->bb.head, rem) {
struct blob_attr *tb[3] = {0};
const struct blobmsg_policy p[3] = {
{ "path", BLOBMSG_TYPE_STRING },
{ "data", BLOBMSG_TYPE_STRING },
{ "type", BLOBMSG_TYPE_STRING }
};
blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur));
char *name = (tb[0]) ? blobmsg_get_string(tb[0]) : "";
char *data = (tb[1]) ? blobmsg_get_string(tb[1]) : "";
char *type = (tb[2]) ? blobmsg_get_string(tb[2]) : "";
printf("%s %s %s\n", name, type, data);
}
} else {
printf("ERROR: %d retrieving %s\n", err, bbfdm_ctx->in_param);
err = -1;
}
return err;
}
int main(int argc, char **argv)
{
DMOBJ *CLI_DM_ROOT_OBJ = NULL;
void *cli_lib_handle = NULL;
struct dmctx bbfdm_ctx = {0};
bbfdm_config_t bbfdm_config = {0};
char *plugin_path = NULL, *plugin_dir = NULL, *dm_path = NULL;
unsigned int proto = BBFDM_BOTH;
int err = 0, ch;
memset(&bbfdm_ctx, 0, sizeof(struct dmctx));
while ((ch = getopt(argc, argv, "hc:u:l:p:")) != -1) {
switch (ch) {
case 'c':
bbfdm_ctx.dm_type = BBFDM_CWMP;
dm_path = argv[optind - 1];
break;
case 'u':
bbfdm_ctx.dm_type = BBFDM_USP;
dm_path = argv[optind - 1];
break;
case 'l':
plugin_path = optarg;
break;
case 'p':
plugin_dir = optarg;
break;
default:
break;
}
}
if (plugin_path == NULL) {
err = bbfdm_load_internal_plugin(tDynamicObj, &bbfdm_config, &CLI_DM_ROOT_OBJ);
} else {
err = bbfdm_load_dotso_plugin(&cli_lib_handle, plugin_path, &bbfdm_config, &CLI_DM_ROOT_OBJ);
}
if (err || !CLI_DM_ROOT_OBJ) {
printf("ERROR: Failed to load plugin\n");
return -1;
}
if (!dm_path) {
printf("ERROR: Data Model path should be defined\n");
return -1;
}
// Initialize global context
bbf_global_init(CLI_DM_ROOT_OBJ, plugin_dir);
// Initialize the bbfdm context
bbf_ctx_init(&bbfdm_ctx, CLI_DM_ROOT_OBJ);
err = cli_exec_schema(&bbfdm_ctx, dm_path);
// Clean up the context and global resources
bbf_ctx_clean(&bbfdm_ctx);
bbf_global_clean(CLI_DM_ROOT_OBJ);
// Free plugin handle
bbfdm_free_dotso_plugin(&cli_lib_handle);
return err;
}

View file

@ -93,7 +93,7 @@ This tool helps in validating the json schema, which is very helpful in the deve
```bash
$ ./tools/validate_json_plugin.py test/files/etc/bbfdm/json/X_IOPSYS_EU_TEST.json
$ ./tools/validate_json_plugin.py dmtree/json/datamodel.json
$ ./tools/validate_json_plugin.py tools/datamodel.json
```
More examples available in [this path](../test/files/usr/share/bbfdm/plugins).
@ -135,7 +135,6 @@ The parameters/keys used in tools_input.json file are mostly self-explanatory bu
| product_class" | The product class, e.g., "DG400PRIME" |
| model_name | The model name, e.g., "DG400PRIME-A" |
| software_version | The software version, e.g., "1.2.3.4" |
| vendor_list | This option should have the same name of the vendor directory names, e.g., ["iopsys"] |
| dm_json_files | This should contain the list of json file path, where each file contains the definition of DM objects/parameters |
| vendor_prefix | The prefix used by vendor for vendor extension in DM objects/parameters, e.g., "X_IOPSYS_EU_" |
| plugins | A list of plugins with associated repositories and data model files |
@ -153,7 +152,7 @@ The parameters/keys used in tools_input.json file are mostly self-explanatory bu
> Note:
> To add more description about the vendor extended DM objects/parameters, it is required to add the definition of the required/related DM objects/parameters in a json file (The json structure should follow same format as given in [datamodel.json](../libbbfdm/dmtree/json/datamodel.json)), The same json file need to be defined in dm_json_files list.
> To add more description about the vendor extended DM objects/parameters, it is required to add the definition of the required/related DM objects/parameters in a json file (The json structure should follow same format as given in [datamodel.json](datamodel.json)), The same json file need to be defined in dm_json_files list.
The input json file should be defined as follow:
@ -166,12 +165,8 @@ The input json file should be defined as follow:
"product_class": "DG400PRIME",
"model_name": "DG400PRIME-A",
"software_version": "1.2.3.4",
"vendor_list": [
"iopsys",
"test"
],
"dm_json_files": [
"../libbbfdm/dmtree/json/datamodel.json"
"tools/datamodel.json"
]
"vendor_prefix": "X_IOPSYS_EU_",
"plugins": [

View file

@ -7,7 +7,6 @@ import sys
import os
import subprocess
import shutil
import json
import glob
# Constants
@ -16,7 +15,7 @@ CURRENT_PATH = os.getcwd()
BBF_PLUGIN_DIR = "/usr/share/bbfdm/plugins/"
BBF_MS_DIR = "/usr/share/bbfdm/micro_services/"
DM_JSON_FILE = os.path.join(CURRENT_PATH, "libbbfdm", "dmtree", "json", "datamodel.json")
DM_JSON_FILE = os.path.join(CURRENT_PATH, "tools", "datamodel.json")
LIST_SUPPORTED_USP_DM = []
LIST_SUPPORTED_CWMP_DM = []
@ -97,15 +96,6 @@ def obj_has_param(value):
return False
def get_vendor_list(val):
vendor_list = ""
if isinstance(val, list):
for vendor in val:
vendor_list = vendor if not vendor_list else (
vendor_list + "," + vendor)
return vendor_list
def get_option_value(value, option, default=None):
if isinstance(value, dict):
for obj, val in value.items():
@ -184,7 +174,7 @@ def generate_shared_library(dm_name, source_files, vendor_prefix, extra_dependen
return False
def build_and_install_bbfdm(vendor_prefix, vendor_list):
def build_and_install_bbfdm(vendor_prefix):
print("Compiling and installing bbfdmd in progress ...")
create_folder(os.path.join(CURRENT_PATH, "build"))
@ -196,18 +186,11 @@ def build_and_install_bbfdm(vendor_prefix, vendor_list):
else:
VENDOR_PREFIX = "X_IOPSYS_EU_"
# Set vendor list
if vendor_list is None:
VENDOR_LIST = "iopsys"
else:
VENDOR_LIST = get_vendor_list(vendor_list)
# Build and install bbfdm
cmake_command = [
"cmake",
"../",
"-DBBF_SCHEMA_FULL_TREE=ON",
f"-DBBF_VENDOR_LIST={VENDOR_LIST}",
f"-DBBF_VENDOR_PREFIX={VENDOR_PREFIX}",
"-DBBF_MAX_OBJECT_INSTANCES=255",
"-DBBFDMD_MAX_MSG_LEN=1048576",
@ -229,41 +212,52 @@ def build_and_install_bbfdm(vendor_prefix, vendor_list):
print('Compiling and installing bbfdmd done')
def create_bbfdm_input_json_file(proto, dm_name=None):
data = {
"daemon": {
},
"cli": {
"config": {
"proto": proto
},
"input": {
"type": "DotSo",
"name": "/usr/share/bbfdm/libbbfdm.so",
"plugin_dir": "/usr/share/bbfdm/plugins"
},
"output": {
"type": "CLI"
}
}
}
def build_and_install_dmcli():
print("Compiling and installing dm-cli in progress ...")
create_folder(os.path.join(CURRENT_PATH, "build"))
cd_dir(os.path.join(CURRENT_PATH, "build"))
# GCC command to compile dm-cli
gcc_command = [
"gcc",
"../test/tools/dm-cli.c",
"-lbbfdm-api",
"-lbbfdm-ubus",
"-lubox",
"-lblobmsg_json",
"-lbbfdm",
"-ljson-c",
"-lssl",
"-lcrypto",
"-o", "dm-cli"
]
try:
subprocess.check_call(gcc_command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
subprocess.check_call(["mv", "dm-cli", "/usr/sbin/dm-cli"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
print(f"Error running commands: {e}")
sys.exit(1)
cd_dir(CURRENT_PATH)
remove_folder(os.path.join(CURRENT_PATH, "build"))
print('Compiling and installing dm-cli done')
def fill_list_dm(proto, dm_list, dm_name=None):
# Determine the base command depending on the presence of dm_name
if dm_name:
del data["cli"]["input"]["plugin_dir"]
data["cli"]["input"]["name"] = dm_name
command = f"dm-cli -l {dm_name}"
else:
command = "dm-cli -p /usr/share/bbfdm/plugins"
file_path = '/tmp/bbfdm/input.json'
# Add the appropriate flag (-c or -u) based on the proto value
if proto == "cwmp":
command += " -c Device."
elif proto == "usp":
command += " -u Device."
# Ensure the directory exists
os.makedirs(os.path.dirname(file_path), exist_ok=True)
# Open the file in 'w' mode (create or truncate)
with open(file_path, 'w', encoding='utf-8') as json_file:
json.dump(data, json_file, indent=4)
def fill_list_dm(dm_list):
command = "bbfdmd -c schema Device."
try:
# Run the command
result = subprocess.run(command, shell=True, text=True, capture_output=True, check=True)
@ -308,8 +302,7 @@ def remove_duplicate_elements(input_list):
def fill_list_supported_dm():
for proto, DB in [("usp", LIST_SUPPORTED_USP_DM), ("cwmp", LIST_SUPPORTED_CWMP_DM)]:
create_bbfdm_input_json_file(proto)
fill_list_dm(DB)
fill_list_dm(proto, DB)
DB.sort(key=lambda x: x['param'], reverse=False)
DB[:] = remove_duplicate_elements(DB)
@ -318,8 +311,7 @@ def fill_list_supported_dm():
if os.path.isfile(f):
for proto, DB in [("usp", LIST_SUPPORTED_USP_DM), ("cwmp", LIST_SUPPORTED_CWMP_DM)]:
create_bbfdm_input_json_file(proto, f)
fill_list_dm(DB)
fill_list_dm(proto, DB, f)
DB.sort(key=lambda x: x['param'], reverse=False)
DB[:] = remove_duplicate_elements(DB)
@ -428,18 +420,20 @@ def download_and_build_plugins(plugins, vendor_prefix):
print('Generating plugins completed.')
def generate_supported_dm(vendor_prefix=None, vendor_list=None, plugins=None):
def generate_supported_dm(vendor_prefix=None, plugins=None):
'''
Generates supported data models and performs necessary actions.
Args:
vendor_prefix (str, optional): Vendor prefix for shared libraries.
vendor_list (list, optional): List of vendor data models.
plugins (list, optional): List of plugin configurations.
'''
# Build && Install bbfdm
build_and_install_bbfdm(vendor_prefix, vendor_list)
build_and_install_bbfdm(vendor_prefix)
# Build && Install dm-cli
build_and_install_dmcli()
# Download && Build Plugins Data Models
download_and_build_plugins(plugins, vendor_prefix)

View file

@ -25,7 +25,6 @@ if len(sys.argv) < 2:
print_dm_usage()
VENDOR_PREFIX = None
VENDOR_LIST = None
PLUGINS = None
OUTPUT = None
DM_JSON_FILES = None
@ -67,10 +66,6 @@ for option, value in json_data.items():
VENDOR_PREFIX = value
continue
elif option == "vendor_list":
VENDOR_LIST = value
continue
elif option == "dm_json_files":
DM_JSON_FILES = value
continue
@ -90,7 +85,7 @@ for option, value in json_data.items():
if OUTPUT is None:
bbf.download_and_build_plugins(PLUGINS, VENDOR_PREFIX)
else:
bbf.generate_supported_dm(VENDOR_PREFIX, VENDOR_LIST, PLUGINS)
bbf.generate_supported_dm(VENDOR_PREFIX, PLUGINS)
file_format = bbf.get_option_value(OUTPUT, "file_format", ['xml'])
output_file_prefix = bbf.get_option_value(OUTPUT, "output_file_prefix", "datamodel")

View file

@ -196,13 +196,6 @@ if __name__ == '__main__':
help= 'Includes OBJ/PARAM defined under remote repositories defined as bbf plugin'
)
parser.add_argument(
'-v', '--vendor-list',
metavar='iopsys',
action = 'append',
help='Generate data model tree with vendor extension OBJ/PARAM'
)
parser.add_argument(
'-p', '--vendor-prefix',
default = 'X_IOPSYS_EU_',
@ -232,7 +225,7 @@ if __name__ == '__main__':
plugins.append(r)
bbf.generate_supported_dm(args.vendor_prefix, args.vendor_list, plugins)
bbf.generate_supported_dm(args.vendor_prefix, plugins)
generate_excel(args.output)
print(f'Datamodel generation completed, aritifacts available in {args.output}')
sys.exit(bbf.BBF_ERROR_CODE)

View file

@ -390,13 +390,6 @@ if __name__ == '__main__':
help= 'Includes OBJ/PARAM defined under remote repositories defined as bbf plugin'
)
parser.add_argument(
'-v', '--vendor-list',
metavar='iopsys',
action = 'append',
help='Generate data model tree with vendor extension OBJ/PARAM.'
)
parser.add_argument(
'-p', '--vendor-prefix',
default = 'X_IOPSYS_EU_',
@ -483,7 +476,7 @@ if __name__ == '__main__':
plugins.append(r)
bbf.generate_supported_dm(args.vendor_prefix, args.vendor_list, plugins)
bbf.generate_supported_dm(args.vendor_prefix, plugins)
generate_xml(args.format, args.dm_json_files, args.output)
print(f'Datamodel generation completed, aritifacts available in {args.output}')
sys.exit(bbf.BBF_ERROR_CODE)

View file

@ -5,12 +5,9 @@
"product_class": "DG400PRIME",
"model_name": "DG400PRIME-A",
"software_version": "1.2.3.4",
"vendor_list": [
"iopsys"
],
"dm_json_files": [
"libbbfdm/dmtree/json/datamodel.json",
"libbbfdm/dmtree/vendor/iopsys/vendor.json"
"tools/datamodel.json",
"libbbfdm/vendor/vendor.json"
],
"vendor_prefix": "X_IOPSYS_EU_",
"plugins": [