Multiple improvements

- New input daemon option, 'service_name' to easily configure micro-service
- service_name used with 'dm_' prefix in process name
- service_name with 'dm_' prefix and '_inst' suffix for forked instance updater
- Unified signal handler for micro-service and main process
- Cli argument '-m' overloaded to support module name in place of plugin path
- Test alignments and improvements
This commit is contained in:
Vivek Kumar Dutta 2024-04-15 13:46:49 +00:00
parent faa59d7ea7
commit 63fad00eee
39 changed files with 365 additions and 247 deletions

1
.gitignore vendored
View file

@ -10,3 +10,4 @@ docs/index.md
__pycache__ __pycache__
out out
/datamodel /datamodel
/build

View file

@ -36,6 +36,13 @@
#define BBFDM_JSON_INPUT DAEMON_JSON_INPUT #define BBFDM_JSON_INPUT DAEMON_JSON_INPUT
#endif #endif
#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_MICROSERVICE_INPUT_PATH "/etc/bbfdm/micro_services"
#define BBFDM_DEFAULT_UBUS_OBJ "bbfdm"
#define BBFDM_DEFAULT_DEBUG_LEVEL LOG_ERR
extern struct list_head loaded_json_files; extern struct list_head loaded_json_files;
extern struct list_head json_list; extern struct list_head json_list;
extern struct list_head json_memhead; extern struct list_head json_memhead;
@ -58,18 +65,10 @@ static void sig_handler(int sig)
{ {
if (sig == SIGSEGV) { if (sig == SIGSEGV) {
handle_pending_signal(sig); handle_pending_signal(sig);
} else if (sig == SIGUSR1) {
ERR("# SIGUSR1 handler for main process PID[%ld]", getpid());
} }
} }
static void signal_init(void) static void signal_init(void)
{
signal(SIGSEGV, sig_handler);
signal(SIGUSR1, sig_handler);
}
static void service_signal_init(void)
{ {
signal(SIGSEGV, sig_handler); signal(SIGSEGV, sig_handler);
} }
@ -949,8 +948,7 @@ enum {
BBF_SERVICE_CMD, BBF_SERVICE_CMD,
BBF_SERVICE_NAME, BBF_SERVICE_NAME,
BBF_SERVICE_PARENT_DM, BBF_SERVICE_PARENT_DM,
BBF_SERVICE_OBJECT, BBF_SERVICE_OBJECTS,
BBF_SERVICE_MULTI_OBJECTS,
__BBF_SERVICE_MAX, __BBF_SERVICE_MAX,
}; };
@ -958,8 +956,7 @@ static const struct blobmsg_policy service_policy[] = {
[BBF_SERVICE_CMD] = { .name = "cmd", .type = BLOBMSG_TYPE_STRING }, [BBF_SERVICE_CMD] = { .name = "cmd", .type = BLOBMSG_TYPE_STRING },
[BBF_SERVICE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, [BBF_SERVICE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
[BBF_SERVICE_PARENT_DM] = { .name = "parent_dm", .type = BLOBMSG_TYPE_STRING }, [BBF_SERVICE_PARENT_DM] = { .name = "parent_dm", .type = BLOBMSG_TYPE_STRING },
[BBF_SERVICE_OBJECT] = { .name = "object", .type = BLOBMSG_TYPE_STRING }, [BBF_SERVICE_OBJECTS] = { .name = "objects", .type = BLOBMSG_TYPE_ARRAY },
[BBF_SERVICE_MULTI_OBJECTS] = { .name = "multiple_objects", .type = BLOBMSG_TYPE_ARRAY },
}; };
static void service_list(struct blob_buf *bb) static void service_list(struct blob_buf *bb)
@ -1024,28 +1021,24 @@ static int bbfdm_service_handler(struct ubus_context *ctx, struct ubus_object *o
goto end; goto end;
} }
if (!tb[BBF_SERVICE_OBJECT] && !tb[BBF_SERVICE_MULTI_OBJECTS]) { if (!tb[BBF_SERVICE_OBJECTS]) {
blobmsg_add_string(&bb, "error", "service object/multiple_objects should be defined!!"); blobmsg_add_string(&bb, "error", "service objects should be defined!!");
goto end; goto end;
} }
char *srv_name = blobmsg_get_string(tb[BBF_SERVICE_NAME]); char *srv_name = blobmsg_get_string(tb[BBF_SERVICE_NAME]);
char *srv_parent_dm = blobmsg_get_string(tb[BBF_SERVICE_PARENT_DM]); char *srv_parent_dm = blobmsg_get_string(tb[BBF_SERVICE_PARENT_DM]);
char *srv_obj = NULL;
bool res = true; bool res = true;
if (tb[BBF_SERVICE_MULTI_OBJECTS]) { if (tb[BBF_SERVICE_OBJECTS]) {
struct blob_attr *objs = tb[BBF_SERVICE_MULTI_OBJECTS]; struct blob_attr *objs = tb[BBF_SERVICE_OBJECTS];
struct blob_attr *obj = NULL; struct blob_attr *obj = NULL;
size_t rem; size_t rem;
blobmsg_for_each_attr(obj, objs, rem) { blobmsg_for_each_attr(obj, objs, rem) {
srv_obj = blobmsg_get_string(obj); char *srv_obj = blobmsg_get_string(obj);
res |= load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj); res |= load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj);
} }
} else if (tb[BBF_SERVICE_OBJECT]) {
srv_obj = blobmsg_get_string(tb[BBF_SERVICE_OBJECT]);
res = load_service(DEAMON_DM_ROOT_OBJ, &head_registered_service, srv_name, srv_parent_dm, srv_obj);
} else { } else {
res = false; res = false;
} }
@ -1275,8 +1268,11 @@ static int fork_instance_checker(struct bbfdm_context *u)
} }
child = fork(); child = fork();
if (child == 0) { if (child == 0) {
INFO("{fork} Instances checker entry"); char inst_ser[32] = {0};
prctl(PR_SET_NAME, (unsigned long) "bbfdm_instance");
snprintf(inst_ser, sizeof(inst_ser), "dm_%s_in", u->config.service_name);
INFO("{%s::fork} Instances checker entry", inst_ser);
prctl(PR_SET_NAME, inst_ser, NULL, NULL, NULL);
// child initialise signal to prevent segfaults // child initialise signal to prevent segfaults
signal_init(); signal_init();
/* free fd's and memory inherited from parent */ /* free fd's and memory inherited from parent */
@ -1382,14 +1378,10 @@ static bool register_service(struct ubus_context *ctx)
blobmsg_add_string(&bb, "name", u->config.out_name); blobmsg_add_string(&bb, "name", u->config.out_name);
blobmsg_add_string(&bb, "parent_dm", u->config.out_parent_dm); blobmsg_add_string(&bb, "parent_dm", u->config.out_parent_dm);
if (DM_STRLEN(u->config.out_multi_objects[0]) != 0) { void *arr = blobmsg_open_array(&bb, "objects");
void *arr = blobmsg_open_array(&bb, "multiple_objects"); for (int i = 0; i < MAX_OBJS && DM_STRLEN(u->config.out_objects[i]) != 0; i++)
for (int i = 0; i < MAX_MULTI_OBJS && DM_STRLEN(u->config.out_multi_objects[i]) != 0; i++) blobmsg_add_string(&bb, NULL, u->config.out_objects[i]);
blobmsg_add_string(&bb, NULL, u->config.out_multi_objects[i]); blobmsg_close_array(&bb, arr);
blobmsg_close_array(&bb, arr);
} else {
blobmsg_add_string(&bb, "object", u->config.out_object);
}
ubus_invoke(ctx, ubus_id, "service", bb.head, NULL, NULL, 5000); ubus_invoke(ctx, ubus_id, "service", bb.head, NULL, NULL, 5000);
blob_buf_free(&bb); blob_buf_free(&bb);
@ -1397,118 +1389,161 @@ static bool register_service(struct ubus_context *ctx)
return true; return true;
} }
static int bbfdm_load_deamon_config(bbfdm_config_t *config, const char *json_path) bool file_exists(const char *path)
{
struct stat buffer;
return stat(path, &buffer) == 0;
}
bool dir_exists(const char *path)
{
struct stat buffer;
return (stat(path, &buffer) == 0 && S_ISDIR(buffer.st_mode));
}
static int _parse_daemon_config_options(bbfdm_config_t *config, json_object *daemon_obj)
{ {
char *opt_val = NULL; char *opt_val = NULL;
int err = 0;
json_object *json_obj = NULL;
if (!json_path || !strlen(json_path)) if (!config || !daemon_obj) {
fprintf(stderr, "Invalid input options \n");
return -1; return -1;
json_obj = json_object_from_file(json_path);
if (!json_obj) {
ERR("Failed to read input %s file", json_path);
goto exit;
} }
json_object *deamon_obj = dmjson_get_obj(json_obj, 1, "daemon"); opt_val = dmjson_get_value(daemon_obj, 2, "config", "loglevel");
if (!deamon_obj) {
err = -1;
goto exit;
}
opt_val = dmjson_get_value(deamon_obj, 2, "config", "loglevel");
if (DM_STRLEN(opt_val)) { if (DM_STRLEN(opt_val)) {
config->log_level = (uint8_t) strtoul(opt_val, NULL, 10); config->log_level = (uint8_t) strtoul(opt_val, NULL, 10);
set_debug_level(config->log_level); set_debug_level(config->log_level);
} else {
set_debug_level(BBFDM_DEFAULT_DEBUG_LEVEL);
} }
opt_val = dmjson_get_value(deamon_obj, 2, "config", "refresh_time"); opt_val = dmjson_get_value(daemon_obj, 2, "config", "refresh_time");
if (DM_STRLEN(opt_val)) { if (DM_STRLEN(opt_val)) {
config->refresh_time = (unsigned int) strtoul(opt_val, NULL, 10) * 1000; config->refresh_time = (unsigned int) strtoul(opt_val, NULL, 10) * 1000;
} else { } else {
config->refresh_time = BBF_INSTANCES_UPDATE_TIMEOUT; config->refresh_time = BBF_INSTANCES_UPDATE_TIMEOUT;
} }
opt_val = dmjson_get_value(deamon_obj, 2, "config", "transaction_timeout"); opt_val = dmjson_get_value(daemon_obj, 2, "config", "transaction_timeout");
if (DM_STRLEN(opt_val)) { if (DM_STRLEN(opt_val)) {
config->transaction_timeout = (int) strtol(opt_val, NULL, 10); config->transaction_timeout = (int) strtol(opt_val, NULL, 10);
configure_transaction_timeout(config->transaction_timeout); configure_transaction_timeout(config->transaction_timeout);
} else {
config->transaction_timeout = 30;
configure_transaction_timeout(30*1000);
} }
opt_val = dmjson_get_value(deamon_obj, 2, "config", "subprocess_level"); opt_val = dmjson_get_value(daemon_obj, 2, "config", "subprocess_level");
if (DM_STRLEN(opt_val)) { if (DM_STRLEN(opt_val)) {
config->subprocess_level = (unsigned int) strtoul(opt_val, NULL, 10); config->subprocess_level = (unsigned int) strtoul(opt_val, NULL, 10);
} else { } else {
config->subprocess_level = BBF_SUBPROCESS_DEPTH; config->subprocess_level = BBF_SUBPROCESS_DEPTH;
} }
return 0;
}
opt_val = dmjson_get_value(deamon_obj, 2, "output", "parent_dm"); static int _parse_daemon_input_options(bbfdm_config_t *config, json_object *daemon_obj)
if (DM_STRLEN(opt_val)) { {
strncpyt(config->out_parent_dm, opt_val, sizeof(config->out_parent_dm)); char *opt_val = NULL;
if (!config || !daemon_obj) {
fprintf(stderr, "Invalid input options \n");
return -1;
} }
opt_val = dmjson_get_value(deamon_obj, 2, "output", "object"); opt_val = dmjson_get_value(daemon_obj, 2, "input", "plugin_dir");
if (DM_STRLEN(opt_val)) { if (DM_STRLEN(opt_val)) {
replace_str(opt_val, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, config->out_object, sizeof(config->out_object)); strncpyt(config->in_plugin_dir, opt_val, sizeof(config->in_plugin_dir));
} else if(is_micro_service == false) {
strncpyt(config->in_plugin_dir, BBFDM_DEFAULT_PLUGINS_PATH, sizeof(config->in_plugin_dir));
} }
json_object *arr_obj = NULL; opt_val = dmjson_get_value(daemon_obj, 2, "input", "name");
char *mem_obj = NULL; if (DM_STRLEN(opt_val)) {
int i = 0; strncpyt(config->in_name, opt_val, sizeof(config->in_name));
dmjson_foreach_value_in_array(deamon_obj, arr_obj, mem_obj, i, 2, "output", "multiple_objects") { opt_val = strrchr(opt_val, '/');
if (i < MAX_MULTI_OBJS) { if (opt_val) {
replace_str(mem_obj, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, config->out_multi_objects[i], sizeof(config->out_multi_objects[i])); strncpyt(config->service_name, opt_val + 1, sizeof(config->service_name));
} else {
WARNING("More multiple_object defined, can handle only %d ...", MAX_MULTI_OBJS);
break;
} }
} else if (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)
{
char opt_val[MAX_DM_PATH] = {0};
if (!config || !sname || strlen(sname) == 0) {
fprintf(stderr, "Invalid input options for service name \n");
return -1;
} }
opt_val = dmjson_get_value(deamon_obj, 2, "output", "root_obj"); strncpyt(config->service_name, sname, sizeof(config->service_name));
if (DM_STRLEN(opt_val)) {
strncpyt(config->out_root_obj, opt_val, sizeof(config->out_root_obj)); // check if the service plugin is DotSO plugin
snprintf(opt_val, MAX_DM_PATH, "%s/%s.so", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, sname);
if (!file_exists(opt_val)) {
snprintf(opt_val, MAX_DM_PATH, "%s/%s.json", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, sname);
} }
opt_val = dmjson_get_value(deamon_obj, 2, "output", "name"); if (!file_exists(opt_val)) {
if (is_micro_service == false) { fprintf(stderr, "Failed to load service plugin %s \n", sname);
strncpyt(config->out_name, opt_val, sizeof(config->out_name)); return -1;
} else {
char val[256] = {0};
if (DM_STRLEN(config->out_object)) {
snprintf(val, sizeof(val), "%s.%s", config->out_root_obj, config->out_object);
} else { //out_multi_objects present
snprintf(val, sizeof(val), "%s", config->out_root_obj);
for (i = 0; i < MAX_MULTI_OBJS; i++) {
if (DM_STRLEN(config->out_multi_objects[i]) == 0) {
break;
}
if (i == 0) {
snprintf(val, sizeof(val), "%s.%s", config->out_root_obj, config->out_multi_objects[0]);
} else {
int len = DM_STRLEN(val);
snprintf(val+len, sizeof(val) - len, "_%s", config->out_multi_objects[i]);
}
}
}
strncpyt(config->out_name, val, sizeof(config->out_name));
} }
opt_val = dmjson_get_value(deamon_obj, 2, "input", "plugin_dir"); strncpyt(config->in_name, opt_val, sizeof(config->in_name));
if (DM_STRLEN(opt_val)) {
snprintf(opt_val, MAX_DM_PATH, "%s/%s", BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH, sname);
if (dir_exists(opt_val)) {
strncpyt(config->in_plugin_dir, opt_val, sizeof(config->in_plugin_dir)); strncpyt(config->in_plugin_dir, opt_val, sizeof(config->in_plugin_dir));
} }
opt_val = dmjson_get_value(deamon_obj, 2, "input", "type"); return 0;
if (DM_STRLEN(opt_val)) { }
strncpyt(config->in_type, opt_val, sizeof(config->in_type));
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(deamon_obj, 2, "input", "name");
opt_val = dmjson_get_value(daemon_obj, 2, "output", "root_obj");
if (DM_STRLEN(opt_val)) { if (DM_STRLEN(opt_val)) {
strncpyt(config->in_name, opt_val, sizeof(config->in_name)); strncpyt(config->out_root_obj, opt_val, sizeof(config->out_root_obj));
} else if (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));
}
// for main process ubus object name
if (is_micro_service == false) {
opt_val = dmjson_get_value(daemon_obj, 2, "output", "name");
if (strlen(opt_val)) {
strncpyt(config->out_name, opt_val, sizeof(config->out_name));
} else {
strncpyt(config->out_name, BBFDM_DEFAULT_UBUS_OBJ, sizeof(config->out_name));
}
}
return 0;
}
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"); opt_val = dmjson_get_value(json_obj, 3, "cli", "config", "proto");
@ -1544,6 +1579,53 @@ static int bbfdm_load_deamon_config(bbfdm_config_t *config, const char *json_pat
if (DM_STRLEN(opt_val)) { if (DM_STRLEN(opt_val)) {
snprintf(config->cli_out_type, sizeof(config->cli_out_type), "%s", opt_val); snprintf(config->cli_out_type, sizeof(config->cli_out_type), "%s", opt_val);
} }
return 0;
}
static int bbfdm_load_deamon_config(bbfdm_config_t *config, const char *module)
{
char *opt_val = NULL;
int err = 0;
json_object *json_obj = NULL;
char json_path[MAX_DM_PATH] = {0};
if (!module || !strlen(module))
return -1;
if (strchr(module, '/')) { // absolute path
strncpyt(json_path, module, MAX_DM_PATH);
} else {
snprintf(json_path, MAX_DM_PATH, "%s/%s.json", BBFDM_DEFAULT_MICROSERVICE_INPUT_PATH, module);
}
json_obj = json_object_from_file(json_path);
if (!json_obj) {
fprintf(stderr, "Failed to read input %s file \n", json_path);
goto exit;
}
_parse_input_cli_options(config, json_obj);
json_object *daemon_obj = dmjson_get_obj(json_obj, 1, "daemon");
if (!daemon_obj) {
err = -1;
goto exit;
}
_parse_daemon_config_options(config, daemon_obj);
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);
}
if (err == -1) {
goto exit;
}
_parse_daemon_output_options(config, daemon_obj);
json_object_put(json_obj); json_object_put(json_obj);
return err; return err;
@ -1552,27 +1634,6 @@ exit:
json_object_put(json_obj); json_object_put(json_obj);
} }
if (is_micro_service == false) {
ERR("Switching to internal defaults");
config->transaction_timeout = 30;
config->refresh_time = BBF_INSTANCES_UPDATE_TIMEOUT;
config->subprocess_level = BBF_SUBPROCESS_DEPTH;
strncpyt(config->out_name, "bbfdm", 6);
strncpyt(config->in_plugin_dir, "/etc/bbfdm/plugins", 19);
strncpyt(config->in_type, "DotSo", 6);
strncpyt(config->in_name, "/lib/libbbfdm.so", 17);
config->proto = BBFDM_BOTH;
config->instance_mode = INSTANCE_MODE_NUMBER;
snprintf(config->cli_in_type, sizeof(config->cli_in_type), "%s", "UBUS");
snprintf(config->cli_in_name, sizeof(config->cli_in_name), "%s", "bbfdm");
snprintf(config->cli_out_type, sizeof(config->cli_out_type), "%s", "CLI");
set_debug_level(config->log_level);
configure_transaction_timeout(config->transaction_timeout);
err = 0;
}
return err; return err;
} }
@ -1671,7 +1732,7 @@ void register_instance_refresh_timer(struct ubus_context *ctx, int start_in)
} }
} }
void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx) static void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx)
{ {
memset(bbfdm_ctx, 0, sizeof(struct bbfdm_context)); memset(bbfdm_ctx, 0, sizeof(struct bbfdm_context));
blob_buf_init(&bbfdm_ctx->dm_schema, 0); blob_buf_init(&bbfdm_ctx->dm_schema, 0);
@ -1680,7 +1741,7 @@ void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx)
INIT_LIST_HEAD(&bbfdm_ctx->event_handlers); INIT_LIST_HEAD(&bbfdm_ctx->event_handlers);
} }
int daemon_load_datamodel(struct bbfdm_context *daemon_ctx) static int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
{ {
int err = -1; int err = -1;
char *file_path = daemon_ctx->config.in_name; char *file_path = daemon_ctx->config.in_name;
@ -1690,6 +1751,26 @@ int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
return -1; return -1;
} }
char *ext = strrchr(file_path, '.');
if (ext == NULL) {
ERR("Input file without extension");
} else if (strcasecmp(ext, ".json") == 0) {
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) {
INFO("Loading DotSo plugin %s", file_path);
err = load_dotso_plugin(&deamon_lib_handle, file_path, &daemon_ctx->config, &DEAMON_DM_ROOT_OBJ);
} else {
ERR("Input type %s not supported", ext);
}
if (!err) {
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 {
ERR("Failed loading %s", file_path);
}
if (DM_STRLEN(daemon_ctx->config.out_name) == 0) { if (DM_STRLEN(daemon_ctx->config.out_name) == 0) {
ERR("output name not defined"); ERR("output name not defined");
return -1; return -1;
@ -1701,8 +1782,8 @@ int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
return -1; return -1;
} }
if (DM_STRLEN(daemon_ctx->config.out_object) == 0 && DM_STRLEN(daemon_ctx->config.out_multi_objects[0]) == 0) { if (DM_STRLEN(daemon_ctx->config.out_objects[0]) == 0) {
ERR("output object and multiple_objects both are not defined"); ERR("output objects is not defined");
return -1; return -1;
} }
@ -1712,26 +1793,6 @@ int daemon_load_datamodel(struct bbfdm_context *daemon_ctx)
} }
} }
char *ext = strrchr(file_path, '.');
if (ext == NULL) {
ERR("Input file without extension");
} else if (strcasecmp(ext, ".json") == 0) {
INFO("Loading JSON plugin %s", file_path);
err = load_json_plugin(&loaded_json_files, &json_list, &json_memhead, file_path, &DEAMON_DM_ROOT_OBJ);
} else if (strcasecmp(ext, ".so") == 0) {
INFO("Loading DotSo plugin %s", file_path);
err = load_dotso_plugin(&deamon_lib_handle, file_path, &DEAMON_DM_ROOT_OBJ);
} else {
ERR("Input type %s not supported", ext);
}
if (!err) {
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 {
ERR("Failed loading %s", file_path);
}
return err; return err;
} }
@ -1742,6 +1803,9 @@ int main(int argc, char **argv)
char *cli_argv[4] = {0}; char *cli_argv[4] = {0};
int err = 0, ch, cli_argc = 0, i; int err = 0, ch, cli_argc = 0, i;
bool ubus_init_done = false; bool ubus_init_done = false;
char log_level[32] = {0};
bbfdm_ctx_init(&bbfdm_ctx);
while ((ch = getopt(argc, argv, "hs:m:c:")) != -1) { while ((ch = getopt(argc, argv, "hs:m:c:")) != -1) {
switch (ch) { switch (ch) {
@ -1766,20 +1830,16 @@ int main(int argc, char **argv)
} }
} }
bbfdm_ctx_init(&bbfdm_ctx); signal_init();
if (is_micro_service == false) { // It's not a micro-service instance
signal_init();
} else {
service_signal_init();
}
err = bbfdm_load_deamon_config(&bbfdm_ctx.config, input_file); err = bbfdm_load_deamon_config(&bbfdm_ctx.config, input_file);
if (err) { if (err) {
fprintf(stderr, "Failed to load %s config from json file (%s)\n", bbfdm_ctx.config.out_name, input_file); fprintf(stderr, "Failed to load %s config from json file (%s)\n", bbfdm_ctx.config.service_name, input_file);
goto exit; goto exit;
} }
openlog(bbfdm_ctx.config.out_name, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); snprintf(log_level, sizeof(log_level), "bbfdm.%s", bbfdm_ctx.config.service_name);
openlog(log_level, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
if (cli_argc) { if (cli_argc) {
err = bbfdm_cli_exec_command(&bbfdm_ctx.config, cli_argc, cli_argv); err = bbfdm_cli_exec_command(&bbfdm_ctx.config, cli_argc, cli_argv);
@ -1814,6 +1874,12 @@ int main(int argc, char **argv)
goto exit; goto exit;
if (is_micro_service == true) { // It's a micro-service instance if (is_micro_service == true) { // It's a micro-service instance
char proc_name[32] = {0};
snprintf(proc_name, sizeof(proc_name), "dm_%s", bbfdm_ctx.config.service_name);
// Set process name based on microservice
prctl(PR_SET_NAME, proc_name, NULL, NULL, NULL);
bool is_registred = register_service(&bbfdm_ctx.ubus_ctx); bool is_registred = register_service(&bbfdm_ctx.ubus_ctx);
if (is_registred == false) { if (is_registred == false) {
// register for add event // register for add event
@ -1824,6 +1890,7 @@ int main(int argc, char **argv)
ubus_register_event_handler(&bbfdm_ctx.ubus_ctx, &add_event, "ubus.object.add"); ubus_register_event_handler(&bbfdm_ctx.ubus_ctx, &add_event, "ubus.object.add");
} }
} }
INFO("Waiting on uloop...."); INFO("Waiting on uloop....");
uloop_run(); uloop_run();

View file

@ -7,7 +7,7 @@
#include "dmbbf.h" #include "dmbbf.h"
#define MAX_MULTI_OBJS 5 #define MAX_OBJS 5
struct bbfdm_async_req { struct bbfdm_async_req {
struct ubus_context *ctx; struct ubus_context *ctx;
@ -17,25 +17,24 @@ struct bbfdm_async_req {
}; };
typedef struct bbfdm_config { typedef struct bbfdm_config {
int proto; int proto; // Protocol identifier, Possible values: { '0'<both>, '1'<cwmp>, '2'<usp> }
int instance_mode; int instance_mode; // Instance mode, Possible values: { '0'<Instance Number>, '1'<Instance Alias> }
int transaction_timeout; int transaction_timeout; // Timeout for transactions
int subprocess_level; int subprocess_level; // Subprocess level
uint8_t log_level; uint8_t log_level; // Log level, Possible values: { '1', '2', '3', '4' }
uint32_t refresh_time; uint32_t refresh_time; // Refresh time
char in_type[32]; char service_name[16]; // Service name for micro-service identification
char in_name[128]; char in_type[32]; // Input type, Possible values: { 'JSON', 'DotSo' }
char in_plugin_dir[128]; char in_name[128]; // plugin path
char out_type[32]; char in_plugin_dir[128]; // extra plugin directory path
char out_name[128]; char out_name[128]; // Ubus name to use
char out_parent_dm[32]; char out_parent_dm[32]; // Parent device for micro-service
char out_object[32]; char out_objects[MAX_OBJS][32]; // Micro-service objects to expose
char out_multi_objects[MAX_MULTI_OBJS][32]; char out_root_obj[32]; // Ubus name to use as root data model
char out_root_obj[32]; char cli_in_type[32]; // CLI input type, Possible values: { 'UBUS', 'JSON', 'DotSo' }
char cli_in_type[32]; char cli_in_name[128]; // CLI input name
char cli_in_name[128]; char cli_in_plugin_dir[128]; // CLI input plugin directory
char cli_in_plugin_dir[128]; char cli_out_type[32]; // CLI output type, Possible values: { 'CLI' }
char cli_out_type[32];
} bbfdm_config_t; } bbfdm_config_t;
struct bbfdm_context { struct bbfdm_context {

View file

@ -514,12 +514,12 @@ static int cli_exec_command(cli_data_t *cli_data, int argc, char *argv[])
if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0) { if (strcasecmp(cli_data->in_type, "DotSO") == 0 || strcasecmp(cli_data->in_type, "JSON") == 0) {
if (strcasecmp(cli_data->in_type, "DotSO") == 0) { if (strcasecmp(cli_data->in_type, "DotSO") == 0) {
if (load_dotso_plugin(&cli_lib_handle, cli_data->in_name, &CLI_DM_ROOT_OBJ) != 0) { if (load_dotso_plugin(&cli_lib_handle, cli_data->in_name, NULL, &CLI_DM_ROOT_OBJ) != 0) {
err = EXIT_FAILURE; err = EXIT_FAILURE;
goto end; goto end;
} }
} else { } else {
if (load_json_plugin(&loaded_json_files, &json_list, &json_memhead, cli_data->in_name, &CLI_DM_ROOT_OBJ) != 0) { if (load_json_plugin(&loaded_json_files, &json_list, &json_memhead, cli_data->in_name, NULL, &CLI_DM_ROOT_OBJ) != 0) {
err = EXIT_FAILURE; err = EXIT_FAILURE;
goto end; goto end;
} }

View file

@ -31,8 +31,30 @@ static uint8_t find_number_of_objects(DM_MAP_OBJ *dynamic_obj)
return len; return len;
} }
static void fill_dotso_micro_service_out_args(bbfdm_config_t *config, DMOBJ *entryobj, char *parent_dm, int *idx)
{
if (!config || !entryobj || !parent_dm || !idx || *idx >= MAX_OBJS)
return;
int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_entry) 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]));
int len = DM_STRLEN(config->out_name);
if (len == 0) {
snprintf(config->out_name, sizeof(config->out_name), "%s.%s", config->out_root_obj, entryobj->obj);
} else {
snprintf(config->out_name + len, sizeof(config->out_name) - len, "_%s", entryobj->obj);
}
}
}
int load_dotso_plugin(void **lib_handle, const char *file_path, bbfdm_config_t *config, DMOBJ **main_entry)
{ {
if (!lib_handle || !file_path || !strlen(file_path) || !main_entry) { if (!lib_handle || !file_path || !strlen(file_path) || !main_entry) {
ERR("Input validation failed\n"); ERR("Input validation failed\n");
@ -65,6 +87,8 @@ int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_ent
return -1; return -1;
} }
int out_obj_idx = 0;
for (int i = 0; dynamic_obj[i].path; i++) { for (int i = 0; dynamic_obj[i].path; i++) {
char *node_obj = dm_dynamic_strdup(&plugin_mem, dynamic_obj[i].path); char *node_obj = dm_dynamic_strdup(&plugin_mem, dynamic_obj[i].path);
unsigned int len = strlen(node_obj); unsigned int len = strlen(node_obj);
@ -74,6 +98,10 @@ int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_ent
return -1; return -1;
} }
// Fill out arguments if it is running as micro-service
if (is_micro_service == true)
fill_dotso_micro_service_out_args(config, dynamic_obj[i].root_obj, node_obj, &out_obj_idx);
node_obj[len-1] = 0; node_obj[len-1] = 0;
dm_entryobj[i].obj = node_obj; dm_entryobj[i].obj = node_obj;
@ -101,7 +129,24 @@ int free_dotso_plugin(void *lib_handle)
return 0; return 0;
} }
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path, DMOBJ **main_entry) static void fill_json_micro_service_out_args(bbfdm_config_t *config, char *parent_dm, char *obj, int idx)
{
if (!config || !obj || idx >= MAX_OBJS)
return;
strncpyt(config->out_parent_dm, parent_dm, sizeof(config->out_parent_dm));
strncpyt(config->out_objects[idx], obj, sizeof(config->out_objects[idx]));
int len = DM_STRLEN(config->out_name);
if (len == 0) {
snprintf(config->out_name, sizeof(config->out_name), "%s.%s", config->out_root_obj, obj);
} else {
snprintf(config->out_name + len, sizeof(config->out_name) - len, "_%s", obj);
}
}
int 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; DMOBJ *dm_entryobj = NULL;
int json_plugin_version = JSON_VERSION_0; int json_plugin_version = JSON_VERSION_0;
@ -148,6 +193,17 @@ int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list,
return -1; return -1;
} }
char obj_name[64] = {0};
json_plugin_find_current_obj(node_obj, obj_name, sizeof(obj_name));
if (strlen(obj_name) == 0) {
ERR("ERROR: Obj name is empty for (%s) Object\n", node_obj);
return -1;
}
// Fill out arguments if it is running as micro-service
if (is_micro_service == true)
fill_json_micro_service_out_args(config, obj_prefix, obj_name, idx);
// Remove '.' from object prefix // Remove '.' from object prefix
if (obj_prefix[obj_prefix_len - 1] == '.') if (obj_prefix[obj_prefix_len - 1] == '.')
obj_prefix[obj_prefix_len - 1] = 0; obj_prefix[obj_prefix_len - 1] = 0;

View file

@ -10,10 +10,11 @@
#ifndef PLUGIN_H #ifndef PLUGIN_H
int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_entry); 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 free_dotso_plugin(void *lib_handle);
int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list, struct list_head *json_memhead, const char *file_path, DMOBJ **main_entry); int 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 free_json_plugin(void);
#endif /* PLUGIN_H */ #endif /* PLUGIN_H */

View file

@ -8,7 +8,7 @@
## 1. Shared library via external package ## 1. Shared library via external package
The application should bring its shared library under **'/usr/lib/bbfdm/'** path that contains the sub tree of **Objects/Parameters** and the related functions **Get/Set/Add/Delete/Operate**. The new added objects, parameters and operates will be automatically shown by icwmpd and bbfdmd/obuspa. The application should bring its shared library under **'/usr/share/bbfdm/plugins'** path that contains the sub tree of **Objects/Parameters** and the related functions **Get/Set/Add/Delete/Operate**. The new added objects, parameters and operates will be automatically shown by icwmpd and bbfdmd/obuspa.
Each library should contains the Root table: **“tDynamicObj”** Each library should contains the Root table: **“tDynamicObj”**

View file

@ -16,9 +16,8 @@ if [ -n "${CI_SERVER_HOST}" ]; then
fi fi
# Make sure that all plugins are removed # Make sure that all plugins are removed
repo_dir="/etc/bbfdm/plugins" [ ! -d "${BBFDM_PLUGIN_DIR}" ] && mkdir -p "${BBFDM_PLUGIN_DIR}"
[ ! -d "${repo_dir}" ] && mkdir -p "${repo_dir}" rm -f ${BBFDM_PLUGIN_DIR}/*
rm -f ${repo_dir}/*
if [ -z "${1}" ]; then if [ -z "${1}" ]; then
./tools/generate_dm.py tools/tools_input.json ./tools/generate_dm.py tools/tools_input.json

View file

@ -10,9 +10,8 @@ exec_cmd apt install -y python3-pip iproute2 jq
exec_cmd pip3 install pexpect ubus xlwt exec_cmd pip3 install pexpect ubus xlwt
# Make sure that all plugins are removed # Make sure that all plugins are removed
repo_dir="/etc/bbfdm/plugins" [ ! -d "${BBFDM_PLUGIN_DIR}" ] && mkdir -p "${BBFDM_PLUGIN_DIR}"
[ ! -d "${repo_dir}" ] && mkdir -p "${repo_dir}" rm -f ${BBFDM_PLUGIN_DIR}/*
rm -f ${repo_dir}/*
# compile and install libbbf # compile and install libbbf
install_libbbf ${1} install_libbbf ${1}
@ -23,11 +22,11 @@ install_libbbf_test ${1}
# Install datamodel plugins/micro-service only when pipeline trigger for bbfdm # Install datamodel plugins/micro-service only when pipeline trigger for bbfdm
if [ -z "${1}" ]; then if [ -z "${1}" ]; then
# Generate plugin_input.json # Generate plugin_input.json
jq 'del(.output)' tools/tools_input.json > plugin_input.json jq 'del(.output)' tools/tools_input.json > /tmp/plugin_input.json
# Install datamodel plugins # Install datamodel plugins
./tools/generate_dm.py plugin_input.json ./tools/generate_dm.py /tmp/plugin_input.json
check_ret $? check_ret $?
ls -l /etc/bbfdm/plugins/ ls -l /usr/share/bbfdm/plugins/
fi fi

View file

@ -2,6 +2,8 @@
echo "# Setting pipeline ci credentials" echo "# Setting pipeline ci credentials"
echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}" > ~/.git-credential if [ -n "${CI_SERVER_HOST}" ]; then
git config --global credential.helper "store --file ~/.git-credential" echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}" > ~/.git-credential
git config --global credential.helper "store --file ~/.git-credential"
fi

View file

@ -1,5 +1,7 @@
#!/bin/bash #!/bin/bash
BBFDM_PLUGIN_DIR="/usr/share/bbfdm/plugins"
if [ -z "${CI_PROJECT_PATH}" ]; then if [ -z "${CI_PROJECT_PATH}" ]; then
CI_PROJECT_PATH=${PWD} CI_PROJECT_PATH=${PWD}
fi fi
@ -41,7 +43,7 @@ function exec_cmd_verbose()
function install_plugin() function install_plugin()
{ {
exec_cmd cp -f "${1}" /etc/bbfdm/plugins/ exec_cmd cp -f "${1}" ${BBFDM_PLUGIN_DIR}/
} }
function install_libbbf() function install_libbbf()
@ -67,7 +69,7 @@ function install_libbbf()
echo "installing libbbf" echo "installing libbbf"
exec_cmd_verbose make install exec_cmd_verbose make install
ln -sf /usr/share/bbfdm/bbf.diag /usr/libexec/rpcd/bbf.diag ln -sf /usr/share/bbfdm/scripts/bbf.diag /usr/libexec/rpcd/bbf.diag
echo "371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04" > /etc/bbfdm/.secure_hash echo "371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04" > /etc/bbfdm/.secure_hash
cd .. cd ..
} }

View file

@ -18,33 +18,19 @@ echo "Validate BBF Data Model JSON Plugin"
./tools/validate_json_plugin.py libbbfdm/dmtree/json/datamodel.json ./tools/validate_json_plugin.py libbbfdm/dmtree/json/datamodel.json
check_ret $? check_ret $?
echo "Validate X_IOPSYS_EU_Dropbear JSON Plugin" echo "Validating plugins"
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/X_IOPSYS_EU_Dropbear.json for plugin in $(ls -1 test/files/usr/share/bbfdm/plugins/*); do
check_ret $? echo "Validating ${plugin} JSON Plugin"
./tools/validate_json_plugin.py ${plugin}
check_ret $?
done
echo "Validate X_IOPSYS_EU_TEST JSON Plugin" echo "Validate test Plugin"
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/X_IOPSYS_EU_TEST.json for plugin in $(ls -1 test/vendor_test/*); do
check_ret $? echo "Validating ${plugin} JSON Plugin"
./tools/validate_json_plugin.py test/vendor_test/test_extend.json
echo "Validate X_IOPSYS_EU_WiFi JSON Plugin" check_ret $?
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/X_IOPSYS_EU_WiFi.json done
check_ret $?
echo "Validate UCI_TEST_V1 JSON Plugin"
./tools/validate_json_plugin.py test/files/etc/bbfdm/plugins/X_IOPSYS_EU_JSON_TEST_V1.json
check_ret $?
echo "Validate test extend Plugin"
./tools/validate_json_plugin.py test/vendor_test/test_extend.json
check_ret $?
echo "Validate test exclude Plugin"
./tools/validate_json_plugin.py test/vendor_test/test_exclude.json
check_ret $?
echo "Validate test overwrite Plugin"
./tools/validate_json_plugin.py test/vendor_test/test_overwrite.json
check_ret $?
echo "Validate Data Model JSON Plugin after generating from TR-181, TR-104 and TR-135 XML Files" echo "Validate Data Model JSON Plugin after generating from TR-181, TR-104 and TR-135 XML Files"
json_path=$(./tools/convert_dm_xml_to_json.py -d test/tools/) json_path=$(./tools/convert_dm_xml_to_json.py -d test/tools/)

View file

@ -142,6 +142,7 @@ extern char *RateAdjAlgorithm[]; // To be removed later!!!!!!!!!!!!
#define FILE_URI "file://" #define FILE_URI "file://"
#define FILE_LOCALHOST_URI "file://localhost" #define FILE_LOCALHOST_URI "file://localhost"
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100) #define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
#define BBFDM_SCRIPTS_PATH "/usr/share/bbfdm/scripts"
#define DM_ASSERT(X, Y) \ #define DM_ASSERT(X, Y) \
do { \ do { \

View file

@ -162,7 +162,7 @@ void json_plugin_find_prefix_obj(const char *full_obj, char *prefix_obj, size_t
snprintf(prefix_obj, len, "%s", full_object); snprintf(prefix_obj, len, "%s", full_object);
} }
static void json_plugin_find_current_obj(const char *full_obj, char *curr_obj, size_t len) void json_plugin_find_current_obj(const char *full_obj, char *curr_obj, size_t len)
{ {
int last_occurent = 0, occur = 0; int last_occurent = 0, occur = 0;
char full_object[MAX_DM_LENGTH] = {0}; char full_object[MAX_DM_LENGTH] = {0};

View file

@ -23,6 +23,7 @@ enum json_plugin_version {
void save_loaded_json_files(struct list_head *json_list, json_object *data); void save_loaded_json_files(struct list_head *json_list, json_object *data);
void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json_version, struct list_head *list); void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json_version, struct list_head *list);
void json_plugin_find_prefix_obj(const char *full_obj, char *prefix_obj, size_t len); void json_plugin_find_prefix_obj(const char *full_obj, char *prefix_obj, size_t len);
void json_plugin_find_current_obj(const char *full_obj, char *curr_obj, size_t len);
int get_json_plugin_version(json_object *json_obj); int get_json_plugin_version(json_object *json_obj);
int load_json_plugins(DMOBJ *entryobj, const char *path); int load_json_plugins(DMOBJ *entryobj, const char *path);

View file

@ -43,12 +43,15 @@ ADD_LIBRARY(bbfdm SHARED ${BBF_DM_SOURCES} ${BBF_TR181_SOURCES} ${BBF_TR143_SOUR
TARGET_LINK_LIBRARIES(bbfdm uci ubus ubox json-c blobmsg_json m bbfdm-api ssl crypto) 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 INSTALL(TARGETS bbfdm
LIBRARY DESTINATION usr/lib) LIBRARY DESTINATION usr/lib)
INSTALL(DIRECTORY DESTINATION etc/bbfdm) INSTALL(DIRECTORY DESTINATION etc/bbfdm)
INSTALL(DIRECTORY DESTINATION etc/bbfdm/dmmap) INSTALL(DIRECTORY DESTINATION etc/bbfdm/dmmap)
INSTALL(DIRECTORY DESTINATION etc/bbfdm/plugins) INSTALL(DIRECTORY DESTINATION usr/share/bbfdm/plugins)
IF(BBF_TR143) IF(BBF_TR143)
INSTALL(DIRECTORY DESTINATION usr/share/bbfdm) INSTALL(DIRECTORY DESTINATION usr/share/bbfdm)
@ -58,12 +61,12 @@ IF(BBF_TR143)
FOREACH(script ${scripts}) FOREACH(script ${scripts})
IF(IS_DIRECTORY ${script}) IF(IS_DIRECTORY ${script})
INSTALL(DIRECTORY ${script} INSTALL(DIRECTORY ${script}
DESTINATION usr/share/bbfdm DESTINATION usr/share/bbfdm/scripts
) )
ELSE() ELSE()
INSTALL(FILES ${script} INSTALL(FILES ${script}
PERMISSIONS OWNER_EXECUTE PERMISSIONS OWNER_EXECUTE
DESTINATION usr/share/bbfdm DESTINATION usr/share/bbfdm/scripts
) )
ENDIF() ENDIF()
ENDFOREACH() ENDFOREACH()

View file

@ -15,9 +15,9 @@
#endif #endif
#ifdef BBF_TR143 #ifdef BBF_TR143
#define TRACEROUTE_DIAGNOSTIC_PATH "/usr/share/bbfdm/traceroute" #define TRACEROUTE_DIAGNOSTIC_PATH BBFDM_SCRIPTS_PATH"/traceroute"
#define DOWNLOAD_DIAGNOSTIC_PATH "/usr/share/bbfdm/download" #define DOWNLOAD_DIAGNOSTIC_PATH BBFDM_SCRIPTS_PATH"/download"
#define UPLOAD_DIAGNOSTIC_PATH "/usr/share/bbfdm/upload" #define UPLOAD_DIAGNOSTIC_PATH BBFDM_SCRIPTS_PATH"/upload"
#endif #endif
/************************************************************* /*************************************************************

View file

@ -11,7 +11,7 @@
#include "packetcapture.h" #include "packetcapture.h"
#define PACKET_CAPTURE_DIAGNOSTIC_PATH "/usr/share/bbfdm/packetcapture" #define PACKET_CAPTURE_DIAGNOSTIC_PATH BBFDM_SCRIPTS_PATH"/packetcapture"
/************************************************************* /*************************************************************
* ENTRY METHODS * ENTRY METHODS

View file

@ -11,7 +11,7 @@
#include "iplayercap.h" #include "iplayercap.h"
#define IPLAYER_CAP_DIAGNOSTIC_PATH "/usr/share/bbfdm/iplayercap" #define IPLAYER_CAP_DIAGNOSTIC_PATH BBFDM_SCRIPTS_PATH"/iplayercap"
static char *Protocol_Version[] = {"Any", "IPv4", "IPv6", NULL}; static char *Protocol_Version[] = {"Any", "IPv4", "IPv6", NULL};
static char *IPLayerCapacity_Role[] = {"Receiver", "Sender", NULL}; static char *IPLayerCapacity_Role[] = {"Receiver", "Sender", NULL};

View file

@ -10,4 +10,4 @@ FILE(GLOB BBF_IOPSYS_VENDOR_EXTENSION_SOURCES ../../../dmlayer.c *.c)
ADD_LIBRARY(bbfdm_iopsys_ext SHARED ${BBF_IOPSYS_VENDOR_EXTENSION_SOURCES}) ADD_LIBRARY(bbfdm_iopsys_ext SHARED ${BBF_IOPSYS_VENDOR_EXTENSION_SOURCES})
INSTALL(TARGETS bbfdm_iopsys_ext INSTALL(TARGETS bbfdm_iopsys_ext
LIBRARY DESTINATION etc/bbfdm/plugins) LIBRARY DESTINATION usr/share/bbfdm/plugins)

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
BBF_DIAG_SCRIPTS="/usr/share/bbfdm/bbf_diag" BBF_DIAG_SCRIPTS="/usr/share/bbfdm/scripts/bbf_diag"
. /usr/share/libubox/jshn.sh . /usr/share/libubox/jshn.sh

View file

@ -4,7 +4,7 @@
# Author: AMIN Ben Ramdhane <amin.benramdhane@pivasoftware.com> # Author: AMIN Ben Ramdhane <amin.benramdhane@pivasoftware.com>
. /usr/share/libubox/jshn.sh . /usr/share/libubox/jshn.sh
. /usr/share/bbfdm/bbf_api . /usr/share/bbfdm/scripts/bbf_api
ipping_list() { ipping_list() {
json_add_object "ipping" json_add_object "ipping"

View file

@ -3,7 +3,7 @@
# Author: AMIN Ben Ramdhane <amin.benramdhane@pivasoftware.com> # Author: AMIN Ben Ramdhane <amin.benramdhane@pivasoftware.com>
. /usr/share/libubox/jshn.sh . /usr/share/libubox/jshn.sh
. /usr/share/bbfdm/bbf_api . /usr/share/bbfdm/scripts/bbf_api
get_nslookup_log_file() { get_nslookup_log_file() {
IDX=1 IDX=1

View file

@ -3,7 +3,7 @@
# Author: AMIN Ben Ramdhane <amin.benramdhane@pivasoftware.com> # Author: AMIN Ben Ramdhane <amin.benramdhane@pivasoftware.com>
. /usr/share/libubox/jshn.sh . /usr/share/libubox/jshn.sh
. /usr/share/bbfdm/bbf_api . /usr/share/bbfdm/scripts/bbf_api
serverselection_list() { serverselection_list() {
json_add_object "serverselection" json_add_object "serverselection"

View file

@ -3,7 +3,7 @@
# Author: AMIN Ben Ramdhane <amin.benramdhane@pivasoftware.com> # Author: AMIN Ben Ramdhane <amin.benramdhane@pivasoftware.com>
. /usr/share/libubox/jshn.sh . /usr/share/libubox/jshn.sh
. /usr/share/bbfdm/bbf_api . /usr/share/bbfdm/scripts/bbf_api
udpecho_list() { udpecho_list() {
json_add_object "udpecho" json_add_object "udpecho"

View file

@ -2,7 +2,7 @@ LIB = libbbf_test.so
LIB_OBJS = libbbf_test.o LIB_OBJS = libbbf_test.o
LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC -I /usr/local/include/ LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC -I /usr/local/include/
LIB_LDFLAGS = $(LDFLAGS) -lbbfdm-api LIB_LDFLAGS = $(LDFLAGS) -L/usr/share/bbfdm -lbbfdm-api
%.o: %.c %.o: %.c
$(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $< $(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $<

View file

@ -1,6 +1,6 @@
CC = gcc CC = gcc
CFLAGS = -g -Wall -Werror CFLAGS = -g -Wall -Werror
LDFLAGS = -lcmocka -lbbfdm-api -lbbfdm LDFLAGS = -lcmocka -L/usr/share/bbfdm -lbbfdm-api -lbbfdm
UNIT_TESTS = unit_test_bbfd UNIT_TESTS = unit_test_bbfd
FUNCTIONAL_TESTS = functional_test_bbfd FUNCTIONAL_TESTS = functional_test_bbfd
FUNCTIONAL_API_TESTS = functional_api_test_bbfd FUNCTIONAL_API_TESTS = functional_api_test_bbfd

View file

@ -41,7 +41,7 @@ static int teardown_commit(void **state)
static int group_init(void **state) static int group_init(void **state)
{ {
bbf_global_init(TR181_ROOT_TREE, "/etc/bbfdm/plugins"); bbf_global_init(TR181_ROOT_TREE, "/usr/share/bbfdm/plugins");
return 0; return 0;
} }

View file

@ -52,7 +52,7 @@ static int teardown_revert(void **state)
static int group_init(void **state) static int group_init(void **state)
{ {
bbf_global_init(TR181_ROOT_TREE, "/etc/bbfdm/plugins"); bbf_global_init(TR181_ROOT_TREE, "/usr/share/bbfdm/plugins");
return 0; return 0;
} }

View file

@ -1,11 +1,12 @@
{ {
"daemon": { "daemon": {
"config": { "config": {
"loglevel": "1"
}, },
"input": { "input": {
"type": "DotSo", "type": "DotSo",
"name": "/lib/libbbfdm.so", "name": "/usr/share/bbfdm/libbbfdm.so",
"plugin_dir": "/etc/bbfdm/plugins" "plugin_dir": "/usr/share/bbfdm/plugins"
}, },
"output": { "output": {
"type": "UBUS", "type": "UBUS",

View file

@ -13,8 +13,8 @@ $(LIB): $(LIB_OBJS)
$(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^ $(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
install: install:
cp -f $(LIB) /etc/bbfdm/plugins cp -f $(LIB) /usr/share/bbfdm/plugins/
cp -f *.json /etc/bbfdm/plugins cp -f *.json /usr/share/bbfdm/plugins
clean: clean:
rm -fv *.o $(LIB) rm -fv *.o $(LIB)

View file

@ -97,7 +97,7 @@ $ ./tools/validate_json_plugin.py test/files/etc/bbfdm/json/X_IOPSYS_EU_TEST.jso
$ ./tools/validate_json_plugin.py dmtree/json/datamodel.json $ ./tools/validate_json_plugin.py dmtree/json/datamodel.json
``` ```
More examples available in [this path](https://dev.iopsys.eu/bbf/bbfdm/-/tree/devel/test/files/etc/bbfdm/plugins). More examples available in [this path](../test/files/usr/share/bbfdm/plugins).
### generate_dm.sh ### generate_dm.sh

View file

@ -230,8 +230,8 @@ def create_bbfdm_input_json_file(proto):
}, },
"input": { "input": {
"type": "DotSo", "type": "DotSo",
"name": "/lib/libbbfdm.so", "name": "/usr/share/bbfdm/libbbfdm.so",
"plugin_dir": "/etc/bbfdm/plugins" "plugin_dir": "/usr/share/bbfdm/plugins"
}, },
"output": { "output": {
"type": "CLI" "type": "CLI"
@ -374,7 +374,7 @@ def download_and_build_plugins(plugins, vendor_prefix):
if filename.endswith('.c'): if filename.endswith('.c'):
LIST_FILES.append(filename) LIST_FILES.append(filename)
elif filename.endswith('.json'): elif filename.endswith('.json'):
move_file(filename, "/etc/bbfdm/plugins") move_file(filename, "/usr/share/bbfdm/plugins")
else: else:
print(f"Unknown file format {filename}") print(f"Unknown file format {filename}")
BBF_ERROR_CODE += 1 BBF_ERROR_CODE += 1
@ -383,7 +383,7 @@ def download_and_build_plugins(plugins, vendor_prefix):
BBF_ERROR_CODE += 1 BBF_ERROR_CODE += 1
if len(LIST_FILES) > 0: if len(LIST_FILES) > 0:
generate_shared_library(f"/etc/bbfdm/plugins/lib{plugin_index}.so", LIST_FILES, vendor_prefix, extra_dependencies) generate_shared_library(f"/usr/share/bbfdm/plugins/lib{plugin_index}.so", LIST_FILES, vendor_prefix, extra_dependencies)
clear_list(LIST_FILES) clear_list(LIST_FILES)
cd_dir(CURRENT_PATH) cd_dir(CURRENT_PATH)

View file

@ -117,9 +117,9 @@
{ {
"repo": "https://dev.iopsys.eu/feed/openwrt-packages.git", "repo": "https://dev.iopsys.eu/feed/openwrt-packages.git",
"proto": "git", "proto": "git",
"version": "devel", "version": "bbfdm_shared",
"dm_files": [ "dm_files": [
"net/openvpn/files/etc/bbfdm/plugins/OpenVPN_DM.json" "net/openvpn/files/bbfdm/OpenVPN_DM.json"
] ]
}, },
{ {