mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Split 'bbfdmd' into two binaries: 'bbfdmd' (main tree) and 'dm-service' (micro-service tree)
This commit is contained in:
parent
ebdb414e09
commit
9a6dfdfe3e
49 changed files with 629 additions and 1159 deletions
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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, " -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;
|
||||
return bbfdm_cli_exec_command(cli_argc, cli_argv);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
bbfdm_ubus_set_log_level(log_level);
|
||||
bbfdm_ubus_load_data_model(tDynamicObj);
|
||||
|
||||
return bbfdm_cli_exec_command(&bbfdm_ctx.config, cli_argc, cli_argv);
|
||||
}
|
||||
|
||||
openlog("bbfdm", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
||||
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:
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
12
dm-service/CMakeLists.txt
Normal 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
85
dm-service/dm_service.c
Normal 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;
|
||||
}
|
||||
|
|
@ -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."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
} else {
|
||||
BBF_ERR("Failed loading %s", file_path);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,46 +61,27 @@ 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
dm_dynamic_initmem(&plugin_mem);
|
||||
|
||||
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);
|
||||
|
|
@ -110,7 +93,7 @@ int load_dotso_plugin(void **lib_handle, const char *file_path, bbfdm_config_t *
|
|||
|
||||
// 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);
|
||||
fill_dotso_micro_service_out_args(config, dynamic_obj[i].root_obj, node_obj);
|
||||
|
||||
node_obj[len-1] = 0;
|
||||
|
||||
|
|
@ -122,30 +105,50 @@ int load_dotso_plugin(void **lib_handle, const char *file_path, bbfdm_config_t *
|
|||
}
|
||||
|
||||
*main_entry = dm_entryobj;
|
||||
} else {
|
||||
BBF_ERR("Main entry not available");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
extern DM_MAP_OBJ tDynamicObj[];
|
||||
|
||||
extern DMOBJ tDeviceObj[];
|
||||
extern DMLEAF tDeviceParams[];
|
||||
extern DMOBJ tDMRootObj[];
|
||||
extern DMLEAF tDMRootParams[];
|
||||
|
||||
#endif
|
||||
13
libbbfdm/dmtree/vendor/iopsys/CMakeLists.txt
vendored
13
libbbfdm/dmtree/vendor/iopsys/CMakeLists.txt
vendored
|
|
@ -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)
|
||||
27
libbbfdm/dmtree/vendor/iopsys/deviceinfo.c
vendored
27
libbbfdm/dmtree/vendor/iopsys/deviceinfo.c
vendored
|
|
@ -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}
|
||||
};
|
||||
19
libbbfdm/dmtree/vendor/iopsys/deviceinfo.h
vendored
19
libbbfdm/dmtree/vendor/iopsys/deviceinfo.h
vendored
|
|
@ -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
|
||||
19
libbbfdm/dmtree/vendor/iopsys/extension.c
vendored
19
libbbfdm/dmtree/vendor/iopsys/extension.c
vendored
|
|
@ -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}
|
||||
};
|
||||
19
libbbfdm/dmtree/vendor/iopsys/extension.h
vendored
19
libbbfdm/dmtree/vendor/iopsys/extension.h
vendored
|
|
@ -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
|
||||
43
libbbfdm/dmtree/vendor/iopsys/vendor.json
vendored
43
libbbfdm/dmtree/vendor/iopsys/vendor.json
vendored
|
|
@ -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
47
libbbfdm/vendor/vendor.json
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
117
test/tools/dm-cli.c
Normal 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;
|
||||
}
|
||||
|
|
@ -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": [
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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": [
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue