diff --git a/Makefile b/Makefile
index 6f01f0e407e782bd1b2f32e05bce6c4be1e9433e..c7d0c9f29ffbff3487317377adc1e9ef057f01d9 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ swmodd:
clean:
make -C src clean
- -rm -f swmodd
+ -rm -f swmodd *.so
-find -name '*.gcda' -exec rm {} -fv \;
-find -name '*.gcno' -exec rm {} -fv \;
-find -name '*.gcov' -exec rm {} -fv \;
diff --git a/README.md b/README.md
index 403a2c95f0b6fd5a42a337801b79ab5db3a7a798..242a2dd872fddd29efac2794066444aafc3fac62 100644
--- a/README.md
+++ b/README.md
@@ -7,10 +7,11 @@ It is written in C programming language and depends on a number of libraries of
## Good to Know
`SWMODD` currently has support for LXC containers and can also be used to manage host services in the same way. To manage the service/deployment units it depends on `opkg`, so all the `opkg` limitations can be considered as limitation for `swmodd` as well with respect to listing/installing/upgrading packages/services.
-Currently, `swmodd` can not create new environment and it depends on pre-created environments/containers. `swmodd` treats host as one environment and further it usages the pre-created lxc-containers as available environments for managing services.
+Currently, `swmodd` can not create new execution environment and it depends on pre-created execution environments/containers. `swmodd` treats host as one execution environment and further it usages the pre-created lxc-containers as available execution environments for managing services.
## Concepts and Workflow
`SWMODD` usages lxc library to interact with the lxc containers and opkg system utilities to manage the services running inside that container.
+`swmodd` is used to manage the software modules and exposes the functionality over ubus, whereas `libswmodd.so` is `bbf` plugin which exposes the SoftwareModules functionality over TR181 using `libbbf_api`.
## swmodd uBus
@@ -30,10 +31,10 @@ root@iopsys:~#
For more info on the `swmodules` ubus schema see [link](./docs/api/swmodules.md) or [raw schema](./schemas/ubus/swmodules.json)
-### tr069 ubus examples
+### swmodd ubus examples
The outputs shown below are just an example, it can vary on each system. Long outputs are truncated to beautify the document.
-#### List down the available environments
+#### List down the available execution environments
```bash
root@iopsys:~# ubus call swmodules environment
{
diff --git a/gitlab-ci/setup.sh b/gitlab-ci/setup.sh
index 7d5a0a066ce18a34f5f0b878eff40a01291bd9d6..f441c89d27884f9eca2038486c1119c1c819f5bd 100755
--- a/gitlab-ci/setup.sh
+++ b/gitlab-ci/setup.sh
@@ -3,6 +3,6 @@
echo "preparation script"
pwd
-#cp -r ./test/files/* /
+cp -r ./test/files/* /
cp ./gitlab-ci/iopsys-supervisord.conf /etc/supervisor/conf.d/
diff --git a/gitlab-ci/shared.sh b/gitlab-ci/shared.sh
index d200846421f8b5a11e7504267b0c10bd94bf2e39..1aa934fa6150a41795d38b9a8aa596b9de138638 100644
--- a/gitlab-ci/shared.sh
+++ b/gitlab-ci/shared.sh
@@ -63,4 +63,6 @@ function build_swmodd()
{
CFLAGS="-g -O0 -fprofile-arcs -ftest-coverage" LDFLAGS="--coverage" make
check_ret $?
+ mkdir -p /usr/lib/bbfdm/
+ exec_cmd libswmodd.so /usr/lib/bbfdm/libswmodd.so
}
diff --git a/src/Makefile b/src/Makefile
index 4d6e446ff1dfc00329482e9f18da3426a6c9f67c..72570a1ef5b447848a1d05ed902b3cbb5ced1aec 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,9 +3,12 @@ CP := cp -f
endif
PROG = swmodd
+LIB = libswmodd.so
+
OBJS = swmod.o swmod_host.o swmod_opkg.o swmod_uci.o tools.o
+LIB_OBJS = datamodel.o
-PROG_CFLAGS = $(CFLAGS) -fstrict-aliasing -Wall
+PROG_CFLAGS = $(CFLAGS) -fstrict-aliasing -Wall -fPIC
PROG_LDFLAGS = $(LDFLAGS) -luci -lubus -lubox -lblobmsg_json -luuid
ifeq ($(SWMOD_LXC),yes)
@@ -17,11 +20,15 @@ endif
%.o: %.c
$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
-all: ${PROG}
+all: ${PROG} ${LIB}
${PROG}: $(OBJS)
$(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS)
$(CP) ${PROG} ../${PROG}
+$(LIB): $(LIB_OBJS)
+ $(CC) $(PROG_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
+ $(CP) ${LIB} ../${LIB}
+
clean:
- rm -f *.o $(PROG)
+ rm -f *.o $(PROG) $(LIB)
diff --git a/src/datamodel.c b/src/datamodel.c
new file mode 100644
index 0000000000000000000000000000000000000000..22ef9e9ed1ebbb7cc489a3d9e49ced820f5deead
--- /dev/null
+++ b/src/datamodel.c
@@ -0,0 +1,944 @@
+/*
+ * 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 "datamodel.h"
+
+DMLEAF tSoftwareModulesExecEnvParams[];
+DMLEAF tSoftwareModulesDeploymentUnitParams[];
+DMLEAF tSoftwareModulesExecutionUnitParams[];
+static opr_ret_t swmodules_exec_env_reset(struct dmctx *dmctx, char *path, json_object *input);
+static opr_ret_t swmodules_install_du(struct dmctx *dmctx, char *path, json_object *input);
+static opr_ret_t swmodules_update_du(struct dmctx *dmctx, char *path, json_object *input);
+static opr_ret_t swmodules_uninstall_du(struct dmctx *dmctx, char *path, json_object *input);
+
+char *get_param_val_from_op_cmd(char *op_cmd, const char *param);
+
+struct deployment_unit_install {
+ char *url;
+ char *uuid;
+ char *username;
+ char *password;
+ char *environment;
+};
+
+struct deployment_unit_update {
+ char *url;
+ char *username;
+ char *password;
+};
+
+// Dynamic Operate commands
+DM_MAP_OPERATE tDynamicOperate[] = {
+ {
+ "Device.SoftwareModules.ExecEnv.*.Reset", swmodules_exec_env_reset, "sync"
+ },
+ {
+ "Device.SoftwareModules.InstallDU", swmodules_install_du, "async",
+ {
+ .in = (const char *[]) {
+ "URL",
+ "UUID",
+ "Username",
+ "Password",
+ "ExecutionEnvRef",
+ NULL
+ }
+ }
+ },
+ {
+ "Device.SoftwareModules.DeploymentUnit.*.Update", swmodules_update_du, "async",
+ {
+ .in = (const char *[]) {
+ "URL",
+ "Username",
+ "Password",
+ NULL
+ }
+ }
+ },
+ {
+ "Device.SoftwareModules.DeploymentUnit.*.Uninstall", swmodules_uninstall_du, "async"
+ },
+ {0}
+};
+
+/* ********** DynamicObj ********** */
+DM_MAP_OBJ tDynamicObj[] = {
+/* parentobj, nextobject, parameter */
+{"Device.", tSWmodObj, NULL},
+{0}
+};
+
+DMOBJ tSWmodObj[] = {
+/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
+{"SoftwareModules", &DMREAD, NULL, NULL, "ubus:swmodules", NULL, NULL, NULL, tSoftwareModulesObj, tSoftwareModulesParams, NULL, BBFDM_BOTH},
+{0}
+};
+
+// Operate command
+static opr_ret_t swmodules_exec_env_reset(struct dmctx *dmctx, char *path, json_object *input)
+{
+ char *exec_env = get_param_val_from_op_cmd(path, "Name");
+ if (exec_env) {
+ if (strcmp(exec_env, "OpenWRT_Linux") == 0) {
+ if (0 == dmcmd_no_wait("/sbin/defaultreset", 0))
+ return SUCCESS;
+ else
+ return FAIL;
+ }
+ } else
+ return FAIL;
+
+ return SUCCESS;
+}
+
+static opr_ret_t swmodules_install_du(struct dmctx *dmctx, char *path, json_object *input)
+{
+ json_object *res = NULL;
+ struct deployment_unit_install du_install = {0};
+
+ du_install.url = dmjson_get_value(input, 1, "URL");
+ if (du_install.url[0] == '\0')
+ return UBUS_INVALID_ARGUMENTS;
+ du_install.uuid = dmjson_get_value(input, 1, "UUID");
+ du_install.username = dmjson_get_value(input, 1, "Username");
+ du_install.password = dmjson_get_value(input, 1, "Password");
+ du_install.environment = dmjson_get_value(input, 1, "ExecutionEnvRef");
+
+ char *exec_env = get_param_val_from_op_cmd(du_install.environment ? du_install.environment : "Device.SoftwareModules.ExecEnv.1.", "Name");
+ if (!exec_env)
+ return FAIL;
+
+ dmubus_call("swmodules", "du_install", UBUS_ARGS{
+ {"url", du_install.url, String},
+ {"uuid", du_install.uuid, String},
+ {"username", du_install.username, String},
+ {"password", du_install.password, String},
+ {"environment", exec_env, String}},
+ 5,
+ &res);
+
+ if (!res)
+ return FAIL;
+
+ char *status = dmjson_get_value(res, 1, "status");
+
+ return (strcmp(status, "true") == 0) ? SUCCESS : FAIL;
+}
+
+static opr_ret_t swmodules_update_du(struct dmctx *dmctx, char *path, json_object *input)
+{
+ json_object *res = NULL;
+ struct deployment_unit_update du_update = {0};
+
+ du_update.url = dmjson_get_value(input, 1, "URL");
+ if (du_update.url[0] == '\0')
+ return UBUS_INVALID_ARGUMENTS;
+ du_update.username = dmjson_get_value(input, 1, "Username");
+ du_update.password = dmjson_get_value(input, 1, "Password");
+
+ char *du_uuid = get_param_val_from_op_cmd(path, "UUID");
+ if (!du_uuid)
+ return FAIL;
+
+ dmubus_call("swmodules", "du_update", UBUS_ARGS{
+ {"uuid", du_uuid, String},
+ {"url", du_update.url, String},
+ {"username", du_update.username, String},
+ {"password", du_update.password, String}},
+ 4,
+ &res);
+
+ if (!res)
+ return FAIL;
+
+ char *status = dmjson_get_value(res, 1, "status");
+
+ return (strcmp(status, "true") == 0) ? SUCCESS : FAIL;
+}
+
+static opr_ret_t swmodules_uninstall_du(struct dmctx *dmctx, char *path, json_object *input)
+{
+ json_object *res = NULL;
+ char exec_env_path[64] = {0};
+
+ char *du_name = get_param_val_from_op_cmd(path, "Name");
+ if (!du_name)
+ return FAIL;
+
+ char *exec_env = get_param_val_from_op_cmd(path, "ExecutionEnvRef");
+ if (!exec_env)
+ return FAIL;
+
+ snprintf(exec_env_path, sizeof(exec_env_path), "%s.", exec_env);
+ char *env = get_param_val_from_op_cmd(exec_env_path, "Name");
+ if (!env)
+ return FAIL;
+
+ dmubus_call("swmodules", "du_uninstall", UBUS_ARGS{
+ {"name", du_name, String},
+ {"environment", env, String}},
+ 2,
+ &res);
+
+ if (!res)
+ return FAIL;
+
+ char *status = dmjson_get_value(res, 1, "status");
+
+ return (strcmp(status, "true") == 0) ? SUCCESS : FAIL;
+
+}
+
+/**************************************************************************
+* LINKER
+***************************************************************************/
+static int get_exe_cenv_linker(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker)
+{
+ char *name = dmjson_get_value((json_object *)data, 1, "name");
+ *linker = (name && *name) ? dmstrdup(name) : "";
+ return 0;
+}
+
+static int get_du_linker(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker)
+{
+ char *name = dmjson_get_value((json_object *)data, 1, "name");
+ char *environment = dmjson_get_value((json_object *)data, 1, "environment");
+ dmasprintf(linker, "%s-%s", name, environment);
+ return 0;
+}
+
+/*************************************************************
+* ENTRY METHOD
+*************************************************************/
+static int browseSoftwareModulesExecEnvInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
+{
+ json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
+ char *inst = NULL, *max_inst = NULL;
+ int id = 0, env = 0;
+
+ dmubus_call("swmodules", "environment", UBUS_ARGS{}, 0, &res);
+ dmjson_foreach_obj_in_array(res, arrobj, du_obj, env, 1, "environment") {
+ inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id);
+ if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)du_obj, inst) == DM_STOP)
+ break;
+ }
+ return 0;
+}
+
+static int browseSoftwareModulesDeploymentUnitInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
+{
+ json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
+ char *inst = NULL, *max_inst = NULL;
+ int id = 0, du = 0;
+
+ dmubus_call("swmodules", "du_list", UBUS_ARGS{}, 0, &res);
+ dmjson_foreach_obj_in_array(res, arrobj, du_obj, du, 1, "deployment_unit") {
+ inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id);
+ if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)du_obj, inst) == DM_STOP)
+ break;
+ }
+ return 0;
+}
+
+static int browseSoftwareModulesExecutionUnitInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
+{
+ json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
+ char *inst = NULL, *max_inst = NULL;
+ int id = 0, eu = 0;
+
+ dmubus_call("swmodules", "eu_list", UBUS_ARGS{}, 0, &res);
+ dmjson_foreach_obj_in_array(res, arrobj, du_obj, eu, 1, "execution_unit") {
+ inst = handle_update_instance(1, dmctx, &max_inst, update_instance_without_section, 1, ++id);
+ if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)du_obj, inst) == DM_STOP)
+ break;
+ }
+ return 0;
+}
+
+/*************************************************************
+* COMMON FUNCTIONS
+**************************************************************/
+static int get_SoftwareModules_VendorConfigList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ struct uci_section *s = NULL;
+ *value = "";
+
+ char *config = dmjson_get_value((json_object *)data, 1, "config");
+ if (config == NULL || *config == '\0')
+ return 0;
+
+ uci_path_foreach_sections(bbfdm, DMMAP, "vcf", s) {
+ char *name = NULL;
+
+ dmuci_get_value_by_section_string(s, "name", &name);
+ if (name && strcmp(name, config) == 0) {
+ char *vcf_instance;
+ dmuci_get_value_by_section_string(s, "vcf_instance", &vcf_instance);
+ dmasprintf(value, "Device.DeviceInfo.VendorConfigFile.%s", vcf_instance);
+ break;
+ }
+ }
+ return 0;
+}
+
+/*************************************************************
+* GET & SET PARAM
+*************************************************************/
+static int get_SoftwareModules_ExecEnvNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ json_object *res = NULL, *environment = NULL;
+ size_t nbre_env = 0;
+
+ dmubus_call("swmodules", "environment", UBUS_ARGS{}, 0, &res);
+ DM_ASSERT(res, *value = "0");
+ json_object_object_get_ex(res, "environment", &environment);
+ nbre_env = (environment) ? json_object_array_length(environment) : 0;
+ dmasprintf(value, "%d", nbre_env);
+ return 0;
+}
+
+static int get_SoftwareModules_DeploymentUnitNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ json_object *res = NULL, *deployment_unit = NULL;
+ size_t nbre_du = 0;
+
+ dmubus_call("swmodules", "du_list", UBUS_ARGS{}, 0, &res);
+ DM_ASSERT(res, *value = "0");
+ json_object_object_get_ex(res, "deployment_unit", &deployment_unit);
+ nbre_du = (deployment_unit) ? json_object_array_length(deployment_unit) : 0;
+ dmasprintf(value, "%d", nbre_du);
+ return 0;
+}
+
+static int get_SoftwareModules_ExecutionUnitNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ json_object *res = NULL, *execution_unit = NULL;
+ size_t nbre_env = 0;
+
+ dmubus_call("swmodules", "eu_list", UBUS_ARGS{}, 0, &res);
+ DM_ASSERT(res, *value = "0");
+ json_object_object_get_ex(res, "execution_unit", &execution_unit);
+ nbre_env = (execution_unit) ? json_object_array_length(execution_unit) : 0;
+ dmasprintf(value, "%d", nbre_env);
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.Enable!UBUS:swmodules/environment//environment[i-1].status*/
+static int get_SoftwareModulesExecEnv_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ char *status = dmjson_get_value((json_object *)data, 1, "status");
+ *value = (status && strcmp(status, "Up") == 0) ? "1" : "0";
+ return 0;
+}
+
+static int set_SoftwareModulesExecEnv_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ char *env_name = NULL;
+ bool b;
+
+ switch (action) {
+ case VALUECHECK:
+ if (dm_validate_boolean(value))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ string_to_bool(value, &b);
+ env_name = dmjson_get_value((json_object *)data, 1, "name");
+ if (env_name && strcmp(env_name, "OpenWRT_Linux") != 0)
+ dmcmd_no_wait(b ? "/usr/bin/lxc-start" : "/usr/bin/lxc-stop", 2, "-n", env_name);
+ break;
+ }
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.Status!UBUS:swmodules/environment//environment[i-1].status*/
+static int get_SoftwareModulesExecEnv_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "status");
+ return 0;
+}
+
+static int get_SoftwareModulesExecEnv_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = "0";
+ return 0;
+}
+
+static int set_SoftwareModulesExecEnv_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ char *env_name = NULL;
+ bool b;
+
+ switch (action) {
+ case VALUECHECK:
+ if (dm_validate_boolean(value))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ string_to_bool(value, &b);
+ env_name = dmjson_get_value((json_object *)data, 1, "name");
+ if (env_name && strcmp(env_name, "OpenWRT_Linux") == 0) {
+ if (b) dmcmd_no_wait("/sbin/defaultreset", 0);
+ }
+ break;
+ }
+ return 0;
+}
+
+static int get_SoftwareModulesExecEnv_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ struct uci_section *s = NULL;
+ char *env_name = NULL;
+
+ char *name = dmjson_get_value((json_object *)data, 1, "name");
+ uci_path_foreach_sections(bbfdm, "dmmap_sw_modules", "environment", s) {
+ dmuci_get_value_by_section_string(s, "name", &env_name);
+ if (name && env_name && strcmp(env_name, name) == 0) {
+ dmuci_get_value_by_section_string(s, "alias", value);
+ break;
+ }
+ }
+ if ((*value)[0] == '\0')
+ dmasprintf(value, "cpe-%s", instance);
+ return 0;
+}
+
+static int set_SoftwareModulesExecEnv_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ struct uci_section *s = NULL, *dmmap = NULL;
+ char *name;
+ bool found = false;
+
+ switch (action) {
+ case VALUECHECK:
+ if (dm_validate_string(value, -1, 64, NULL, NULL))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ name = dmjson_get_value((json_object *)data, 1, "name");
+ uci_path_foreach_option_eq(bbfdm, "dmmap_sw_modules", "environment", "name", name, s) {
+ dmuci_set_value_by_section_bbfdm(s, "alias", value);
+ found = true;
+ }
+ if (!found) {
+ dmuci_add_section_bbfdm("dmmap_sw_modules", "environment", &dmmap);
+ dmuci_set_value_by_section(dmmap, "name", name);
+ dmuci_set_value_by_section(dmmap, "alias", value);
+ }
+ break;
+ }
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.Name!UBUS:swmodules/environment//environment[i-1].name*/
+static int get_SoftwareModulesExecEnv_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "name");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.Type!UBUS:swmodules/environment//environment[i-1].type*/
+static int get_SoftwareModulesExecEnv_Type(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "type");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.Vendor!UBUS:swmodules/environment//environment[i-1].vendor*/
+static int get_SoftwareModulesExecEnv_Vendor(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "vendor");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.Version!UBUS:swmodules/environment//environment[i-1].version*/
+static int get_SoftwareModulesExecEnv_Version(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "version");
+ return 0;
+}
+
+static int get_SoftwareModulesExecEnv_ParentExecEnv(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ char *env_name = dmjson_get_value((json_object *)data, 1, "name");
+ if (env_name && strcmp(env_name, "OpenWRT_Linux"))
+ adm_entry_get_linker_param(ctx, "Device.SoftwareModules.ExecEnv.", env_name, value);
+ if (*value == NULL)
+ *value = "";
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.AllocatedDiskSpace!UBUS:swmodules/environment//environment[i-1].allocateddiskspace*/
+static int get_SoftwareModulesExecEnv_AllocatedDiskSpace(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "allocated_disk_space");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.AvailableDiskSpace!UBUS:swmodules/environment//environment[i-1].availablediskspace*/
+static int get_SoftwareModulesExecEnv_AvailableDiskSpace(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "available_disk_space");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.AllocatedMemory!UBUS:swmodules/environment//environment[i-1].allocatedmemory*/
+static int get_SoftwareModulesExecEnv_AllocatedMemory(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "allocated_memory");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecEnv.{i}.AvailableMemory!UBUS:swmodules/environment//environment[i-1].availablememory*/
+static int get_SoftwareModulesExecEnv_AvailableMemory(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "available_memory");
+ return 0;
+}
+
+static int get_SoftwareModulesExecEnv_ActiveExecutionUnits(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
+ unsigned pos = 0, eu = 0;
+ char eu_list[1024];
+
+ eu_list[0] = 0;
+ char *curr_env = dmjson_get_value((json_object *)data, 1, "name");
+ dmubus_call("swmodules", "eu_list", UBUS_ARGS{}, 0, &res);
+ DM_ASSERT(res, *value = "");
+ dmjson_foreach_obj_in_array(res, arrobj, du_obj, eu, 1, "execution_unit") {
+ char *environment = dmjson_get_value(du_obj, 1, "environment");
+
+ if (strcmp(environment, curr_env) == 0)
+ pos += snprintf(&eu_list[pos], sizeof(eu_list) - pos, "Device.SoftwareModules.ExecutionUnit.%u,", eu+1);
+ }
+
+ if (pos)
+ eu_list[pos - 1] = 0;
+
+ *value = dmstrdup(eu_list);
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.UUID!UBUS:swmodules/du_list//deployment_unit[i-1].uuid*/
+static int get_SoftwareModulesDeploymentUnit_UUID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "uuid");
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.DUID!UBUS:swmodules/du_list//deployment_unit[i-1].duid*/
+static int get_SoftwareModulesDeploymentUnit_DUID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "duid");
+ return 0;
+}
+
+static int get_SoftwareModulesDeploymentUnit_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ struct uci_section *s = NULL;
+ char *du_name = NULL, *du_env = NULL;
+
+ char *name = dmjson_get_value((json_object *)data, 1, "name");
+ char *environment = dmjson_get_value((json_object *)data, 1, "environment");
+ uci_path_foreach_sections(bbfdm, "dmmap_sw_modules", "deployment_unit", s) {
+ dmuci_get_value_by_section_string(s, "name", &du_name);
+ dmuci_get_value_by_section_string(s, "environment", &du_env);
+ if (name && du_name && (strcmp(du_name, name) == 0) && (environment && du_env && strcmp(du_env, environment) == 0)) {
+ dmuci_get_value_by_section_string(s, "alias", value);
+ break;
+ }
+ }
+ if ((*value)[0] == '\0')
+ dmasprintf(value, "cpe-%s", instance);
+ return 0;
+}
+
+static int set_SoftwareModulesDeploymentUnit_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ struct uci_section *s = NULL, *dmmap = NULL;
+ char *du_name, *du_env, *environment = NULL, *name = NULL;
+ bool found = false;
+
+ switch (action) {
+ case VALUECHECK:
+ if (dm_validate_string(value, -1, 64, NULL, NULL))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ name = dmjson_get_value((json_object *)data, 1, "name");
+ environment = dmjson_get_value((json_object *)data, 1, "environment");
+ uci_path_foreach_sections(bbfdm, "dmmap_sw_modules", "deployment_unit", s) {
+ dmuci_get_value_by_section_string(s, "name", &du_name);
+ dmuci_get_value_by_section_string(s, "environment", &du_env);
+ if (name && (strcmp(du_name, name) == 0) && (environment && strcmp(du_env, environment) == 0)) {
+ dmuci_set_value_by_section_bbfdm(s, "alias", value);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ dmuci_add_section_bbfdm("dmmap_sw_modules", "deployment_unit", &dmmap);
+ dmuci_set_value_by_section(dmmap, "name", name);
+ dmuci_set_value_by_section(dmmap, "environment", environment);
+ dmuci_set_value_by_section(dmmap, "alias", value);
+ }
+ break;
+ }
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.Name!UBUS:swmodules/du_list//deployment_unit[i-1].name*/
+static int get_SoftwareModulesDeploymentUnit_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "name");
+ return 0;
+}
+
+static int get_SoftwareModulesDeploymentUnit_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = "Installed";
+ return 0;
+}
+
+static int get_SoftwareModulesDeploymentUnit_Resolved(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = "1";
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.URL!UBUS:swmodules/du_list//deployment_unit[i-1].url*/
+static int get_SoftwareModulesDeploymentUnit_URL(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "url");
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.Description!UBUS:swmodules/du_list//deployment_unit[i-1].description*/
+static int get_SoftwareModulesDeploymentUnit_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "description");
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.Vendor!UBUS:swmodules/du_list//deployment_unit[i-1].vendor*/
+static int get_SoftwareModulesDeploymentUnit_Vendor(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "vendor");
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.Version!UBUS:swmodules/du_list//deployment_unit[i-1].version*/
+static int get_SoftwareModulesDeploymentUnit_Version(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "version");
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.VendorConfigList!UBUS:swmodules/du_list//deployment_unit[i-1].config*/
+static int get_SoftwareModulesDeploymentUnit_VendorConfigList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ return get_SoftwareModules_VendorConfigList(refparam, ctx, data, instance, value);
+}
+
+static int get_SoftwareModulesDeploymentUnit_ExecutionUnitList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
+ char *environment = NULL, *name = NULL;
+ int eu = 0;
+
+ char *curr_name = dmjson_get_value((json_object *)data, 1, "name");
+ char *curr_environment = dmjson_get_value((json_object *)data, 1, "environment");
+
+ dmubus_call("swmodules", "eu_list", UBUS_ARGS{}, 0, &res);
+ DM_ASSERT(res, *value = "");
+ dmjson_foreach_obj_in_array(res, arrobj, du_obj, eu, 1, "execution_unit") {
+ name = dmjson_get_value(du_obj, 1, "name");
+ environment = dmjson_get_value(du_obj, 1, "environment");
+ if ((name && curr_name && strcmp(name, curr_name) == 0) && (environment && curr_environment && strcmp(environment, curr_environment) == 0)) {
+ dmasprintf(value, "Device.SoftwareModules.ExecutionUnit.%d", eu+1);
+ break;
+ }
+ }
+ return 0;
+}
+
+/*#Device.SoftwareModules.DeploymentUnit.{i}.ExecutionEnvRef!UBUS:swmodules/du_list//deployment_unit[i-1].environment*/
+static int get_SoftwareModulesDeploymentUnit_ExecutionEnvRef(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ char *linker = dmjson_get_value((json_object *)data, 1, "environment");
+ adm_entry_get_linker_param(ctx, "Device.SoftwareModules.ExecEnv.", linker, value);
+ if (*value == NULL)
+ *value = "";
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.EUID!UBUS:swmodules/eu_list//execution_unit[i-1].euid*/
+static int get_SoftwareModulesExecutionUnit_EUID(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "euid");
+ return 0;
+}
+
+static int get_SoftwareModulesExecutionUnit_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ struct uci_section *s = NULL;
+ char *eu_euid = NULL, *eu_env = NULL;
+
+ char *euid = dmjson_get_value((json_object *)data, 1, "euid");
+ char *environment = dmjson_get_value((json_object *)data, 1, "environment");
+ uci_path_foreach_sections(bbfdm, "dmmap_sw_modules", "execution_unit", s) {
+ dmuci_get_value_by_section_string(s, "euid", &eu_euid);
+ dmuci_get_value_by_section_string(s, "environment", &eu_env);
+ if ((euid && eu_euid && strcmp(eu_euid, euid) == 0) && (environment && eu_env && strcmp(eu_env, environment) == 0)) {
+ dmuci_get_value_by_section_string(s, "alias", value);
+ break;
+ }
+ }
+ if ((*value)[0] == '\0')
+ dmasprintf(value, "cpe-%s", instance);
+ return 0;
+}
+
+static int set_SoftwareModulesExecutionUnit_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+ struct uci_section *s = NULL, *dmmap = NULL;
+ char *eu_euid, *eu_env, *environment, *euid;
+ bool found = false;
+
+ switch (action) {
+ case VALUECHECK:
+ if (dm_validate_string(value, -1, 64, NULL, NULL))
+ return FAULT_9007;
+ break;
+ case VALUESET:
+ euid = dmjson_get_value((json_object *)data, 1, "euid");
+ environment = dmjson_get_value((json_object *)data, 1, "environment");
+ uci_path_foreach_sections(bbfdm, "dmmap_sw_modules", "execution_unit", s) {
+ dmuci_get_value_by_section_string(s, "euid", &eu_euid);
+ dmuci_get_value_by_section_string(s, "environment", &eu_env);
+ if ((strcmp(eu_euid, euid) == 0) && (strcmp(eu_env, environment) == 0)) {
+ dmuci_set_value_by_section_bbfdm(s, "alias", value);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ dmuci_add_section_bbfdm("dmmap_sw_modules", "execution_unit", &dmmap);
+ dmuci_set_value_by_section(dmmap, "euid", euid);
+ dmuci_set_value_by_section(dmmap, "environment", environment);
+ dmuci_set_value_by_section(dmmap, "alias", value);
+ }
+ break;
+ }
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.Name!UBUS:swmodules/eu_list//execution_unit[i-1].name*/
+static int get_SoftwareModulesExecutionUnit_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "name");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.ExecEnvLabel!UBUS:swmodules/eu_list//execution_unit[i-1].euid*/
+static int get_SoftwareModulesExecutionUnit_ExecEnvLabel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "euid");
+ return 0;
+}
+
+static int get_SoftwareModulesExecutionUnit_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = "Active";
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.Vendor!UBUS:swmodules/eu_list//execution_unit[i-1].vendor*/
+static int get_SoftwareModulesExecutionUnit_Vendor(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "vendor");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.Version!UBUS:swmodules/eu_list//execution_unit[i-1].version*/
+static int get_SoftwareModulesExecutionUnit_Version(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "version");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.Description!UBUS:swmodules/eu_list//execution_unit[i-1].description*/
+static int get_SoftwareModulesExecutionUnit_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "description");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.DiskSpaceInUse!UBUS:swmodules/eu_list//execution_unit[i-1].disk_space*/
+static int get_SoftwareModulesExecutionUnit_DiskSpaceInUse(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "disk_space");
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.MemoryInUse!UBUS:swmodules/eu_list//execution_unit[i-1].memory_space*/
+static int get_SoftwareModulesExecutionUnit_MemoryInUse(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ *value = dmjson_get_value((json_object *)data, 1, "memory_space");
+ return 0;
+}
+
+static int get_SoftwareModulesExecutionUnit_References(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
+ char *environment = NULL, *name = NULL;
+ int du = 0;
+
+ char *curr_name = dmjson_get_value((json_object *)data, 1, "name");
+ char *curr_environment = dmjson_get_value((json_object *)data, 1, "environment");
+
+ dmubus_call("swmodules", "du_list", UBUS_ARGS{}, 0, &res);
+ DM_ASSERT(res, *value = "");
+ dmjson_foreach_obj_in_array(res, arrobj, du_obj, du, 1, "deployment_unit") {
+ name = dmjson_get_value(du_obj, 1, "name");
+ environment = dmjson_get_value(du_obj, 1, "environment");
+ if ((name && curr_name && strcmp(name, curr_name) == 0) && (environment && curr_environment && strcmp(environment, curr_environment) == 0)) {
+ dmasprintf(value, "Device.SoftwareModules.DeploymentUnit.%d", du+1);
+ break;
+ }
+ }
+ return 0;
+}
+
+static int get_SoftwareModulesExecutionUnit_AssociatedProcessList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ json_object *res = NULL, *processes_obj = NULL, *arrobj = NULL;
+ char *pid = NULL;
+ int process = 0;
+
+ char *euid = dmjson_get_value((json_object *)data, 1, "euid");
+ dmubus_call("router.system", "processes", UBUS_ARGS{}, 0, &res);
+ DM_ASSERT(res, *value = "");
+ dmjson_foreach_obj_in_array(res, arrobj, processes_obj, process, 1, "processes") {
+ pid = dmjson_get_value(processes_obj, 1, "pid");
+ if (pid && euid && strcmp(euid, pid) == 0) {
+ dmasprintf(value, "Device.DeviceInfo.ProcessStatus.Process.%d", process+1);
+ break;
+ }
+ }
+ return 0;
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.VendorConfigList!UBUS:swmodules/eu_list//execution_unit[i-1].config*/
+static int get_SoftwareModulesExecutionUnit_VendorConfigList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ return get_SoftwareModules_VendorConfigList(refparam, ctx, data, instance, value);
+}
+
+/*#Device.SoftwareModules.ExecutionUnit.{i}.ExecutionEnvRef!UBUS:swmodules/eu_list//execution_unit[i-1].environment*/
+static int get_SoftwareModulesExecutionUnit_ExecutionEnvRef(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+ char *linker = dmjson_get_value((json_object *)data, 1, "environment");
+ adm_entry_get_linker_param(ctx, "Device.SoftwareModules.ExecEnv.", linker, value);
+ if (*value == NULL)
+ *value = "";
+ return 0;
+}
+
+/* *** Device.SoftwareModules. *** */
+DMOBJ tSoftwareModulesObj[] = {
+/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
+{"ExecEnv", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecEnvInst, NULL, NULL, NULL, tSoftwareModulesExecEnvParams, get_exe_cenv_linker, BBFDM_BOTH, LIST_KEY{"Alias", "Name", NULL}},
+{"DeploymentUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesDeploymentUnitInst, NULL, NULL, NULL, tSoftwareModulesDeploymentUnitParams, get_du_linker, BBFDM_BOTH, LIST_KEY{"UUID", "Version", "ExecutionEnvRef", "Alias", NULL}},
+{"ExecutionUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecutionUnitInst, NULL, NULL, NULL, tSoftwareModulesExecutionUnitParams, NULL, BBFDM_BOTH, LIST_KEY{"EUID", "Alias", NULL}},
+{0}
+};
+
+DMLEAF tSoftwareModulesParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
+{"ExecEnvNumberOfEntries", &DMREAD, DMT_UNINT, get_SoftwareModules_ExecEnvNumberOfEntries, NULL, BBFDM_BOTH},
+{"DeploymentUnitNumberOfEntries", &DMREAD, DMT_UNINT, get_SoftwareModules_DeploymentUnitNumberOfEntries, NULL, BBFDM_BOTH},
+{"ExecutionUnitNumberOfEntries", &DMREAD, DMT_UNINT, get_SoftwareModules_ExecutionUnitNumberOfEntries, NULL, BBFDM_BOTH},
+{0}
+};
+
+/* *** Device.SoftwareModules.ExecEnv.{i}. *** */
+DMLEAF tSoftwareModulesExecEnvParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
+{"Enable", &DMWRITE, DMT_BOOL, get_SoftwareModulesExecEnv_Enable, set_SoftwareModulesExecEnv_Enable, BBFDM_BOTH},
+{"Status", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_Status, NULL, BBFDM_BOTH},
+{"Reset", &DMWRITE, DMT_BOOL, get_SoftwareModulesExecEnv_Reset, set_SoftwareModulesExecEnv_Reset, BBFDM_CWMP},
+{"Alias", &DMWRITE, DMT_STRING, get_SoftwareModulesExecEnv_Alias, set_SoftwareModulesExecEnv_Alias, BBFDM_BOTH},
+{"Name", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_Name, NULL, BBFDM_BOTH},
+{"Type", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_Type, NULL, BBFDM_BOTH},
+//{"InitialRunLevel", &DMWRITE, DMT_UNINT, get_SoftwareModulesExecEnv_InitialRunLevel, set_SoftwareModulesExecEnv_InitialRunLevel, BBFDM_BOTH},
+//{"RequestedRunLevel", &DMWRITE, DMT_INT, get_SoftwareModulesExecEnv_RequestedRunLevel, set_SoftwareModulesExecEnv_RequestedRunLevel, BBFDM_CWMP},
+//{"CurrentRunLevel", &DMREAD, DMT_INT, get_SoftwareModulesExecEnv_CurrentRunLevel, NULL, BBFDM_BOTH},
+//{"InitialExecutionUnitRunLevel", &DMWRITE, DMT_INT, get_SoftwareModulesExecEnv_InitialExecutionUnitRunLevel, set_SoftwareModulesExecEnv_InitialExecutionUnitRunLevel, BBFDM_BOTH},
+{"Vendor", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_Vendor, NULL, BBFDM_BOTH},
+{"Version", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_Version, NULL, BBFDM_BOTH},
+{"ParentExecEnv", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_ParentExecEnv, NULL, BBFDM_BOTH},
+{"AllocatedDiskSpace", &DMREAD, DMT_INT, get_SoftwareModulesExecEnv_AllocatedDiskSpace, NULL, BBFDM_BOTH},
+{"AvailableDiskSpace", &DMREAD, DMT_INT, get_SoftwareModulesExecEnv_AvailableDiskSpace, NULL, BBFDM_BOTH},
+{"AllocatedMemory", &DMREAD, DMT_INT, get_SoftwareModulesExecEnv_AllocatedMemory, NULL, BBFDM_BOTH},
+{"AvailableMemory", &DMREAD, DMT_INT, get_SoftwareModulesExecEnv_AvailableMemory, NULL, BBFDM_BOTH},
+{"ActiveExecutionUnits", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_ActiveExecutionUnits, NULL, BBFDM_BOTH},
+//{"ProcessorRefList", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_ProcessorRefList, NULL, BBFDM_BOTH},
+{0}
+};
+
+/* *** Device.SoftwareModules.DeploymentUnit.{i}. *** */
+DMLEAF tSoftwareModulesDeploymentUnitParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
+{"UUID", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_UUID, NULL, BBFDM_BOTH},
+{"DUID", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_DUID, NULL, BBFDM_BOTH},
+{"Alias", &DMWRITE, DMT_STRING, get_SoftwareModulesDeploymentUnit_Alias, set_SoftwareModulesDeploymentUnit_Alias, BBFDM_BOTH},
+{"Name", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_Name, NULL, BBFDM_BOTH},
+{"Status", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_Status, NULL, BBFDM_BOTH},
+{"Resolved", &DMREAD, DMT_BOOL, get_SoftwareModulesDeploymentUnit_Resolved, NULL, BBFDM_BOTH},
+{"URL", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_URL, NULL, BBFDM_BOTH},
+{"Description", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_Description, NULL, BBFDM_BOTH},
+{"Vendor", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_Vendor, NULL, BBFDM_BOTH},
+{"Version", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_Version, NULL, BBFDM_BOTH},
+//{"VendorLogList", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_VendorLogList, NULL, BBFDM_BOTH},
+{"VendorConfigList", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_VendorConfigList, NULL, BBFDM_BOTH},
+{"ExecutionUnitList", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_ExecutionUnitList, NULL, BBFDM_BOTH},
+{"ExecutionEnvRef", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_ExecutionEnvRef, NULL, BBFDM_BOTH},
+{0}
+};
+
+DMLEAF tSoftwareModulesExecutionUnitParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
+{"EUID", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_EUID, NULL, BBFDM_BOTH},
+{"Alias", &DMWRITE, DMT_STRING, get_SoftwareModulesExecutionUnit_Alias, set_SoftwareModulesExecutionUnit_Alias, BBFDM_BOTH},
+{"Name", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_Name, NULL, BBFDM_BOTH},
+{"ExecEnvLabel", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_ExecEnvLabel, NULL, BBFDM_BOTH},
+{"Status", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_Status, NULL, BBFDM_BOTH},
+//{"RequestedState", &DMWRITE, DMT_STRING, get_SoftwareModulesExecutionUnit_RequestedState, set_SoftwareModulesExecutionUnit_RequestedState, BBFDM_CWMP},
+//{"ExecutionFaultCode", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_ExecutionFaultCode, NULL, BBFDM_BOTH},
+//{"ExecutionFaultMessage", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_ExecutionFaultMessage, NULL, BBFDM_BOTH},
+//{"AutoStart", &DMWRITE, DMT_BOOL, get_SoftwareModulesExecutionUnit_AutoStart, set_SoftwareModulesExecutionUnit_AutoStart, BBFDM_BOTH},
+//{"RunLevel", &DMWRITE, DMT_UNINT, get_SoftwareModulesExecutionUnit_RunLevel, set_SoftwareModulesExecutionUnit_RunLevel, BBFDM_BOTH},
+{"Vendor", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_Vendor, NULL, BBFDM_BOTH},
+{"Version", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_Version, NULL, BBFDM_BOTH},
+{"Description", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_Description, NULL, BBFDM_BOTH},
+{"DiskSpaceInUse", &DMREAD, DMT_INT, get_SoftwareModulesExecutionUnit_DiskSpaceInUse, NULL, BBFDM_BOTH},
+{"MemoryInUse", &DMREAD, DMT_INT, get_SoftwareModulesExecutionUnit_MemoryInUse, NULL, BBFDM_BOTH},
+{"References", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_References, NULL, BBFDM_BOTH},
+{"AssociatedProcessList", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_AssociatedProcessList, NULL, BBFDM_BOTH},
+//{"VendorLogList", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_VendorLogList, NULL, BBFDM_BOTH},
+{"VendorConfigList", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_VendorConfigList, NULL, BBFDM_BOTH},
+//{"SupportedDataModelList", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_SupportedDataModelList, NULL, BBFDM_CWMP},
+{"ExecutionEnvRef", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_ExecutionEnvRef, NULL, BBFDM_BOTH},
+{0}
+};
+
diff --git a/src/datamodel.h b/src/datamodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..02bb0a6b24956bbe43eeddbc547e0639552ce89e
--- /dev/null
+++ b/src/datamodel.h
@@ -0,0 +1,20 @@
+/*
+ * 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 __DATAMODEL_H
+#define __DATAMODEL_H
+
+#include <libbbf_api/dmcommon.h>
+
+DMOBJ tSWmodObj[];
+DMOBJ tSoftwareModulesObj[];
+DMLEAF tSoftwareModulesParams[];
+#endif //__DATAMODEL_H
+
diff --git a/test/files/etc/swmod/map_du b/test/files/etc/swmod/map_du
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391