diff --git a/src/Makefile b/src/Makefile
index ad5e9250bd632193fe24a71a654619bf7ebf3b5c..2d8ae15a04b8ec0d1863c9919dffa5090d46da5b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -5,7 +5,7 @@ endif
 PROG = swmodd
 LIB = libswmodd.so
 
-OBJS = swmod.o swmod_host.o swmod_opkg.o swmod_uci.o tools.o opkg_utils.o swmod_api.o
+OBJS = swmod.o swmod_uci.o tools.o swmod_api.o
 LIB_OBJS = datamodel.o
 
 PROG_CFLAGS = $(CFLAGS) -fstrict-aliasing -Wall -Werror -fPIC
@@ -22,6 +22,10 @@ OBJS += swmod_crun.o
 PROG_CFLAGS += -DSWMOD_CRUN
 endif
 
+ifdef SWMOD_VERS
+PROG_CFLAGS += -DSWMOD_VERSION=\"$(SWMOD_VERS)\"
+endif
+
 %.o: %.c
 	$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
 
diff --git a/src/datamodel.c b/src/datamodel.c
index be99ac01a79665b8f70b4712c109b3ba44ba38cf..67d14ed0ecb2e1eb7848edf7be5499deb06ca3f8 100644
--- a/src/datamodel.c
+++ b/src/datamodel.c
@@ -17,477 +17,490 @@ DM_MAP_OBJ tDynamicObj[] = {
 {0}
 };
 
+struct ee_class {
+	char name[256];
+	char vendor[128];
+	char version[32];
+	struct uci_section *dmmap_sec;
+	struct list_head *cap_head;
+};
+
+struct capability {
+	struct list_head list;
+	char spec[256];
+	char spec_ver[32];
+	char uri[256];
+};
+
+static void free_capability_list(struct list_head *cap_list)
+{
+	struct capability *cap = NULL, *tmp = NULL;
+	list_for_each_entry_safe(cap, tmp, cap_list, list) {
+		list_del(&cap->list);
+		dmfree(cap);
+	}
+}
+
+static bool valid_execenv_name(const char *name)
+{
+	/* check if already exist or is a child exec env */
+	struct uci_section *s = NULL, *stmp = NULL;
+
+	uci_foreach_sections_safe("swmodd", "execenv", stmp, s) {
+		char *env_name = NULL;
+		int len;
+
+		dmuci_get_value_by_section_string(s, "name", &env_name);
+		len = DM_STRLEN(env_name);
+
+		if (DM_STRNCMP(env_name, name, len) == 0)
+			return false;
+
+		len = DM_STRLEN(name);
+		if (DM_STRNCMP(name, env_name, len) == 0)
+			return false;
+	}
+
+	return true;
+}
+
 /*************************************************************
 * ENTRY METHOD
 *************************************************************/
-static int browseSoftwareModulesExecEnvInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
+static int browseSoftwareModulesExecEnvClass(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
 {
-	json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
-	char *inst = NULL;
-	int env = 0;
-
-	dmubus_call("swmodules", "ee_list", UBUS_ARGS{0}, 0, &res);
-	dmjson_foreach_obj_in_array(res, arrobj, du_obj, env, 1, "environment") {
-		inst = dmjson_get_value(du_obj, 1, "eeid");
-		if (inst) {
-			if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)du_obj, inst) == DM_STOP)
-				break;
-		}
+	json_object *res = NULL, *cap_obj = NULL, *arrobj = NULL;
+	struct ee_class *class = NULL;
+	int inst = 0;
+	LIST_HEAD(cap_list);
+
+	class = dmcalloc(1, sizeof(struct ee_class));
+	if (!class)
+		return 0;
+
+	memset(class, 0, sizeof(struct ee_class));
+
+	dmubus_call("swmodules", "ee_class", UBUS_ARGS{0}, 0, &res);
+	if (!res)
+		return 0;
+
+	snprintf(class->name, sizeof(class->name), "%s", dmjson_get_value(res, 1, "name"));
+	snprintf(class->vendor, sizeof(class->vendor), "%s", dmjson_get_value(res, 1, "vendor"));
+	snprintf(class->version, sizeof(class->version), "%s", dmjson_get_value(res, 1, "version"));
+
+	dmjson_foreach_obj_in_array(res, arrobj, cap_obj, inst, 1, "capabilities") {
+		struct capability *cap = dmcalloc(1, sizeof(struct capability));
+		if (!cap)
+			break;
+
+		snprintf(cap->spec, sizeof(cap->spec), "%s", dmjson_get_value(cap_obj, 1, "specification"));
+		snprintf(cap->spec_ver, sizeof(cap->spec_ver), "%s", dmjson_get_value(cap_obj, 1, "version"));
+		snprintf(cap->uri, sizeof(cap->uri), "%s", dmjson_get_value(cap_obj, 1, "uri"));
+
+		list_add_tail(&cap->list, &cap_list);
+	}
+
+	class->cap_head = &cap_list;
+
+	struct uci_section *sec = is_dmmap_section_exist("dmmap_swmodd", "execenvclass");
+	if (!sec) {
+		dmuci_add_section_bbfdm("dmmap_swmodd", "execenvclass", &sec);
+		dmuci_set_value_by_section(sec, "class_instance", "1");
 	}
+
+	class->dmmap_sec = sec;
+	handle_instance(dmctx, parent_node, sec, "class_instance", "class_alias");
+	DM_LINK_INST_OBJ(dmctx, parent_node, (void *)class, "1");
+
+	free_capability_list(&cap_list);
+	dmfree(class);
+
 	return 0;
 }
 
-static int browseSoftwareModulesDeploymentUnitInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
+static int browseSoftwareModulesCapability(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
 {
-	json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
+	struct ee_class *class = (struct ee_class *)prev_data;
+	struct capability *cap = NULL, *tmp = NULL;
+	int id = 0;
 	char *inst = NULL;
-	int id = 0, du = 0;
 
-	dmubus_call("swmodules", "du_list", UBUS_ARGS{0}, 0, &res);
-	dmjson_foreach_obj_in_array(res, arrobj, du_obj, du, 1, "deployment_unit") {
+	if (!class)
+		return 0;
+
+	list_for_each_entry_safe(cap, tmp, class->cap_head, list) {
 		inst = handle_instance_without_section(dmctx, parent_node, ++id);
-		if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)du_obj, inst) == DM_STOP)
+		if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)cap, inst) == DM_STOP)
 			break;
 	}
+
 	return 0;
 }
 
-static int browseSoftwareModulesExecutionUnitInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
+static int browseSoftwareModulesExecEnvInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
 {
-	json_object *res = NULL, *eu_obj = NULL, *arrobj = NULL;
+	struct uci_section *s;
 	char *inst = NULL;
-	int id = 0, eu = 0;
 
-	dmubus_call("swmodules", "eu_list", UBUS_ARGS{0}, 0, &res);
-	dmjson_foreach_obj_in_array(res, arrobj, eu_obj, eu, 1, "execution_unit") {
-		inst = handle_instance_without_section(dmctx, parent_node, ++id);
-		if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)eu_obj, inst) == DM_STOP)
+	uci_foreach_sections("swmodd", "execenv", s) {
+		inst = handle_instance(dmctx, parent_node, s, "ee_instance", "ee_alias");
+
+		if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)s, inst) == DM_STOP)
 			break;
 	}
+
 	return 0;
 }
 
-/*************************************************************
-* LINKER FUNCTIONS
-*************************************************************/
-static int get_linker_eu(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker)
+static int browseSoftwareModulesDeploymentUnitInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
 {
-	char *ee_name = NULL, *eu_name = NULL;
-
-	ee_name = dmjson_get_value((json_object *)data, 1, "ee_name");
-	eu_name = dmjson_get_value((json_object *)data, 1, "eu_name");
-	if (ee_name == NULL)
-		ee_name = "";
+	struct uci_section *s;
+	char *inst = NULL;
 
-	if (eu_name == NULL)
-		eu_name = "";
+	uci_foreach_sections("swmodd", "du_eu_assoc", s) {
+		inst = handle_instance(dmctx, parent_node, s, "du_instance", "du_alias");
 
-	dmasprintf(linker, "%.32s%.32s", ee_name, eu_name);
+		if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)s, inst) == DM_STOP)
+			break;
+	}
 
 	return 0;
 }
 
 /*************************************************************
-* COMMON FUNCTIONS
-**************************************************************/
-#if 0
-static int get_SoftwareModules_VendorConfigList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+* LINKER FUNCTIONS
+*************************************************************/
+static int get_linker_execenv(char *refparam, struct dmctx *ctx, void *data, char *instance, char **linker)
 {
-	struct uci_section *s = NULL;
-	dmasprintf(value, "");
-
-	char *config = dmjson_get_value((json_object *)data, 1, "config");
-	if (config == NULL || *config == '\0')
-		return 0;
+	char *value = NULL;
 
-	uci_path_foreach_sections(bbfdm, DMMAP, "vcf", s) {
-		char *name = NULL;
+	dmuci_get_value_by_section_string((struct uci_section *)data, "name", &value);
+	*linker = dmstrdup(value);
 
-		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;
 }
-#endif
+
+/*************************************************************
+* COMMON FUNCTIONS
+**************************************************************/
 
 /*************************************************************
 * GET & SET PARAM
 *************************************************************/
+static int get_SoftwareModules_ExecEnvClassNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	unsigned int cnt = get_number_of_entries(ctx, data, instance, browseSoftwareModulesExecEnvClass);
+	dmasprintf(value, "%u", cnt);
+
+	return 0;
+}
+
 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;
+	unsigned int cnt = get_number_of_entries(ctx, data, instance, browseSoftwareModulesExecEnvInst);
+	dmasprintf(value, "%u", cnt);
 
-	dmubus_call("swmodules", "ee_list", UBUS_ARGS{0}, 0, &res);
-	DM_ASSERT(res, dmasprintf(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;
+	unsigned int cnt = get_number_of_entries(ctx, data, instance, browseSoftwareModulesDeploymentUnitInst);
+	dmasprintf(value, "%u", cnt);
 
-	dmubus_call("swmodules", "du_list", UBUS_ARGS{0}, 0, &res);
-	DM_ASSERT(res, dmasprintf(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)
+static int get_SoftwareModules_CapabilityNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	json_object *res = NULL, *execution_unit = NULL;
-	size_t nbre_env = 0;
+	unsigned int cnt = get_number_of_entries(ctx, data, instance, browseSoftwareModulesCapability);
+	dmasprintf(value, "%u", cnt);
 
-	dmubus_call("swmodules", "eu_list", UBUS_ARGS{0}, 0, &res);
-	DM_ASSERT(res, dmasprintf(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].autoboot*/
-static int get_SoftwareModulesExecEnv_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int get_SoftwareModulesExecEnvClass_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	return bbf_get_alias(ctx, ((struct ee_class *)data)->dmmap_sec, "class_alias", instance, value);
+}
+
+static int set_SoftwareModulesExecEnvClass_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+	return bbf_set_alias(ctx, ((struct ee_class *)data)->dmmap_sec, "class_alias", instance, value);
+}
+
+static int get_SoftwareModulesExecEnvClass_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "autoboot");
+	struct ee_class *class = (struct ee_class *)data;
+	if (!class)
+		return 0;
+
+	*value = dmstrdup(class->name);
 	return 0;
 }
 
-static int set_SoftwareModulesExecEnv_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+static int get_SoftwareModulesExecEnvClass_Vendor(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	char *env_name = NULL;
+	struct ee_class *class = (struct ee_class *)data;
+	if (!class)
+		return 0;
 
-	switch (action)	{
-		case VALUECHECK:
-			if (bbfdm_validate_boolean(ctx, value))
-				return FAULT_9007;
-			break;
-		case VALUESET:
-			env_name = dmjson_get_value((json_object *)data, 1, "ee_name");
+	*value = dmstrdup(class->vendor);
+	return 0;
+}
 
-			dmubus_call_set("swmodules", "set_config", UBUS_ARGS{
-				{"ee_name", env_name, String},
-				{"parameter", "ee_enable", String},
-				{"value", value, String}},
-				3);
-			break;
-	}
+static int get_SoftwareModulesExecEnvClass_Version(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	struct ee_class *class = (struct ee_class *)data;
+	if (!class)
+		return 0;
+
+	*value = dmstrdup(class->version);
 	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)
+static int get_SoftwareModulesExecEnvClass_DURef(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)
+static int get_CapabilitySpecification(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	dmasprintf(value, "0");
+	struct capability *cap = (struct capability *)data;
+	if (!cap)
+		return 0;
+
+	*value = dmstrdup(cap->spec);
 	return 0;
 }
 
-static int set_SoftwareModulesExecEnv_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+static int get_CapabilitySpecificationVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
+	struct capability *cap = (struct capability *)data;
+	if (!cap)
+		return 0;
+
+	*value = dmstrdup(cap->spec_ver);
 	return 0;
 }
 
-static int get_SoftwareModulesExecEnv_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int get_CapabilitySpecificationURI(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	char *alias = dmjson_get_value((json_object *)data, 1, "ee_alias");
+	struct capability *cap = (struct capability *)data;
+	if (!cap)
+		return 0;
 
-	if (DM_STRLEN(alias) == 0)
-		dmasprintf(value, "cpe-%s", instance);
-	else
-		dmasprintf(value, "%s", alias);
+	*value = dmstrdup(cap->uri);
+	return 0;
+}
 
+static int get_SoftwareModulesExecEnv_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	dmuci_get_value_by_section_string((struct uci_section *)data, "enable", value);
 	return 0;
 }
 
-static int set_SoftwareModulesExecEnv_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+static int set_SoftwareModulesExecEnv_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	char *ee_name = NULL;
+	bool val;
+	char *ee_action = NULL;
 
 	switch (action)	{
 		case VALUECHECK:
-			if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL))
+			if (bbfdm_validate_boolean(ctx, value))
 				return FAULT_9007;
 			break;
 		case VALUESET:
-			ee_name = dmjson_get_value((json_object *)data, 1, "ee_name");
-
-			if (DM_STRLEN(ee_name) == 0)
-				return 0;
+			dmuci_get_value_by_section_string((struct uci_section *)data, "action", &ee_action);
+			if (DM_STRLEN(ee_action) != 0) {
+				bbfdm_set_fault_message(ctx, "Execution Environment is busy. Try after sometime.");
+				return FAULT_9001;
+			}
 
-			dmubus_call_set("swmodules", "set_config", UBUS_ARGS{
-					{"ee_name", ee_name, String},
-					{"parameter", "ee_alias", String},
-					{"value", value, String}},
-					3);
+			string_to_bool(value, &val);
 
+			dmuci_set_value_by_section((struct uci_section *)data, "enable", val ? "1" : "0");
+			dmuci_set_value_by_section((struct uci_section *)data, "action", val ? "enable" : "disable");
 			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)
+static int get_SoftwareModulesExecEnv_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "ee_name");
+	char *val = NULL;
+	dmuci_get_value_by_section_string((struct uci_section *)data, "status", &val);
+	if (DM_STRLEN(val) != 0) {
+		*value = dmstrdup(val);
+		return 0;
+	}
+
+	dmuci_get_value_by_section_string((struct uci_section *)data, "action", &val);
+	if (DM_STRCMP(val, "restart") == 0) {
+		*value = dmstrdup("Restarting");
+		return 0;
+	}
+
+	dmuci_get_value_by_section_string((struct uci_section *)data, "enable", &val);
+	if (val[0] == '1')
+		*value = dmstrdup("Up");
+	else
+		*value = dmstrdup("Disabled");
+
 	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)
+static int get_SoftwareModulesExecEnv_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "type");
-	return 0;
+	return bbf_get_alias(ctx, (struct uci_section *)data, "ee_alias", instance, value);
 }
 
-static int get_SoftwareModulesExecEnv_InitialRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int set_SoftwareModulesExecEnv_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	dmasprintf(value, "0");
+	return bbf_set_alias(ctx, (struct uci_section *)data, "ee_alias", instance, value);
+}
+
+static int get_SoftwareModulesExecEnv_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	dmuci_get_value_by_section_string((struct uci_section *)data, "name", value);
 	return 0;
 }
 
-static int set_SoftwareModulesExecEnv_InitialRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+static int get_SoftwareModulesExecEnv_Type(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
 	return 0;
 }
 
-static int get_SoftwareModulesExecEnv_RequestedRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int get_SoftwareModulesExecEnv_InitialRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	dmasprintf(value, "-1");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "initial_runlevel", value);
 	return 0;
 }
 
-static int set_SoftwareModulesExecEnv_RequestedRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+static int set_SoftwareModulesExecEnv_InitialRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
+	switch (action)	{
+		case VALUECHECK:
+			if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1))
+				return FAULT_9007;
+			break;
+		case VALUESET:
+			dmuci_set_value_by_section((struct uci_section *)data, "initial_runlevel", value);
+			break;
+	}
 	return 0;
 }
 
 static int get_SoftwareModulesExecEnv_CurrentRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	dmasprintf(value, "-1");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "current_runlevel", value);
 	return 0;
 }
 
 static int get_SoftwareModulesExecEnv_InitialExecutionUnitRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	dmasprintf(value, "-1");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "initial_eu_runlevel", value);
 	return 0;
 }
 
 static int set_SoftwareModulesExecEnv_InitialExecutionUnitRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
+	switch (action)	{
+		case VALUECHECK:
+			if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"0","65535"}}, 1))
+				return FAULT_9007;
+			break;
+		case VALUESET:
+			dmuci_set_value_by_section((struct uci_section *)data, "initial_eu_runlevel", value);
+			break;
+	}
 	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 *eid = dmjson_get_value((json_object *)data, 1, "parent_ee_ref");
-	if (eid == NULL || strcmp(eid, "0") == 0) {
-		dmasprintf(value, "");
-	} else {
-		dmasprintf(value, "Device.SoftwareModules.ExecEnv.%s", eid);
-	}
-
 	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)
+static int get_SoftwareModulesExecEnv_RestartReason(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "allocated_disk_space");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "restart_reason", value);
 	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)
+static int get_SoftwareModulesExecEnv_RestartCount(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "available_disk_space");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "restart_count", value);
 	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)
+static int get_SoftwareModulesExecEnv_LastRestarted(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "allocated_memory");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "last_restarted", value);
 	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)
+static int get_SoftwareModulesExecEnv_CreatedAt(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "available_memory");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "created_at", value);
 	return 0;
 }
 
-int get_SoftwareModulesExecEnv_ActiveExecutionUnits(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int get_SoftwareModulesExecEnv_ExecEnvClassRef(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	json_object *res = NULL, *du_obj = NULL, *arrobj = NULL;
-	char eu_list[2048];
-	unsigned pos = 0;
-	int eu = 0;
-
-	eu_list[0] = 0;
-	char *curr_env = dmjson_get_value((json_object *)data, 1, "ee_name");
-	dmubus_call("swmodules", "eu_list", UBUS_ARGS{0}, 0, &res);
-	DM_ASSERT(res, dmasprintf(value, ""));
-	dmjson_foreach_obj_in_array(res, arrobj, du_obj, eu, 1, "execution_unit") {
-		char *environment = dmjson_get_value(du_obj, 1, "ee_name");
-
-		if (strcmp(environment, curr_env) == 0)
-			pos += snprintf(&eu_list[pos], sizeof(eu_list) - pos, "Device.SoftwareModules.ExecutionUnit.%d,", eu+1);
-	}
-
-	if (pos)
-		eu_list[pos - 1] = 0;
-
-	*value = dmstrdup(eu_list);
+	*value = "Device.SoftwareModules.ExecEnvClass.1";
 	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");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "uuid", value);
 	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");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "duid", value);
 	return 0;
 }
 
 static int get_SoftwareModulesDeploymentUnit_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	char *alias = dmjson_get_value((json_object *)data, 1, "du_alias");
-
-	if (DM_STRLEN(alias) == 0)
-		dmasprintf(value, "cpe-%s", instance);
-	else
-		dmasprintf(value, "%s", alias);
-
-	return 0;
+	return bbf_get_alias(ctx, (struct uci_section *)data, "du_alias", instance, value);
 }
 
 static int set_SoftwareModulesDeploymentUnit_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	char *ee_name = NULL, *uuid = NULL;
-
-	switch (action)	{
-		case VALUECHECK:
-			if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL))
-				return FAULT_9007;
-			break;
-		case VALUESET:
-			ee_name = dmjson_get_value((json_object *)data, 1, "ee_name");
-			uuid = dmjson_get_value((json_object *)data, 1, "uuid");
-
-			if (DM_STRLEN(ee_name) == 0 || DM_STRLEN(uuid) == 0)
-				return 0;
-
-			dmubus_call_set("swmodules", "set_config", UBUS_ARGS{
-					{"ee_name", ee_name, String},
-					{"uuid", uuid, String},
-					{"parameter", "du_alias", String},
-					{"value", value, String}},
-					4);
-
-			break;
-	}
-	return 0;
-}
-
-static int set_SoftwareModulesExecutionUnit_RequestedState(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
-{
-	char *eid = NULL, *name = NULL;
-
-	switch (action)	{
-		case VALUECHECK:
-			if (strcmp(value, "Idle") != 0 && strcmp(value, "Active") != 0)
-				return FAULT_9007;
-			break;
-		case VALUESET:
-			eid = dmjson_get_value((json_object *)data, 1, "eeid");
-			name = dmjson_get_value((json_object *)data, 1, "eu_name");
-
-			if (eid == NULL || name == NULL) {
-				return 0;
-			}
-
-			if (eid[0] == '\0' || name[0] == '\0') {
-				return 0;
-			}
-
-			dmubus_call_set("swmodules", "set_config", UBUS_ARGS{
-					{"eeid", eid, Integer},
-					{"eu_name", name, String},
-					{"parameter", "eu_requested_state", String},
-					{"value", value, String}},
-					4);
-
-			break;
-	}
-
-	return 0;
+	return bbf_set_alias(ctx, (struct uci_section *)data, "du_alias", instance, value);
 }
 
-/*#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, "du_name");
+	*value = dmstrdup(section_name((struct uci_section *)data));
 	return 0;
 }
 
 static int get_SoftwareModulesDeploymentUnit_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	char *val = dmjson_get_value((json_object *)data, 1, "du_status");
-	if (val) {
-		char *tmp = strchr(val, '_');
-		if (tmp)
-			*tmp = '\0';
-
-		dmasprintf(value, val);
-	} else {
-		dmasprintf(value, "");
-	}
-
+	dmuci_get_value_by_section_string((struct uci_section *)data, "status", value);
 	return 0;
 }
 
 static int get_SoftwareModulesDeploymentUnit_Resolved(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	char *val = dmjson_get_value((json_object *)data, 1, "du_status");
+	char *val = NULL;
+
+	dmuci_get_value_by_section_string((struct uci_section *)data, "status", &val);
 	if (DM_STRCMP(val, "Installed") == 0)
 		dmasprintf(value, "1");
 	else
@@ -496,325 +509,214 @@ static int get_SoftwareModulesDeploymentUnit_Resolved(char *refparam, struct dmc
 	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");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "url", value);
 	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");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "description", value);
 	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");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "vendor", value);
 	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");
+	dmuci_get_value_by_section_string((struct uci_section *)data, "version", value);
 	return 0;
 }
 
 static int get_SoftwareModulesDeploymentUnit_VendorLogList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	dmasprintf(value, "");
 	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)
 {
-	dmasprintf(value, "");
 	return 0;
 }
 
 static int get_SoftwareModulesDeploymentUnit_ExecutionUnitList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	char eu_label[65] = {0};
-
-	char *ee = dmjson_get_value((json_object *)data, 1, "ee_name");
-	char *eu = dmjson_get_value((json_object *)data, 1, "eu_name");
-
-	snprintf(eu_label, sizeof(eu_label), "%.32s%.32s", ee ? ee : "", eu ? eu : "");
-
-	char *linker = NULL;
-	adm_entry_get_linker_param(ctx, "Device.SoftwareModules.ExecutionUnit.", eu_label, &linker);
-	if (DM_STRLEN(linker) != 0)
-		dmasprintf(value, "%s", linker);
-
 	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 *eid = dmjson_get_value((json_object *)data, 1, "eeid");
+	char *execenv = NULL;
 
-	dmasprintf(value, "Device.SoftwareModules.ExecEnv.%s", eid);
-	return 0;
-}
+	dmuci_get_value_by_section_string((struct uci_section *)data, "execenv", &execenv);
+	adm_entry_get_linker_param(ctx, "Device.SoftwareModules.ExecEnv.", execenv, value);
 
-/*#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)
+static int get_SoftwareModulesDeploymentUnit_Installed(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	char *alias = dmjson_get_value((json_object *)data, 1, "eu_alias");
-
-	if (DM_STRLEN(alias) == 0)
-		dmasprintf(value, "cpe-%s", instance);
-	else
-		dmasprintf(value, "%s", alias);
-
+	dmuci_get_value_by_section_string((struct uci_section *)data, "installed_at", value);
 	return 0;
 }
 
-static int set_SoftwareModulesExecutionUnit_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
-{
-	char *eu_name = NULL, *eu_env = NULL;
-
-	switch (action)	{
-		case VALUECHECK:
-			if (bbfdm_validate_string(ctx, value, -1, 64, NULL, NULL))
-				return FAULT_9007;
-			break;
-		case VALUESET:
-			eu_name = dmjson_get_value((json_object *)data, 1, "eu_name");
-			eu_env = dmjson_get_value((json_object *)data, 1, "ee_name");
-
-			if (DM_STRLEN(eu_name) == 0 || DM_STRLEN(eu_env) == 0)
-				return 0;
-
-			dmubus_call_set("swmodules", "set_config", UBUS_ARGS{
-					{"ee_name", eu_env, String},
-					{"eu_name", eu_name, String},
-					{"parameter", "eu_alias", String},
-					{"value", value, String}},
-					4);
-
-			break;
+/*************************************************************
+ * OPERATE COMMANDS
+ *************************************************************/
+static operation_args softwaremodules_add_execenv_args = {
+	.in = (const char *[]) {
+		"Alias",
+		"Name",
+		"ParentExecEnv",
+		"Enable",
+		"AllocatedDiskSpace",
+		NULL
 	}
+};
+
+static int get_operate_args_SoftwareModules_AddExecEnv(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	*value = (char *)&softwaremodules_add_execenv_args;
 	return 0;
 }
 
-static int set_SoftwareModulesExecutionUnit_AutoStart(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+static int operate_SoftwareModules_AddExecEnv(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	char *eeid = NULL, *eu_name = NULL;
-
-	switch (action)	{
-		case VALUECHECK:
-			if (bbfdm_validate_boolean(ctx, value))
-				return FAULT_9007;
-			break;
-		case VALUESET:
-			eeid = dmjson_get_value((json_object *)data, 1, "eeid");
-			eu_name = dmjson_get_value((json_object *)data, 1, "eu_name");
+	struct uci_section *s = NULL;
+	char *name, *alias, *enable, *disk_space;
+	int len;
+	time_t now;
+	char ctime[32] = {0};
+	bool ee_enable;
+
+	name = dmjson_get_value((json_object *)value, 1, "Name");
+	if (name[0] == '\0')
+		return USP_FAULT_INVALID_ARGUMENT;
 
-			if (eu_name == NULL || eeid == NULL) {
-				return 0;
-			}
+	alias = dmjson_get_value((json_object *)value, 1, "Alias");
+	enable = dmjson_get_value((json_object *)value, 1, "Enable");
+	disk_space = dmjson_get_value((json_object *)value, 1, "AllocatedDiskSpace");
 
-			if (eu_name[0] == '\0' || eeid[0] == '\0') {
-				return 0;
-			}
+	len = DM_STRLEN(name);
+	if (name[len-1] == '/')
+		name[len-1] = '0';
 
-			dmubus_call_set("swmodules", "set_config", UBUS_ARGS{
-					{"eeid", eeid, Integer},
-					{"eu_name", eu_name, String},
-					{"parameter", "eu_autostart", String},
-					{"value", value, String}},
-					4);
+	/* check if duplicate env or a nested env */
+	if (!valid_execenv_name(name))
+		return USP_FAULT_INVALID_ARGUMENT;
 
-			break;
-	}
+	dmuci_add_section("swmodd", "execenv", &s);
+	if (!s)
+		return USP_FAULT_INTERNAL_ERROR;
 
-	return 0;
-}
+	dmuci_rename_section_by_section(s, section_name(s));
 
-/*#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, "eu_name");
-	return 0;
-}
+	string_to_bool(enable, &ee_enable);
+	now = time(NULL);
+	strftime(ctime, sizeof(ctime), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
 
-/*#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)
-{
-	char *ee_name = NULL, *eu_name = NULL;
+	dmuci_set_value_by_section(s, "name", name);
+	dmuci_set_value_by_section(s, "ee_alias", alias);
+	dmuci_set_value_by_section(s, "enable", ee_enable ? "1" : "0");
+	dmuci_set_value_by_section(s, "action", "add");
+	dmuci_set_value_by_section(s, "disk_space", disk_space);
+	dmuci_set_value_by_section(s, "initial_runlevel", "65535");
+	dmuci_set_value_by_section(s, "current_runlevel", "-1");
+	dmuci_set_value_by_section(s, "initial_eu_runlevel", "0");
+	dmuci_set_value_by_section(s, "restart_count", "0");
+	dmuci_set_value_by_section(s, "created_at", ctime);
+	dmuci_set_value_by_section(s, "last_restarted", "0001-01-01T00:00:00Z");
 
-	ee_name = dmjson_get_value((json_object *)data, 1, "ee_name");
-	eu_name = dmjson_get_value((json_object *)data, 1, "eu_name");
-	if (ee_name == NULL)
-		ee_name = "";
-
-	if (eu_name == NULL)
-		eu_name = "";
+	dmubus_call_set("uci", "commit", UBUS_ARGS{{"config", "swmodd", String}}, 1);
 
-	dmasprintf(value, "%.32s%.32s", ee_name, eu_name);
 	return 0;
 }
 
-static int get_SoftwareModulesExecutionUnit_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
-{
-	*value = dmjson_get_value((json_object *)data, 1, "state");
-	return 0;
-}
+static operation_args softwaremodules_set_runlevel_args = {
+	.in = (const char *[]) {
+		"RequestedRunLevel",
+		NULL
+	}
+};
 
-static int get_SoftwareModulesExecutionUnit_ExecutionFaultCode(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int get_operate_args_SoftwareModules_SetRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "fault_code");
+	*value = (char *)&softwaremodules_set_runlevel_args;
 	return 0;
 }
 
-static int get_SoftwareModulesExecutionUnit_ExecutionFaultMessage(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int operate_SoftwareModulesExecEnv_SetRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	char *fault = dmjson_get_value((json_object *)data, 1, "fault_code");
-	if (DM_STRCMP(fault, "FailureOnStart") == 0)
-		dmasprintf(value, "Failed to start the OCI based Execution Unit");
-	else
-		dmasprintf(value, "");
+	char *run_level = dmjson_get_value((json_object *)value, 1, "RequestedRunLevel");
 
-	return 0;
-}
+	if (bbfdm_validate_int(ctx, run_level, RANGE_ARGS{{"-1","65535"}}, 1))
+		return USP_FAULT_INVALID_ARGUMENT;
 
-static int get_SoftwareModulesExecutionUnit_AutoStart(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
-{
-	*value = dmjson_get_value((json_object *)data, 1, "autostart");
-	return 0;
-}
+	dmuci_set_value_by_section((struct uci_section *)data, "current_runlevel", run_level);
 
-static int get_SoftwareModulesExecutionUnit_RunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
-{
-	dmasprintf(value, "-1");
-	return 0;
-}
+	dmuci_commit_package("swmodd");
 
-static int set_SoftwareModulesExecutionUnit_RunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
-{
 	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;
-}
+static operation_args softwaremodules_restart_args = {
+	.in = (const char *[]) {
+		"Reason",
+		"Force",
+		NULL
+	}
+};
 
-/*#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)
+static int get_operate_args_SoftwareModules_Restart(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "version");
+	*value = (char *)&softwaremodules_restart_args;
 	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)
+static int operate_SoftwareModulesExecEnv_Restart(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	*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;
-}
+static operation_args softwaremodules_remove_args = {
+	.in = (const char *[]) {
+		"Force",
+		NULL
+	}
+};
 
-/*#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)
+static int get_operate_args_SoftwareModules_Remove(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
-	*value = dmjson_get_value((json_object *)data, 1, "memory_space");
+	*value = (char *)&softwaremodules_remove_args;
 	return 0;
 }
 
-int get_SoftwareModulesExecutionUnit_References(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int operate_SoftwareModulesExecEnv_Remove(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	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, "eu_name");
-	char *curr_environment = dmjson_get_value((json_object *)data, 1, "ee_name");
+	char *ee_action = NULL;
+	char *val = NULL;
+	bool force;
 
-	dmubus_call("swmodules", "du_list", UBUS_ARGS{0}, 0, &res);
-	DM_ASSERT(res, dmasprintf(value, ""));
-	dmjson_foreach_obj_in_array(res, arrobj, du_obj, du, 1, "deployment_unit") {
-		name = dmjson_get_value(du_obj, 1, "du_name");
-		environment = dmjson_get_value(du_obj, 1, "ee_name");
-		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;
-		}
+	dmuci_get_value_by_section_string((struct uci_section *)data, "action", &ee_action);
+	if (DM_STRLEN(ee_action) != 0) {
+		bbfdm_set_fault_message(ctx, "Execution Environment is busy. Try after sometime.");
+		return USP_FAULT_REQUEST_DENIED;
 	}
-	return 0;
-}
 
-static int get_SoftwareModulesExecutionUnit_AssociatedProcessList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
-{
-	char *euid = dmjson_get_value((json_object *)data, 1, "euid");
+	val = dmjson_get_value((json_object *)value, 1, "Force");
+	string_to_bool(val, &force);
 
-	if (DM_STRLEN(euid) == 0 || DM_STRCMP(euid, "Unknown") == 0)
-		return 0;
+	dmuci_set_value_by_section((struct uci_section *)data, "action", force ? "force_remove" : "remove");
 
-	char *linker = NULL;
-	adm_entry_get_linker_param(ctx, "Device.DeviceInfo.ProcessStatus.", euid, &linker);
-	if (DM_STRLEN(linker) != 0)
-		dmasprintf(value, "%s", linker);
-
-	return 0;
-}
-
-static int get_SoftwareModulesExecutionUnit_VendorLogList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
-{
-	dmasprintf(value, "");
-	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)
-{
-	dmasprintf(value, "");
-	return 0;
-}
-
-/*#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 *eid = dmjson_get_value((json_object *)data, 1, "eeid");
+	dmubus_call_set("uci", "commit", UBUS_ARGS{{"config", "swmodd", String}}, 1);
 
-	dmasprintf(value, "Device.SoftwareModules.ExecEnv.%s", eid);
 	return 0;
 }
 
-/*************************************************************
- * OPERATE COMMANDS
- *************************************************************/
-static int operate_SoftwareModulesExecEnv_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
-{
-	return USP_FAULT_COMMAND_FAILURE;
-}
-
-static int operate_SoftwareModulesExecEnv_SetRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
-{
-	return USP_FAULT_COMMAND_FAILURE;
-}
-
 static operation_args softwaremodules_installdu_args = {
 	.in = (const char *[]) {
 		"URL",
@@ -822,6 +724,7 @@ static operation_args softwaremodules_installdu_args = {
 		"Username",
 		"Password",
 		"ExecutionEnvRef",
+		"AutoRestart.Enable",
 		NULL
 	}
 };
@@ -834,8 +737,8 @@ static int get_operate_args_SoftwareModules_InstallDU(char *refparam, struct dmc
 
 static int operate_SoftwareModules_InstallDU(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	unsigned int eeid = 0;
-	json_object *res = NULL;
+	char *env = "";
+	char *autostart = "false";
 
 	char *url = dmjson_get_value((json_object *)value, 1, "URL");
 	if (url[0] == '\0')
@@ -845,29 +748,33 @@ static int operate_SoftwareModules_InstallDU(char *refparam, struct dmctx *ctx,
 	char *username = dmjson_get_value((json_object *)value, 1, "Username");
 	char *password = dmjson_get_value((json_object *)value, 1, "Password");
 	char *environment = dmjson_get_value((json_object *)value, 1, "ExecutionEnvRef");
-	if (DM_STRLEN(environment) == 0) {
-		eeid = 1;
-	} else {
-		sscanf(environment, "Device.SoftwareModules.ExecEnv.%u", &eeid);
-	}
 
-	if (eeid == 0)
-		return USP_FAULT_COMMAND_FAILURE;
+	if (DM_STRLEN(environment) != 0)
+		adm_entry_get_linker_value(ctx, environment, &env);
 
-	char eeid_str[16] = {0};
-	snprintf(eeid_str, sizeof(eeid_str), "%u", eeid);
+	autostart = dmjson_get_value((json_object *)value, 1, "AutoRestart.Enable");
 
-	dmubus_call("swmodules", "du_install", UBUS_ARGS{
+	dmubus_call_set("swmodules", "du_install", UBUS_ARGS{
 			{"url", url, String},
 			{"uuid", uuid, String},
 			{"username", username, String},
 			{"password", password, String},
-			{"eeid", eeid_str, Integer}},
-			5,
-			&res);
+			{"execenv", env, String},
+			{"autorestart", autostart, Boolean}},
+			6);
 
-	char *status = dmjson_get_value(res, 1, "status");
-	return (strcmp(status, "true") == 0) ? 0 : USP_FAULT_COMMAND_FAILURE;
+	return 0;
+}
+
+#if 0
+static int operate_SoftwareModulesExecEnv_Reset(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+	return USP_FAULT_COMMAND_FAILURE;
+}
+
+static int operate_SoftwareModulesExecEnv_SetRunLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+	return USP_FAULT_COMMAND_FAILURE;
 }
 
 static operation_args softwaremodulesdeploymentunit_update_args = {
@@ -1002,6 +909,21 @@ static int get_event_DUStateChagne(char *refparam, struct dmctx *ctx, void *data
 	*value = (char *)&du_state_change_args;
 	return 0;
 }
+#endif
+
+static event_args ee_restarted_args = {
+	.param = (const char *[]) {
+		"RestartTime",
+		"RestartReason",
+		NULL
+	}
+};
+
+static int get_event_ExecEnvRestarted(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	*value = (char *)&ee_restarted_args;
+	return 0;
+}
 
 /**********************************************************************************************************************************
 *                                            OBJ & PARAM DEFINITION
@@ -1016,50 +938,78 @@ DMOBJ tSWmodObj[] = {
 /* *** 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, NULL, BBFDM_BOTH, LIST_KEY{"Alias", "Name", NULL}},
+{"ExecEnvClass", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecEnvClass, NULL, NULL, tCapabilityObj, tSoftwareModulesExecEnvClassParams, NULL, BBFDM_BOTH, LIST_KEY{"Alias", NULL}},
+{"ExecEnv", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecEnvInst, NULL, NULL, NULL, tSoftwareModulesExecEnvParams, get_linker_execenv, BBFDM_BOTH, LIST_KEY{"Alias", "Name", NULL}},
 {"DeploymentUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesDeploymentUnitInst, NULL, NULL, NULL, tSoftwareModulesDeploymentUnitParams, NULL, BBFDM_BOTH, LIST_KEY{"UUID", "Version", "ExecutionEnvRef", "Alias", NULL}},
-{"ExecutionUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecutionUnitInst, NULL, NULL, NULL, tSoftwareModulesExecutionUnitParams, get_linker_eu, BBFDM_BOTH, LIST_KEY{"EUID", "Alias", NULL}},
+{0}
+};
+
+DMOBJ tCapabilityObj[] = {
+/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
+{"Capability", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesCapability, NULL, NULL, NULL, tSoftwareModulesCapabilityParams, NULL, BBFDM_BOTH, LIST_KEY{"Alias", NULL}},
+{0}
+};
+
+DMLEAF tSoftwareModulesExecEnvClassParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
+{"Alias", &DMWRITE, DMT_STRING, get_SoftwareModulesExecEnvClass_Alias, set_SoftwareModulesExecEnvClass_Alias, BBFDM_BOTH},
+{"Name", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnvClass_Name, NULL, BBFDM_BOTH},
+{"Vendor", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnvClass_Vendor, NULL, BBFDM_BOTH},
+{"Version", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnvClass_Version, NULL, BBFDM_BOTH},
+{"DeploymentUnitRef", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnvClass_DURef, NULL, BBFDM_BOTH},
+{"CapabilityNumberOfEntries", &DMREAD, DMT_UNINT, get_SoftwareModules_CapabilityNumberOfEntries, NULL, BBFDM_BOTH},
+{"AddExecEnv()", &DMSYNC, DMT_COMMAND, get_operate_args_SoftwareModules_AddExecEnv, operate_SoftwareModules_AddExecEnv, BBFDM_USP},
 {0}
 };
 
 DMLEAF tSoftwareModulesParams[] = {
 /* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
+{"ExecEnvClassNumberOfEntries", &DMREAD, DMT_UNINT, get_SoftwareModules_ExecEnvClassNumberOfEntries, NULL, BBFDM_BOTH},
 {"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},
 {"InstallDU()", &DMASYNC, DMT_COMMAND, get_operate_args_SoftwareModules_InstallDU, operate_SoftwareModules_InstallDU, BBFDM_USP},
-{"DUStateChange!", &DMREAD, DMT_EVENT, get_event_DUStateChagne, NULL, BBFDM_USP},
 {0}
 };
 
-/* *** Device.SoftwareModules.ExecEnv.{i}. *** */
+DMLEAF tSoftwareModulesCapabilityParams[] = {
+/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
+{"Specification", &DMREAD, DMT_STRING, get_CapabilitySpecification, NULL, BBFDM_BOTH},
+{"SpecificationVersion", &DMREAD, DMT_STRING, get_CapabilitySpecificationVersion, NULL, BBFDM_BOTH},
+{"SpecificationURI", &DMREAD, DMT_STRING, get_CapabilitySpecificationURI, NULL, BBFDM_BOTH},
+{0}
+};
+
 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},
+{"RestartReason", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_RestartReason, NULL, BBFDM_BOTH},
+{"RestartCount", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_RestartCount, NULL, BBFDM_BOTH},
+{"LastRestarted", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_LastRestarted, 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},
-{"Reset()", &DMSYNC, DMT_COMMAND, NULL, operate_SoftwareModulesExecEnv_Reset, BBFDM_USP},
-{"SetRunLevel()", &DMSYNC, DMT_COMMAND, NULL, operate_SoftwareModulesExecEnv_SetRunLevel, BBFDM_USP},
+{"CreatedAt", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_CreatedAt, NULL, BBFDM_BOTH},
+{"ExecEnvClassRef", &DMREAD, DMT_STRING, get_SoftwareModulesExecEnv_ExecEnvClassRef, NULL, BBFDM_BOTH},
+{"SetRunLevel()", &DMSYNC, DMT_COMMAND, get_operate_args_SoftwareModules_SetRunLevel, operate_SoftwareModulesExecEnv_SetRunLevel, BBFDM_USP},
+{"Restart()", &DMASYNC, DMT_COMMAND, get_operate_args_SoftwareModules_Restart, operate_SoftwareModulesExecEnv_Restart, BBFDM_USP},
+{"Remove()", &DMSYNC, DMT_COMMAND, get_operate_args_SoftwareModules_Remove, operate_SoftwareModulesExecEnv_Remove, BBFDM_USP},
+{"Restarted!", &DMREAD, DMT_EVENT, get_event_ExecEnvRestarted, NULL, BBFDM_USP},
 {0}
 };
 
-/* *** Device.SoftwareModules.DeploymentUnit.{i}. *** */
 DMLEAF tSoftwareModulesDeploymentUnitParams[] = {
 /* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
 {"UUID", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_UUID, NULL, BBFDM_BOTH},
@@ -1076,34 +1026,8 @@ DMLEAF tSoftwareModulesDeploymentUnitParams[] = {
 {"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},
+{"Installed", &DMREAD, DMT_STRING, get_SoftwareModulesDeploymentUnit_Installed, NULL, BBFDM_BOTH},
 //{"Update()", &DMASYNC, DMT_COMMAND, get_operate_args_SoftwareModulesDeploymentUnit_Update, operate_SoftwareModulesDeploymentUnit_Update, BBFDM_USP},
-{"Uninstall()", &DMASYNC, DMT_COMMAND, NULL, operate_SoftwareModulesDeploymentUnit_Uninstall, BBFDM_USP},
-{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_empty, 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},
-{"SetRequestedState()", &DMSYNC, DMT_COMMAND, get_operate_args_SoftwareModulesExecutionUnit_SetRequestedState, operate_SoftwareModulesExecutionUnit_SetRequestedState, BBFDM_USP},
+//{"Uninstall()", &DMASYNC, DMT_COMMAND, NULL, operate_SoftwareModulesDeploymentUnit_Uninstall, BBFDM_USP},
 {0}
 };
diff --git a/src/datamodel.h b/src/datamodel.h
index fba0d44264b12b83441dd5453b34a4c58e749cd7..cb91e60b6e4eabf479bf560a8117eb89279e3462 100644
--- a/src/datamodel.h
+++ b/src/datamodel.h
@@ -15,10 +15,12 @@
 
 DMOBJ tSWmodObj[];
 DMOBJ tSoftwareModulesObj[];
+DMOBJ tCapabilityObj[];
 DMLEAF tSoftwareModulesParams[];
+DMLEAF tSoftwareModulesExecEnvClassParams[];
+DMLEAF tSoftwareModulesCapabilityParams[];
 DMLEAF tSoftwareModulesExecEnvParams[];
 DMLEAF tSoftwareModulesDeploymentUnitParams[];
-DMLEAF tSoftwareModulesExecutionUnitParams[];
 
 #endif //__DATAMODEL_H
 
diff --git a/src/opkg_utils.c b/src/opkg_utils.c
deleted file mode 100644
index dd2a3c277e82c10ce2babfdb227d69236b1138c5..0000000000000000000000000000000000000000
--- a/src/opkg_utils.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * opkg_utils.c: OPKG utility functions
- *
- * Copyright (C) 2021-2023 IOPSYS Software Solutions AB. All rights reserved.
- *
- * Author: Vivek Dutta <vivek.dutta@iopsys.eu>
- *
- * See LICENSE file for license related information.
- */
-
-/*
-* Description: Opkg does not provide a library to interact with opkg packages,
-*  utilities written in this file is to provide a wrapper functions.
-*/
-
-#include "opkg_utils.h"
-#include "tools.h"  // run_cmd
-
-int opkg_install_pkg(const char *pkg_name, char *output, int out_len)
-{
-	char command[1024] = {0};
-
-	if (pkg_name == NULL)
-		return 0;
-
-	snprintf(command, sizeof(command), "opkg --force-depends --force-maintainer install %s 2>&1", pkg_name);
-
-	return run_cmd(command, output, out_len);
-}
-
-int opkg_update_pkg(const char *pkg_name, char *output, int out_len)
-{
-	char command[1024] = {0};
-
-	if (pkg_name == NULL)
-		return 0;
-
-	snprintf(command, sizeof(command), "opkg --force-depends --force-maintainer install %s 2>&1", pkg_name);
-
-	return run_cmd(command, output, out_len);
-}
-
-int opkg_remove_pkg(const char *pkg_name, char *output, int out_len)
-{
-	char command[1024] = {0};
-
-	if (pkg_name == NULL)
-		return 0;
-
-	snprintf(command, sizeof(command), "opkg --force-depends remove %s 2>&1", pkg_name);
-
-	return run_cmd(command, output, out_len);
-}
-
-int opkg_get_version(const char *pkg_name, char *buffer, int buf_len)
-{
-	/* Get Description from package_name.control */
-	char pkg_path[128] = {0};
-	snprintf(pkg_path, sizeof(pkg_path), "%s/%s.control", OPKG_INFO_PATH, pkg_name);
-
-	FILE *fp = fopen(pkg_path, "r");
-	if (fp != NULL) {
-		char line[256] = {0};
-		char *spch = NULL;
-
-		while (fgets(line, sizeof(line), fp) != NULL) {
-			if ((spch = strstr(line, "Version:"))) {
-				remove_new_line(spch);
-				snprintf(buffer, buf_len, "%s", spch+9);
-				break;
-			}
-		}
-
-		fclose(fp);
-	}
-
-	return 0;
-}
diff --git a/src/opkg_utils.h b/src/opkg_utils.h
deleted file mode 100644
index 6d35f8a5ffad49f7b636e8a37d5d27361abe089d..0000000000000000000000000000000000000000
--- a/src/opkg_utils.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * opkg_utils.h: OPKG utility functions
- *
- * Copyright (C) 2021-2023 IOPSYS Software Solutions AB. All rights reserved.
- *
- * Author: Vivek Dutta <vivek.dutta@iopsys.eu>
- *
- * See LICENSE file for license related information.
- */
-
-#ifndef __OPKG_UTILS_H
-#define __OPKG_UTILS_H
-#include <stdbool.h>
-
-int opkg_install_pkg(const char *pkg_name, char *output, int out_len);
-int opkg_update_pkg(const char *pkg_name, char *output, int out_len);
-int opkg_remove_pkg(const char *pkg_name, char *output, int out_len);
-int opkg_get_version(const char *pkg_name, char *output, int out_len);
-
-#endif //__OPKG_UTILS_H
diff --git a/src/swmod.c b/src/swmod.c
index b3e38d1132464f4ab5b917896eb6be89d28e48f5..7617bd616d773a946120b368b4341905c3f11b01 100644
--- a/src/swmod.c
+++ b/src/swmod.c
@@ -15,12 +15,11 @@
 #include <libubox/uloop.h>
 #include <sys/prctl.h>
 
+#include "swmod.h"
 #include "swmod_uci.h"
-#include "swmod_opkg.h"
 #include "swmod_api.h"
 #include "tools.h"
-#include "swmod_host.h"
-#include "swmod.h"
+
 #ifdef SWMOD_LXC
 #include "swmod_lxc.h"
 #endif
@@ -29,192 +28,36 @@
 #include "swmod_crun.h"
 #endif
 
+#ifdef SWMOD_VERSION
+#define version SWMOD_VERSION
+#else
+#define version "Unknown"
+#endif
+
 struct ubus_context *ubus_ctx;
-ExecEnv_t g_environments[MAX_ENV] = {0};
 ConfigParams swmod_config;
 
 enum {
-	DU_INSTALL_ENV_ID,
 	DU_INSTALL_ENV,
 	DU_INSTALL_UUID,
 	DU_INSTALL_URL,
 	DU_INSTALL_USERNAME,
 	DU_INSTALL_PASSWORD,
+	DU_AUTO_RESTART,
 	__DU_INSTALL_MAX
 };
 
-enum {
-	DU_UPDATE_ENV_ID,
-	DU_UPDATE_ENV,
-	DU_UPDATE_UUID,
-	DU_UPDATE_URL,
-	DU_UPDATE_USERNAME,
-	DU_UPDATE_PASSWORD,
-	__DU_UPDATE_MAX
-};
-
-enum {
-	DU_UNINSTALL_ENV_ID,
-	DU_UNINSTALL_ENV,
-	DU_UNINSTALL_NAME,
-	__DU_UNINSTALL_MAX
-};
-
-enum {
-	EU_DU_LIST_ENV_ID,
-	EU_DU_LIST_ENV,
-	__EU_DU_LIST_MAX
-};
-
-enum {
-	SET_CONFIG_ENV_ID,
-	SET_CONFIG_ENV,
-	SET_CONFIG_UUID,
-	SET_CONFIG_EU_NAME,
-	SET_CONFIG_PARAM,
-	SET_CONFIG_VALUE,
-	__SET_CONFIG_MAX
-};
-
-enum config_param {
-	EE_ALIAS,
-	EE_ENABLE,
-	DU_ALIAS,
-	EU_ALIAS,
-	EU_REQUESTED_STATE,
-	EU_AUTOSTART,
-	__CONFIG_PARAM_MAX
-};
-
-struct param_name {
-	enum config_param type;
-	char param_name[MAX_LEN_32];
-};
-
-static const struct param_name param[__CONFIG_PARAM_MAX] = {
-	{ EE_ALIAS, "ee_alias" },
-	{ EE_ENABLE, "ee_enable" },
-	{ DU_ALIAS, "du_alias" },
-	{ EU_ALIAS, "eu_alias" },
-	{ EU_REQUESTED_STATE, "eu_requested_state" },
-	{ EU_AUTOSTART, "eu_autostart" },
-};
-
-static int get_param_type(const char *param_name)
-{
-	int i;
-	if (param_name == NULL)
-		return __CONFIG_PARAM_MAX;
-
-	for (i = 0; i < __CONFIG_PARAM_MAX; i++) {
-		if (strcmp(param_name, param[i].param_name) == 0)
-			return param[i].type;
-	}
-
-	return __CONFIG_PARAM_MAX;
-}
-
-static const struct blobmsg_policy set_config_policy[__SET_CONFIG_MAX] = {
-	[SET_CONFIG_ENV_ID] = { .name = "eeid", .type = BLOBMSG_TYPE_INT32 },
-	[SET_CONFIG_ENV] = { .name = "ee_name", .type = BLOBMSG_TYPE_STRING },
-	[SET_CONFIG_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_STRING },
-	[SET_CONFIG_EU_NAME] = { .name = "eu_name", .type = BLOBMSG_TYPE_STRING },
-	[SET_CONFIG_PARAM] = { .name = "parameter", .type = BLOBMSG_TYPE_STRING },
-	[SET_CONFIG_VALUE] = { .name = "value", .type = BLOBMSG_TYPE_STRING },
-};
-
 static const struct blobmsg_policy du_install_policy[__DU_INSTALL_MAX] = {
-	[DU_INSTALL_ENV_ID] = { .name = "eeid", .type = BLOBMSG_TYPE_INT32 },
-	[DU_INSTALL_ENV] = { .name = "ee_name", .type = BLOBMSG_TYPE_STRING },
+	[DU_INSTALL_ENV] = { .name = "execenv", .type = BLOBMSG_TYPE_STRING },
 	[DU_INSTALL_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_STRING },
 	[DU_INSTALL_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING },
 	[DU_INSTALL_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING },
 	[DU_INSTALL_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING },
+	[DU_AUTO_RESTART] = { .name = "autorestart", .type = BLOBMSG_TYPE_BOOL },
 };
 
-static const struct blobmsg_policy du_update_policy[__DU_UPDATE_MAX] = {
-	[DU_UPDATE_ENV_ID] = { .name = "eeid", .type = BLOBMSG_TYPE_INT32 },
-	[DU_UPDATE_ENV] = { .name = "ee_name", .type = BLOBMSG_TYPE_STRING },
-	[DU_UPDATE_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_STRING },
-	[DU_UPDATE_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING },
-	[DU_UPDATE_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING },
-	[DU_UPDATE_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING },
-};
-
-static const struct blobmsg_policy du_uninstall_policy[__DU_UNINSTALL_MAX] = {
-	[DU_UNINSTALL_ENV_ID] = { .name = "eeid", .type = BLOBMSG_TYPE_INT32 },
-	[DU_UNINSTALL_ENV] = { .name = "ee_name", .type = BLOBMSG_TYPE_STRING },
-	[DU_UNINSTALL_NAME] = { .name = "du_name", .type = BLOBMSG_TYPE_STRING },
-};
-
-static const struct blobmsg_policy eu_du_list_policy[__EU_DU_LIST_MAX] = {
-	[EU_DU_LIST_ENV_ID] = { .name = "eeid", .type = BLOBMSG_TYPE_INT32 },
-	[EU_DU_LIST_ENV] = { .name = "ee_name", .type = BLOBMSG_TYPE_STRING },
-};
-
-static void
-populate_environments(void)
-{
-	struct list_head ee_head;
-	memset(&ee_head, 0, sizeof(struct list_head));
-	memset(g_environments, '\0', sizeof(g_environments));
-
-	INIT_LIST_HEAD(&ee_head);
-	/* Host system */
-	populate_host_system_environment(&ee_head);
-
-	/* Linux containers */
-#ifdef SWMOD_LXC
-	populate_lxc_environment(&ee_head, swmod_config.lxc_bundle_root);
-#endif
-
-	sync_eeid_with_uci(&ee_head, g_environments, swmod_config.lxc_bundle_root);
-	swmod_delete_ee_list(&ee_head);
-
-	int i;
-	for (i = 0; i < MAX_ENV; i++) {
-		if (!g_environments[i].exists)
-			continue;
-
-		swmod_get_env_info(&g_environments[i]);
-	}
-}
-
-ExecEnv_t* get_ee_from_eeid(unsigned int eid)
-{
-	int i;
-	for (i = 0; i < MAX_ENV; i++) {
-		if (!g_environments[i].exists)
-			continue;
-
-		if (eid == g_environments[i].eeid) {
-			return &g_environments[i];
-		}
-	}
-
-	return NULL;
-}
-
-ExecEnv_t* get_ee_from_name(char *ename)
-{
-	if (ename == NULL)
-		return NULL;
-
-	int i;
-	for (i = 0; i < MAX_ENV; i++) {
-		if (!g_environments[i].exists)
-			continue;
-
-		if (strcmp(g_environments[i].name, ename) == 0) {
-			return &g_environments[i];
-		}
-	}
-
-	return NULL;
-}
-
 static int
-swmod_environment(struct ubus_context *ctx, struct ubus_object *obj,
+swmod_ee_class(struct ubus_context *ctx, struct ubus_object *obj,
 		struct ubus_request_data *req, const char *method,
 		struct blob_attr *msg)
 {
@@ -222,34 +65,23 @@ swmod_environment(struct ubus_context *ctx, struct ubus_object *obj,
 	void *a, *t;
 	int i;
 
-	populate_environments();
-
 	memset(&bb, 0, sizeof(struct blob_buf));
 	blob_buf_init(&bb, 0);
 
-	a = blobmsg_open_array(&bb, "environment");
+	blobmsg_add_string(&bb, "name", swmod_config.ee_class_name);
+	blobmsg_add_string(&bb, "vendor", swmod_config.ee_class_vendor);
+	blobmsg_add_string(&bb, "version", swmod_config.ee_class_version);
+
+	a = blobmsg_open_array(&bb, "capabilities");
 
-	for (i = 0; i < MAX_ENV; i++) {
-		if (!g_environments[i].exists)
+	for (i = 0; i < DU_TYPE_MAX; i++) {
+		if (strlen(swmod_config.ee_cap[i].spec) == 0)
 			continue;
 
 		t = blobmsg_open_table(&bb, "");
-
-		blobmsg_add_string(&bb, "ee_name", g_environments[i].name);
-		blobmsg_add_string(&bb, "ee_alias", g_environments[i].alias);
-		blobmsg_add_u32(&bb, "eeid", g_environments[i].eeid);
-		blobmsg_add_string(&bb, "status", g_environments[i].status);
-		blobmsg_add_u32(&bb, "pause", g_environments[i].pause);
-		blobmsg_add_u32(&bb, "autoboot", g_environments[i].autoboot);
-		blobmsg_add_string(&bb, "type", g_environments[i].type);
-		blobmsg_add_string(&bb, "vendor", g_environments[i].vendor);
-		blobmsg_add_string(&bb, "version", g_environments[i].version);
-		blobmsg_add_u64(&bb, "allocated_disk_space", g_environments[i].allocated_disk_space);
-		blobmsg_add_u64(&bb, "available_disk_space", g_environments[i].available_disk_space);
-		blobmsg_add_u64(&bb, "allocated_memory", g_environments[i].allocated_memory);
-		blobmsg_add_u64(&bb, "available_memory", g_environments[i].available_memory);
-		blobmsg_add_u32(&bb, "parent_ee_ref", g_environments[i].parent_eeid);
-
+		blobmsg_add_string(&bb, "specification", swmod_config.ee_cap[i].spec);
+		blobmsg_add_string(&bb, "version", swmod_config.ee_cap[i].ver);
+		blobmsg_add_string(&bb, "uri", swmod_config.ee_cap[i].uri);
 		blobmsg_close_table(&bb, t);
 	}
 
@@ -261,362 +93,12 @@ swmod_environment(struct ubus_context *ctx, struct ubus_object *obj,
 }
 
 static int
-swmod_reload_config(struct ubus_context *ctx, struct ubus_object *obj,
+swmod_reload(struct ubus_context *ctx, struct ubus_object *obj,
 		struct ubus_request_data *req, const char *method,
 		struct blob_attr *msg)
 {
-#ifdef SWMOD_CRUN
-	swmod_change_crun_du_state(swmod_config.oci_bundle_root);
-#endif
-	return 0;
-}
-
-static void swmod_perform_package_uninstall(PkgInfo *pkg)
-{
-	char output[MAX_LEN_1024] = {0};
-	ExecEnv_t *env = NULL;
-	time_t finish;
-	bool reload_crun = false;
-
-	if (pkg == NULL) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "Invalid DU arguments");
-		swmod_send_event_du_state_change(true, 7002, finish, finish, "", "",
-						 SWMOD_REMOVE, output);
-		return;
-	}
-
-	env = get_ee_from_name((char*)pkg->env_name);
-	if (env == NULL) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "Invalid ExecEnvReference");
-		swmod_send_event_du_state_change(true, 7223, pkg->start, finish, "", "",
-						 SWMOD_REMOVE, output);
-		return;
-	}
-
-	/* Now write the DU params in UCI */
-	char uci_file[MAX_LEN_256] = {0};
-	int ret = swmod_ee_uci_init(env, uci_file, sizeof(uci_file));
-	if (ret != 0 || strlen(uci_file) == 0) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "Internal Error");
-		swmod_send_event_du_state_change(true, 7002, pkg->start, finish, "", "",
-						 SWMOD_REMOVE, output);
-		return;
-	}
-
-	bool found = false;
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(uci_file, "du_eu_assoc", stmp, s) {
-		char *ee_name = swmod_uci_get_value_by_section(s, "ee_name");
-		char *du_name = swmod_uci_get_value_by_section(s, "name");
-
-		if (strcmp(ee_name, env->name) == 0 && strcmp(du_name, pkg->url) == 0) {
-			char *uuid = swmod_uci_get_value_by_section(s, "uuid");
-			memset(pkg->uuid, 0, sizeof(pkg->uuid));
-			snprintf(pkg->uuid, sizeof(pkg->uuid), "%s", uuid);
-			found = true;
-			break;
-		}
-	}
-
-	if (found == false) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "DU (%.64s) not exists in (%s) env", pkg->url, env->name);
-		swmod_send_event_du_state_change(true, 7002, pkg->start, finish, "", "",
-						 SWMOD_REMOVE, output);
-		swmod_uci_fini(uci_file);
-		return;
-	}
-
-	char start_time[MAX_LEN_32] = {0};
-	snprintf(start_time, sizeof(start_time), "%lu", (unsigned long)pkg->start);
-
-	swmod_uci_set_value_by_section(s, "start_time", start_time);
-	swmod_uci_set_value_by_section(s, "du_status", "Uninstalling");
-
-	int err = swmod_remove_package(env, pkg, output, sizeof(output));
-
-	struct du_info info;
-	memset(&info, 0, sizeof(struct du_info));
-
-	if (err == 0) {
-		if (strstr(output, "Removing package") != NULL) {
-			char *ptr = strstr(output, "Package Name:");
-			if (ptr != NULL) {
-				sscanf(ptr, "Package Name:%63s Version:%63s", info.name, info.version);
-			}
-		} else if (strstr(output, "Container") != NULL) {
-				sscanf(output, "Container %63s uninstalled", info.name);
-				reload_crun = true;
-		} else {
-			err = -1;
-		}
-	}
-
-	bool failed = (err) ? true : false;
-
-	if (!failed) {
-		if (reload_crun) {
-			// for crun containers
-			swmod_uci_fini(uci_file);
-			swmod_uci_commit("crun");
-		} else {
-			// for lxc packages
-			swmod_uci_delete_by_section(s, NULL, NULL);
-			swmod_uci_fini(uci_file);
-			finish = time(NULL);
-			swmod_send_event_du_state_change(false, 0, pkg->start, finish, pkg->uuid,
-							 info.version, SWMOD_REMOVE, output);
-		}
-	} else {
-		swmod_uci_set_value_by_section(s, "du_status", "Installed");
-		swmod_uci_fini(uci_file);
-		finish = time(NULL);
-		swmod_send_event_du_state_change(true, 7002, pkg->start, finish, pkg->uuid,
-						 info.version, SWMOD_REMOVE, output);
-	}
-
-}
-
-static void swmod_perform_package_install(PkgInfo *pkg)
-{
-	char output[MAX_LEN_1024] = {0};
-	ExecEnv_t *env = NULL;
-	time_t finish;
-	bool docker_image = false;
-
-	if (pkg == NULL) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "Invalid DU arguments");
-		swmod_send_event_du_state_change(true, 7002, finish, finish, "", "",
-						 SWMOD_INSTALL, output);
-		return;
-	}
-
-	env = get_ee_from_name((char*)pkg->env_name);
-	if (env == NULL) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "Invalid ExecEnvReference");
-		swmod_send_event_du_state_change(true, 7223, pkg->start, finish, pkg->uuid, "",
-						 SWMOD_INSTALL, output);
-		return;
-	}
-
-	char uci_file[MAX_LEN_256] = {0};
-	int ret = swmod_ee_uci_init(env, uci_file, sizeof(uci_file));
-	if (ret != 0 || strlen(uci_file) == 0) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "Internal Error");
-		swmod_send_event_du_state_change(true, 7002, pkg->start, finish, pkg->uuid, "",
-						 SWMOD_INSTALL, output);
-		return;
-	}
-
-	char start_time[MAX_LEN_32] = {0};
-	snprintf(start_time, sizeof(start_time), "%lu", (unsigned long)pkg->start);
-
-	struct uci_section *s = swmod_uci_add_section(uci_file, "du_eu_assoc", false);
-	swmod_uci_set_value_by_section(s, "start_time", start_time);
-	swmod_uci_set_value_by_section(s, "url", pkg->url);
-	swmod_uci_set_value_by_section(s, "username", pkg->uname);
-	swmod_uci_set_value_by_section(s, "password", pkg->psw);
-	swmod_uci_set_value_by_section(s, "uuid", pkg->uuid);
-	swmod_uci_set_value_by_section(s, "ee_name", pkg->env_name);
-	swmod_uci_set_value_by_section(s, "du_status", "Installing");
-
-	static int incr = 0;
-	char *duid = generate_duid(true, incr++);
-	swmod_uci_set_value_by_section(s, "duid", duid);
-	FREE(duid);
-
-	// set the corresponding section in pkg for further use if any
-	pkg->section = s;
-
-	// Now perform installation
-	int err = swmod_install_package(env, pkg, output, sizeof(output));
-
-	struct du_info info;
-	memset(&info, 0, sizeof(struct du_info));
-	if (err == 0) {
-		if (strstr(output, "Installing") != NULL) {
-			sscanf(output, "Installing %63s (%63[^)] to root...", info.name, info.version);
-			get_opkg_description(env, info.name, info.desc, sizeof(info.desc));
-			get_opkg_service_name(env, info.name, info.eu_name, sizeof(info.eu_name));
-			snprintf(info.du_type, sizeof(info.du_type), "lxc");
-		} else if (strstr(output, "Container") != NULL) {
-			sscanf(output, "Container %63s to be installed", info.name);
-			snprintf(info.du_type, sizeof(info.du_type), "crun");
-			snprintf(info.eu_name, sizeof(info.eu_name), "%.32s", info.name);
-			docker_image = true; // installation performed externally
-		} else if (strstr(output, "Tar") != NULL) {
-			sscanf(output, "Tar %63s installed", info.name);
-			snprintf(info.du_type, sizeof(info.du_type), "crun");
-			snprintf(info.eu_name, sizeof(info.eu_name), "%.32s", info.name);
-		} else {
-			err = -1;
-		}
-	}
-
-	bool failed = (err) ? true : false;
-
-	if (!failed) {
-		// write the DU informations
-		swmod_uci_set_value_by_section(s, "name", info.name);
-		swmod_uci_set_value_by_section(s, "version", info.version);
-		swmod_uci_set_value_by_section(s, "description", info.desc);
-		swmod_uci_set_value_by_section(s, "type", info.du_type);
-		swmod_uci_set_value_by_section(s, "autostart", "1");
-		swmod_uci_set_value_by_section(s, "requested_state", "Active");
-		swmod_uci_set_value_by_section(s, "eu_name", info.eu_name);
-
-		if (docker_image == false) {
-			// internally handled so need to set status accordingly
-			swmod_uci_set_value_by_section(s, "du_status", "Installed");
-			swmod_uci_delete_by_section(s, "username", pkg->uname);
-			swmod_uci_delete_by_section(s, "password", pkg->psw);
-			finish = time(NULL);
-			swmod_send_event_du_state_change(false, 0, pkg->start, finish,
-						pkg->uuid, info.version, SWMOD_INSTALL, output);
-		}
-
-		swmod_uci_fini(uci_file);
-
-		if (strcmp(info.du_type, "crun") == 0) {// for crun containers
-			swmod_uci_commit("crun");
-		}
-	} else {
-		PRINT_ERR("DU Installation failed");
-		swmod_uci_delete_by_section(s, NULL, NULL);
-		swmod_uci_fini(uci_file);
-		finish = time(NULL);
-		swmod_send_event_du_state_change(true, 7002, pkg->start, finish, pkg->uuid,
-					 info.version, SWMOD_INSTALL, output);
-	}
-}
-
-static int swmod_perform_du_operation(PkgInfo *pkg, size_t size)
-{
-	int ret = -1;
-	int fd[2];
-
-	if (pkg == NULL)
-		return ret;
-
-	if (pipe(fd) < 0)
-		return ret;
-
-	pid_t child;
-	child = fork();
-	if (child == -1) {
-		PRINT_ERR("fork error");
-		return ret;
-	} else if (child != 0) {
-		// parent process
-		close(fd[0]);
-		write(fd[1], pkg, size);
-		close(fd[1]);
-		ret = 0;
-	} else {
-		// child process
-		prctl(PR_SET_NAME, "swmodd_du_operation");
-		ubus_shutdown(ubus_ctx);
-		ubus_ctx = NULL;
-		uloop_done();
-		fclose(stderr);
-		fclose(stdout);
-		fclose(stdin);
-
-		close(fd[1]);
-		PkgInfo p_info;
-		memset(&p_info, 0, sizeof(PkgInfo));
-		int res = read(fd[0], &p_info, sizeof(PkgInfo));
-		close(fd[0]);
-
-		if (res == -1) {
-			PRINT_DEBUG("DU param value read failed");
-			exit(EXIT_FAILURE);
-		}
-
-		PRINT_DEBUG("Perform DU operation: %d", p_info.operation);
-		ubus_ctx = ubus_connect(NULL);
-		if (ubus_ctx == NULL) {
-			PRINT_ERR("Failed to connect UBUS");
-			exit(EXIT_FAILURE);
-		}
-
-		switch (p_info.operation) {
-		case SWMOD_INSTALL:
-			swmod_perform_package_install(&p_info);
-			break;
-		case SWMOD_UPDATE:
-			break;
-		case SWMOD_REMOVE:
-			swmod_perform_package_uninstall(&p_info);
-			break;
-		}
-
-		ubus_free(ubus_ctx);
-		exit(EXIT_SUCCESS);
-	}
-
-	return ret;
-}
-
-static int
-swmod_du_uninstall(struct ubus_context *ctx, struct ubus_object *obj,
-		struct ubus_request_data *req, const char *method,
-		struct blob_attr *msg)
-{
-	struct blob_attr *tb[__DU_UNINSTALL_MAX] = {NULL};
-	char output[MAX_LEN_1024] = {0};
-	ExecEnv_t *env = NULL;
-	time_t finish;
-	PkgInfo pkg;
-
-	memset(&pkg, 0, sizeof(PkgInfo));
-	pkg.start = time(NULL);
-
-	if (blobmsg_parse(du_uninstall_policy, __DU_UNINSTALL_MAX, tb, blob_data(msg), blob_len(msg)))
-		return UBUS_STATUS_UNKNOWN_ERROR;
-
-	if (!tb[DU_UNINSTALL_NAME]) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "No DU Name found");
-		swmod_send_event_du_state_change(true, 7002, pkg.start, finish, "", "",
-						 SWMOD_REMOVE, output);
-		return UBUS_STATUS_INVALID_ARGUMENT;
-	}
-
-	if (tb[DU_UNINSTALL_ENV])
-		env = get_ee_from_name(blobmsg_get_string(tb[DU_UNINSTALL_ENV]));
-
-	/* Priority should be given on EID if both EID and ENV name are provided */
-	if (tb[DU_UNINSTALL_ENV_ID])
-		env = get_ee_from_eeid(blobmsg_get_u32(tb[DU_UNINSTALL_ENV_ID]));
-
-	if (env == NULL) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "Could not find Execution Environment");
-		swmod_send_event_du_state_change(true, 7223, pkg.start, finish, "", "",
-						 SWMOD_REMOVE, output);
-		return UBUS_STATUS_INVALID_ARGUMENT;
-	}
-
-	snprintf(pkg.url, sizeof(pkg.url), "%s", blobmsg_get_string(tb[DU_UNINSTALL_NAME]));
-	snprintf(pkg.env_name, sizeof(pkg.env_name), "%s", env->name);
-	pkg.operation = SWMOD_REMOVE;
-
-	int ret = swmod_perform_du_operation(&pkg, sizeof(pkg));
-
-	struct blob_buf bb;
-	memset(&bb, 0, sizeof(struct blob_buf));
-	blob_buf_init(&bb, 0);
-	blobmsg_add_u8(&bb, "status", ret ? false : true);
-	ubus_send_reply(ctx, req, bb.head);
-	blob_buf_free(&bb);
-
+	/* there could be request for execenv add, restart or remove */
+	swmod_execenv_actions();
 	return 0;
 }
 
@@ -625,480 +107,55 @@ swmod_du_install(struct ubus_context *ctx, struct ubus_object *obj,
 		struct ubus_request_data *req, const char *method,
 		struct blob_attr *msg)
 {
-	time_t finish;
 	struct blob_attr *tb[__DU_INSTALL_MAX] = {NULL};
-	ExecEnv_t *env = NULL;
 	PkgInfo pkg;
-	char output[MAX_LEN_1024] = {0};
-
-	memset(&pkg, 0, sizeof(PkgInfo));
-	pkg.start = time(NULL);
 
 	if (blobmsg_parse(du_install_policy, __DU_INSTALL_MAX, tb, blob_data(msg), blob_len(msg)))
 		return UBUS_STATUS_UNKNOWN_ERROR;
 
-	if (tb[DU_INSTALL_ENV])
-		env = get_ee_from_name(blobmsg_get_string(tb[DU_INSTALL_ENV]));
+	memset(&pkg, 0, sizeof(PkgInfo));
 
-	/* Priority should be given on EID if both EID and ENV name are provided */
-	if (tb[DU_INSTALL_ENV_ID])
-		env = get_ee_from_eeid(blobmsg_get_u32(tb[DU_INSTALL_ENV_ID]));
+	if (tb[DU_INSTALL_ENV])
+		snprintf(pkg.execenv, sizeof(pkg.execenv), "%s", blobmsg_get_string(tb[DU_INSTALL_ENV]));
+	
+	if (strlen(pkg.execenv) == 0) {
+		char *env = swmod_select_env();
+		snprintf(pkg.execenv, sizeof(pkg.execenv), "%s", env ? env : "");
+		FREE(env);
+	}
 
-	if (tb[DU_INSTALL_UUID]) {
+	if (tb[DU_INSTALL_UUID])
 		snprintf(pkg.uuid, sizeof(pkg.uuid), "%s", blobmsg_get_string(tb[DU_INSTALL_UUID]));
-		if (!valid_uuid(pkg.uuid, swmod_config.lxc_bundle_root, swmod_config.oci_bundle_root)) {
-			finish = time(NULL);
-			snprintf(output, sizeof(output), "UUID is not valid");
-			swmod_send_event_du_state_change(true, 7002, pkg.start, finish, pkg.uuid, "",
-							 SWMOD_INSTALL, output);
-			return UBUS_STATUS_INVALID_ARGUMENT;
-		}
-	}
 
-	// Generate UUID if not provided
 	if (strlen(pkg.uuid) == 0) {
-		char *id = generate_uuid();
-		if (id == NULL) {
-			finish = time(NULL);
-			snprintf(output, sizeof(output), "Failed to generate UUID");
-			swmod_send_event_du_state_change(true, 7002, pkg.start, finish, "", "",
-							 SWMOD_INSTALL, output);
-			return UBUS_STATUS_UNKNOWN_ERROR;
-		}
-
-		snprintf(pkg.uuid, sizeof(pkg.uuid), "%s", id);
-		free(id);
-	}
-
-	if (!tb[DU_INSTALL_URL]) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "No URL provided");
-		swmod_send_event_du_state_change(true, 7002, pkg.start, finish, pkg.uuid, "",
-						 SWMOD_INSTALL, output);
-		return UBUS_STATUS_INVALID_ARGUMENT;
-	}
-
-	if (env == NULL) {
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "Could not find Execution Environment");
-		swmod_send_event_du_state_change(true, 7223, pkg.start, finish, pkg.uuid, "",
-						 SWMOD_INSTALL, output);
-		return UBUS_STATUS_INVALID_ARGUMENT;
-	}
-
-	snprintf(pkg.url, sizeof(pkg.url), "%s", blobmsg_get_string(tb[DU_INSTALL_URL]));
-	if (strncmp(pkg.url, "docker://", 9) != 0 && strchr(pkg.url, '@') != NULL) { /* In docker link there could be '@' for specific sha */
-		finish = time(NULL);
-		snprintf(output, sizeof(output), "URL contains user info");
-		swmod_send_event_du_state_change(true, 7004, pkg.start, finish, pkg.uuid, "",
-						 SWMOD_INSTALL, output);
-		return UBUS_STATUS_INVALID_ARGUMENT;
+		char *uuid = generate_uuid();
+		snprintf(pkg.uuid, sizeof(pkg.uuid), "%s", uuid ? uuid : "");
+		FREE(uuid);
 	}
 
+	if (tb[DU_INSTALL_URL])
+		snprintf(pkg.url, sizeof(pkg.url), "%s", blobmsg_get_string(tb[DU_INSTALL_URL]));
+		
 	if (tb[DU_INSTALL_USERNAME])
 		snprintf(pkg.uname, sizeof(pkg.uname), "%s", blobmsg_get_string(tb[DU_INSTALL_USERNAME]));
 
 	if (tb[DU_INSTALL_PASSWORD])
 		snprintf(pkg.psw, sizeof(pkg.psw), "%s", blobmsg_get_string(tb[DU_INSTALL_PASSWORD]));
+		
+	if (tb[DU_AUTO_RESTART])
+		pkg.autostart = blobmsg_get_bool(tb[DU_AUTO_RESTART]);
 
-	snprintf(pkg.env_name, sizeof(pkg.env_name), "%s", env->name);
 	pkg.operation = SWMOD_INSTALL;
 
-	int ret = swmod_perform_du_operation(&pkg, sizeof(pkg));
-
-	struct blob_buf bb;
-	memset(&bb, 0, sizeof(struct blob_buf));
-	blob_buf_init(&bb, 0);
-	blobmsg_add_u8(&bb, "status", ret ? false : true);
-	ubus_send_reply(ctx, req, bb.head);
-	blob_buf_free(&bb);
-
-	return 0;
-}
-
-static char *get_performed_operation(int action)
-{
-	switch(action) {
-	case SWMOD_INSTALL:
-		return "Install";
-	case SWMOD_UPDATE:
-		return "Update";
-	case SWMOD_REMOVE:
-		return "Uninstall";
-	}
-
-	return "Invalid";
-}
-
-static char *get_current_du_state(int action, bool failed)
-{
-	switch(action) {
-	case SWMOD_INSTALL:
-		if (failed)
-			return "Failed";
-
-		return "Installed";
-	case SWMOD_UPDATE:
-		return "Installed";
-	case SWMOD_REMOVE:
-		if (failed)
-			return "Installed";
-		return "UnInstalled";
-	}
-
-	return "Invalid";
-}
-
-void swmod_send_event_du_state_change(bool failed, int code, time_t start, time_t end,
-			const char *uuid, const char *ver, int action, const char *err)
-{
-	uint32_t id;
-	char start_time[MAX_LEN_32] = {0};
-	char end_time[MAX_LEN_32] = {0};
-
-	if (ubus_ctx == NULL) {
-		return;
-	}
-
-	strftime(start_time, sizeof(start_time), "%Y-%m-%dT%H:%M:%SZ", gmtime(&start));
-	strftime(end_time, sizeof(end_time), "%Y-%m-%dT%H:%M:%SZ", gmtime(&end));
-	char *operation = get_performed_operation(action);
-	char *state = get_current_du_state(action, failed);
-
-	struct blob_buf b;
-	memset(&b, 0, sizeof(struct blob_buf));
-
-	blob_buf_init(&b, 0);
-	blobmsg_add_string(&b, "name", "Device.SoftwareModules.DUStateChange!");
-
-	void *tbl = blobmsg_open_table(&b, "input");
-	blobmsg_add_string(&b, "UUID", uuid);
-	blobmsg_add_string(&b, "Version", ver);
-	blobmsg_add_string(&b, "CurrentState", state);
-	blobmsg_add_string(&b, "Resolved", failed ? "0" : "1");
-	blobmsg_add_string(&b, "StartTime", start_time);
-	blobmsg_add_string(&b, "CompleteTime", end_time);
-	blobmsg_add_string(&b, "OperationPerformed", operation);
-
-	if (failed) {
-		blobmsg_add_u32(&b, "Fault.FaultCode", code);
-		if (err && err[0] != '\0')
-			blobmsg_add_string(&b, "Fault.FaultString", err);
-		else
-			blobmsg_add_string(&b, "Fault.FaultString", "Internal Error");
-	} else {
-		blobmsg_add_u32(&b, "Fault.FaultCode", 0);
-		blobmsg_add_string(&b, "Fault.FaultString", "");
-	}
-
-	blobmsg_close_table(&b, tbl);
-
-	if (!ubus_lookup_id(ubus_ctx, "usp.raw", &id))
-		ubus_invoke(ubus_ctx, id, "notify_event", b.head, NULL, NULL, UBUS_TIMEOUT);
-
-	blob_buf_free(&b);
-
-	return;
-}
-
-static int
-swmod_du_update(struct ubus_context *ctx, struct ubus_object *obj,
-		struct ubus_request_data *req, const char *method,
-		struct blob_attr *msg)
-{
-	struct blob_buf bb;
-	memset(&bb, 0, sizeof(struct blob_buf));
-	blob_buf_init(&bb, 0);
-	blobmsg_add_u8(&bb, "status", false);
-	blobmsg_add_string(&bb, "info", "DU update not supported");
-	ubus_send_reply(ctx, req, bb.head);
-	blob_buf_free(&bb);
-
-	return 0;
-}
-
-static ExecEnv_t* get_ee_from_blob(struct blob_attr *msg)
-{
-	ExecEnv_t *env = NULL;
-	struct blob_attr *tb[__EU_DU_LIST_MAX] = {NULL};
-
-	if (blobmsg_parse(eu_du_list_policy, __EU_DU_LIST_MAX, tb, blob_data(msg), blob_len(msg)) == 0) {
-		if (tb[EU_DU_LIST_ENV]) {
-			env = get_ee_from_name(blobmsg_get_string(tb[EU_DU_LIST_ENV]));
-		}
-
-		/* Priority given to EID if both EID and ENV name are provided */
-		if (tb[EU_DU_LIST_ENV_ID]) {
-			env = get_ee_from_eeid(blobmsg_get_u32(tb[EU_DU_LIST_ENV_ID]));
-		}
-	}
-
-	return env;
-}
-
-static void prepare_du_list_result(ExecEnv_t *env, struct blob_buf *bb)
-{
-	struct uci_section *ss = NULL;
-
-	if (env == NULL)
-		return;
-
-	if (env->exists == false)
-		return;
-
-	char uci_file[MAX_LEN_256] = {0};
-	int ret = swmod_ee_uci_init(env, uci_file, sizeof(uci_file));
-	if (ret != 0 || strlen(uci_file) == 0) {
-		return;
-	}
-
-	swmod_uci_foreach_section(uci_file, "du_eu_assoc", ss) {
-
-		const char *ee_name = swmod_uci_get_value_by_section(ss, "ee_name");
-		if (strlen(ee_name) == 0)
-			continue;
-
-		if (strcmp(ee_name, env->name) != 0)
-			continue;
-
-		void *t = blobmsg_open_table(bb, "");
-
-		blobmsg_add_string(bb, "du_name", swmod_uci_get_value_by_section(ss, "name"));
-		blobmsg_add_string(bb, "du_alias", swmod_uci_get_value_by_section(ss, "du_alias"));
-		blobmsg_add_string(bb, "ee_name", ee_name);
-		blobmsg_add_u32(bb, "eeid", env->eeid);
-		blobmsg_add_string(bb, "uuid", swmod_uci_get_value_by_section(ss, "uuid"));
-		blobmsg_add_string(bb, "duid", swmod_uci_get_value_by_section(ss, "duid"));
-		blobmsg_add_string(bb, "url", swmod_uci_get_value_by_section(ss, "url"));
-		blobmsg_add_string(bb, "version", swmod_uci_get_value_by_section(ss, "version"));
-		blobmsg_add_string(bb, "config", swmod_uci_get_value_by_section(ss, "config"));
-		blobmsg_add_string(bb, "description", swmod_uci_get_value_by_section(ss, "description"));
-		blobmsg_add_string(bb, "du_status", swmod_uci_get_value_by_section(ss, "du_status"));
-		blobmsg_add_string(bb, "eu_name", swmod_uci_get_value_by_section(ss, "eu_name"));
-		blobmsg_add_string(bb, "vendor", swmod_uci_get_value_by_section(ss, "vendor"));
-
-		blobmsg_close_table(bb, t);
-	}
-
-	swmod_uci_fini(uci_file);
-}
-
-static int
-swmod_du_list(struct ubus_context *ctx, struct ubus_object *obj,
-		struct ubus_request_data *req, const char *method,
-		struct blob_attr *msg)
-{
-	struct blob_buf bb;
-	void *a;
-	ExecEnv_t *env = get_ee_from_blob(msg);
-
-	memset(&bb, 0, sizeof(struct blob_buf));
-	blob_buf_init(&bb, 0);
-
-	a = blobmsg_open_array(&bb, "deployment_unit");
-
-	if (env != NULL) {
-		prepare_du_list_result(env, &bb);
-	} else {
-		for (int i = 0; i < MAX_ENV; i++) {
-			prepare_du_list_result(&g_environments[i], &bb);
-		}
-	}
-
-	blobmsg_close_array(&bb, a);
-
-	ubus_send_reply(ctx, req, bb.head);
-	blob_buf_free(&bb);
-	return 0;
-}
-
-static void prepare_eu_list_result(ExecEnv_t *env, struct blob_buf *bb)
-{
-	void *t;
-
-	if (env == NULL)
-		return;
-
-	if (env->exists == false)
-		return;
-
-	if (list_empty(&env->eu_list))
-		return;
-
-	EuNode *iter = NULL;
-
-	list_for_each_entry(iter, &env->eu_list, list) {
-		if (iter->eu.eu_exists == false) {
-			continue;
-		}
-
-		t = blobmsg_open_table(bb, "");
-
-		blobmsg_add_string(bb, "eu_name", iter->eu.name);
-		blobmsg_add_string(bb, "eu_alias", iter->eu.eu_alias);
-		blobmsg_add_string(bb, "command", iter->eu.command);
-		blobmsg_add_string(bb, "state", iter->eu.state);
-		blobmsg_add_string(bb, "config", iter->eu.config);
-		blobmsg_add_string(bb, "version", iter->eu.version);
-		blobmsg_add_string(bb, "description", iter->eu.description);
-		blobmsg_add_string(bb, "ee_name", iter->eu.environment);
-		blobmsg_add_u32(bb, "eeid", env->eeid);
-		blobmsg_add_string(bb, "euid", iter->eu.euid);
-		blobmsg_add_u32(bb, "disk_space", iter->eu.disk_space);
-		blobmsg_add_u32(bb, "memory_space", iter->eu.memory_space);
-		blobmsg_add_string(bb, "vendor", iter->eu.vendor); //TODO
-		blobmsg_add_string(bb, "req_state", iter->eu.req_state);
-		blobmsg_add_u8(bb, "autostart", iter->eu.autostart);
-		blobmsg_add_string(bb, "du_name", iter->eu.du_name);
-		blobmsg_add_string(bb, "fault_code", iter->eu.fault_code);
-
-		blobmsg_close_table(bb, t);
-	}
-
-	swmod_delete_eu_list(&env->eu_list);
-}
-
-static int
-swmod_eu_list(struct ubus_context *ctx, struct ubus_object *obj,
-		struct ubus_request_data *req, const char *method,
-		struct blob_attr *msg)
-{
-	struct blob_buf bb;
-	void *a;
-
-	ExecEnv_t *env = get_ee_from_blob(msg);
-
-	memset(&bb, 0, sizeof(struct blob_buf));
-	blob_buf_init(&bb, 0);
-
-	a = blobmsg_open_array(&bb, "execution_unit");
-
-	if (env != NULL) {
-		populate_execution_unit(env);
-		prepare_eu_list_result(env, &bb);
-	} else {
-		for (int i = 0; i < MAX_ENV; i++) {
-			populate_execution_unit(&g_environments[i]);
-			prepare_eu_list_result(&g_environments[i], &bb);
-		}
-	}
-
-	blobmsg_close_array(&bb, a);
-
-	ubus_send_reply(ctx, req, bb.head);
-	blob_buf_free(&bb);
-	return 0;
-}
-
-static int
-swmod_set_config(struct ubus_context *ctx, struct ubus_object *obj,
-		struct ubus_request_data *req, const char *method,
-		struct blob_attr *msg)
-{
-	struct blob_buf bb;
-	struct blob_attr *tb[__SET_CONFIG_MAX] = {NULL};
-	char param_name[MAX_LEN_32] = {0};
-	ExecEnv_t *env = NULL;
-	char alias[65] = {0};
-	bool enable = false;
-
-	if (blobmsg_parse(set_config_policy, __SET_CONFIG_MAX, tb, blob_data(msg), blob_len(msg)) != 0) {
-		return UBUS_STATUS_INVALID_ARGUMENT;
-	}
-
-	if (!tb[SET_CONFIG_PARAM] || !tb[SET_CONFIG_VALUE]) {
-		return UBUS_STATUS_INVALID_ARGUMENT;
-	}
-
-	if (tb[SET_CONFIG_ENV]) {
-		env = get_ee_from_name(blobmsg_get_string(tb[SET_CONFIG_ENV]));
-	}
-
-	/* Priority should be given on EID if both EID and ENV name are provided */
-	if (tb[SET_CONFIG_ENV_ID]) {
-		env = get_ee_from_eeid(blobmsg_get_u32(tb[SET_CONFIG_ENV_ID]));
-	}
-
-	if (env == NULL)
-		return UBUS_STATUS_INVALID_ARGUMENT;
-
-	memset(&bb, 0, sizeof(struct blob_buf));
-	blob_buf_init(&bb, 0);
-
-	snprintf(param_name, sizeof(param_name), "%s", blobmsg_get_string(tb[SET_CONFIG_PARAM]));
-	int param = get_param_type(param_name);
-
-	switch (param) {
-	case EE_ALIAS:
-		snprintf(alias, sizeof(alias), "%s", blobmsg_get_string(tb[SET_CONFIG_VALUE]));
-		swmod_set_ee_alias(env, alias, &bb);
-		break;
-	case EE_ENABLE:
-		enable = uci_str_to_bool(blobmsg_get_string(tb[SET_CONFIG_VALUE]));
-		enable ? swmod_change_ee_state(env, "start", &bb) : swmod_change_ee_state(env, "stop", &bb);
-		break;
-	case DU_ALIAS:
-		if (!tb[SET_CONFIG_UUID]) {
-			blob_buf_free(&bb);
-			return UBUS_STATUS_INVALID_ARGUMENT;
-		}
-
-		snprintf(alias, sizeof(alias), "%s", blobmsg_get_string(tb[SET_CONFIG_VALUE]));
-		swmod_set_du_alias(env, blobmsg_get_string(tb[SET_CONFIG_UUID]), alias, &bb);
-		break;
-	case EU_ALIAS:
-		if (!tb[SET_CONFIG_EU_NAME]) {
-			blob_buf_free(&bb);
-			return UBUS_STATUS_INVALID_ARGUMENT;
-		}
-
-		snprintf(alias, sizeof(alias), "%s", blobmsg_get_string(tb[SET_CONFIG_VALUE]));
-		swmod_set_eu_alias(env, blobmsg_get_string(tb[SET_CONFIG_EU_NAME]), alias, &bb);
-		break;
-	case EU_REQUESTED_STATE:
-		if (!tb[SET_CONFIG_EU_NAME]) {
-			blob_buf_free(&bb);
-			return UBUS_STATUS_INVALID_ARGUMENT;
-		}
-
-		if (strcmp(blobmsg_get_string(tb[SET_CONFIG_VALUE]), "Idle") == 0) {
-			swmod_set_service_state(env, blobmsg_get_string(tb[SET_CONFIG_EU_NAME]), false, &bb);
-		} else if (strcmp(blobmsg_get_string(tb[SET_CONFIG_VALUE]), "Active") == 0) {
-			swmod_set_service_state(env, blobmsg_get_string(tb[SET_CONFIG_EU_NAME]), true, &bb);
-		} else {
-			blob_buf_free(&bb);
-			return UBUS_STATUS_INVALID_ARGUMENT;
-		}
-		break;
-	case EU_AUTOSTART:
-		if (!tb[SET_CONFIG_EU_NAME]) {
-			blob_buf_free(&bb);
-			return UBUS_STATUS_INVALID_ARGUMENT;
-		}
-
-		enable = uci_str_to_bool(blobmsg_get_string(tb[SET_CONFIG_VALUE]));
-		swmod_set_eu_autostart(env, blobmsg_get_string(tb[SET_CONFIG_EU_NAME]), enable, &bb);
-		break;
-	default:
-		blob_buf_free(&bb);
-		return UBUS_STATUS_INVALID_ARGUMENT;
-	}
-
-	ubus_send_reply(ctx, req, bb.head);
-	blob_buf_free(&bb);
+	swmod_perform_du_operation(ubus_ctx, &pkg, sizeof(pkg));
 
 	return 0;
 }
 
 static const struct ubus_method swmod_object_methods[] = {
-	UBUS_METHOD_NOARG("ee_list", swmod_environment),
-	UBUS_METHOD_NOARG("reload", swmod_reload_config),
-	UBUS_METHOD("du_list", swmod_du_list, eu_du_list_policy),
-	UBUS_METHOD("eu_list", swmod_eu_list, eu_du_list_policy),
+	UBUS_METHOD_NOARG("ee_class", swmod_ee_class),
+	UBUS_METHOD_NOARG("reload", swmod_reload),
 	UBUS_METHOD("du_install", swmod_du_install, du_install_policy),
-	UBUS_METHOD("du_update", swmod_du_update, du_update_policy),
-	UBUS_METHOD("du_uninstall", swmod_du_uninstall, du_uninstall_policy),
-	UBUS_METHOD("set_config", swmod_set_config, set_config_policy),
 };
 
 static struct ubus_object_type swmod_object_type = UBUS_OBJECT_TYPE("swmodules", swmod_object_methods);
@@ -1112,12 +169,39 @@ static struct ubus_object swmod_object = {
 
 static int swmod_pre_init(void)
 {
+	int ret = -1;
+
 	/* get config */
 	memset(&swmod_config, 0, sizeof(ConfigParams));
-	get_swmod_config_params(&swmod_config);
 
-	// Populate ExecEnv details
-	populate_environments();
+	if (swmod_uci_init(STD_UCI_PATH) != 0)
+		return ret;
+
+	struct uci_section *s = NULL;
+	swmod_uci_foreach_section(SWMOD_UCI_FILE, "globals", s) {
+		if (strcmp(s->e.name, "globals") == 0) {
+			const char *vendor = swmod_uci_get_value_by_section(s, "vendor");
+			snprintf(swmod_config.ee_class_vendor, MAX_LEN_128, "%s", vendor);
+
+			const char *name = swmod_uci_get_value_by_section(s, "name");
+			snprintf(swmod_config.ee_class_name, MAX_LEN_256, "%s", name);
+			break;
+		}
+	}
+
+	swmod_uci_fini(SWMOD_UCI_FILE);
+
+	snprintf(swmod_config.ee_class_version, MAX_LEN_32, "%s", version);
+
+	ret = swmod_check_capability(swmod_config.ee_cap);
+	if (ret)
+		return ret;
+
+	// If any du pending uninstallation, do it
+	swmod_du_pending_uninstallation();
+
+	// Sync existing envs
+	swmod_sync_envs();
 
 	return 0;
 }
@@ -1174,10 +258,14 @@ int main(int argc, char **argv)
 		return -1;
 	}
 
-	swmod_pre_init();
-
 	ubus_add_uloop(ubus_ctx);
 
+	ret = swmod_pre_init();
+	if (ret) {
+		fprintf(stderr, "Failed in pre_init\n");
+		goto out;
+	}
+
 	ret = swmod_init(ubus_ctx);
 	if (ret)
 		goto out;
diff --git a/src/swmod.h b/src/swmod.h
index ed93e5e622acd16c428d761b9fd7e8907eec9ed7..1f284d2cc40083c5d8881bf8a9a4db66d35d3236 100644
--- a/src/swmod.h
+++ b/src/swmod.h
@@ -18,9 +18,6 @@
 
 #include "swmod_common.h"
 
-#define HOST_SYSTEM "OpenWRT_Linux"
-#define MAX_ENV 8 //Max Environment
-#define MAX_EU 256 //Max Execution Unit
 #define UBUS_TIMEOUT 5000 // 5 seconds
 #define MAX_BUFFER_LEN (102400)
 #define MAX_LEN_16 16
@@ -33,82 +30,37 @@
 #define MAX_LEN_1024 1024
 
 typedef enum {
-	EE_TYPE_UNKNOWN,
-	EE_TYPE_HOST,
-	EE_TYPE_LXC,
-	EE_TYPE_CRUN,
-	EE_TYPE_MAX
-} EE_TYPE_t;
+	DU_TYPE_CRUN,
+	DU_TYPE_LXC,
+	DU_TYPE_MAX
+} DU_TYPE_t;
 
 typedef struct {
-	bool exists;
-	unsigned int parent_eeid;
-	unsigned int eeid;
-	EE_TYPE_t ee_type;
-	int pause;
-	int autoboot;
-	unsigned long allocated_disk_space; //AllocatedDiskSpace
-	unsigned long available_disk_space; //AvailableDiskSpace
-	unsigned long allocated_memory; //AllocatedMemory
-	unsigned long available_memory; //AvailableMemory
-	struct list_head eu_list;
-	char status[MAX_LEN_32]; //Status
-	char name[MAX_LEN_32]; //Name
-	char type[MAX_LEN_64]; //Type
-	char vendor[MAX_LEN_128]; //Vendor
-	char version[MAX_LEN_16]; //Version
-	char alias[MAX_LEN_65]; //Version
-} ExecEnv_t;
-
-typedef struct ExecUnit {
-	bool eu_exists;
-	char euid[MAX_LEN_65]; //EUID
-	int disk_space; //DiskSpaceInUse
-	int memory_space; //MemoryInUse
-	char name[MAX_LEN_32]; // //Execution Unit Name
-	char state[MAX_LEN_32]; // //Execution Unit Name
-	char command[MAX_LEN_32]; //Execution Unit Command
-	char vendor[MAX_LEN_128]; //Execution Unit Vendor
-	char config[MAX_LEN_32]; //Config File
-	char version[MAX_LEN_32]; //Version
-	char description[MAX_LEN_1024]; //Description
-	char environment[MAX_LEN_32]; //Environment Name
-	char req_state[MAX_LEN_16];
-	char du_name[MAX_LEN_64]; // //Deployment Unit Name
-	char eu_alias[MAX_LEN_65];
-	bool autostart;
-	char fault_code[MAX_LEN_32];
-} ExecUnit;
-
-typedef struct EuNode {
-	ExecUnit eu;
-	struct list_head list;
-} EuNode;
-
-typedef struct ExecEnvNode {
-	ExecEnv_t env;
-	struct list_head list;
-} ExecEnvNode;
+	char spec[MAX_LEN_16];
+	char ver[MAX_LEN_32];
+	char uri[MAX_LEN_256];
+} ExecEnvCap_t;
 
 typedef struct swmodConfig {
-	char oci_bundle_root[MAX_LEN_32];
-	char lxc_bundle_root[MAX_LEN_32];
+	char ee_class_name[MAX_LEN_256];
+	char ee_class_vendor[MAX_LEN_128];
+	char ee_class_version[MAX_LEN_32];
+	ExecEnvCap_t ee_cap[DU_TYPE_MAX];
 } ConfigParams;
 
-struct du_info {
-	char du_type[MAX_LEN_16];
-	char name[MAX_LEN_64];
-	char version[MAX_LEN_64];
-	char desc[256];
-	char eu_name[33];
-};
+typedef struct duInfo {
+	char du_name[MAX_LEN_256];
+	char execenv[MAX_LEN_256];
+	char eu_runlevel[6];
+	int du_type;
+} duInfo_t;
+
+typedef struct duNode {
+	duInfo_t du;
+	struct list_head list;
+} duInfoNode_t;
 
 extern struct ubus_context *ubus_ctx;
-extern ExecEnv_t g_environments[MAX_ENV];
 extern ConfigParams swmod_config;
 
-void swmod_send_event_du_state_change(bool failed, int code, time_t start, time_t end,
-			const char *uuid, const char *ver, int action, const char *err);
-ExecEnv_t* get_ee_from_name(char *ename);
-ExecEnv_t* get_ee_from_eeid(unsigned int eid);
 #endif //SWMOD_H
diff --git a/src/swmod_api.c b/src/swmod_api.c
index ab51e6f83b3e924ddffefc50f6b513033e49e268..fe9abbf10746683789e534e8b0e1c293c97125a2 100644
--- a/src/swmod_api.c
+++ b/src/swmod_api.c
@@ -13,10 +13,9 @@
 * from host or lxc sub-system
 */
 
-#include "opkg_utils.h"
-#include "swmod_opkg.h"
-#include "swmod_host.h"
+#include "swmod.h"
 #include "tools.h"  // run_cmd
+#include "swmod_uci.h"
 
 #ifdef SWMOD_LXC
 #include "swmod_lxc.h"
@@ -26,502 +25,173 @@
 #include "swmod_crun.h"
 #endif
 
-int swmod_run_cmd(ExecEnv_t *ee, char *cmd, char *output, int out_len)
+int swmod_get_container_type(const char *du_type)
 {
-	/* Get Config from package_name.list */
-	int ret = 0;
+	int i;
 
-	if (cmd == NULL || ee->exists == false) {
-		PRINT_ERR("Either cmd is null or ee is disabled");
+	if (!du_type)
 		return -1;
-	}
-
-	switch(ee->ee_type) {
-		case EE_TYPE_HOST:
-		{
-			ret = run_cmd(cmd, output, out_len);
-		}
-		break;
-		case EE_TYPE_LXC:
-		{
-#ifdef SWMOD_LXC
-			ret = lxc_run_cmd(ee, cmd, output, out_len);
-#endif
-		}
-		break;
-		default:
-		{
-			PRINT_ERR("Invalid ee type %d", ee->ee_type);
-		}
-	}
-
-	return ret;
-}
-
-int swmod_install_package(ExecEnv_t *env, PkgInfo *pkg, char *output, int outlen)
-{
-	int ret = -1;
-
-	if (output == NULL) {
-		PRINT_ERR("output buffer is NULL");
-		return ret;
-	}
-
-	if (pkg == NULL) {
-		snprintf(output, outlen, "Internal Error");
-		return ret;
-	}
-
-	if (env->exists == false) {
-		snprintf(output, outlen, "ExecEnv not exists");
-		return ret;
-	}
-
-	PRINT_INFO("Installing [%s] in[%s]", pkg->url, env->name);
 
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-#ifdef SWMOD_CRUN
-		ret = swmod_crun_perform_install(pkg, output, outlen);
-#endif
-		break;
-	case EE_TYPE_LXC:
-#ifdef SWMOD_LXC
-		ret = swmod_lxc_install_update_remove_package(pkg, output, outlen, env->name, SWMOD_INSTALL);
-#else
-		ret = -1;
-#endif
-		break;
-	default:
-		ret = -1;
+	for (i = 0; i < DU_TYPE_MAX; i++) {
+		if (strcmp(du_type, swmod_config.ee_cap[i].spec) == 0)
+			return i;
 	}
 
-	return ret;
+	return -1;
 }
 
-int swmod_update_package(ExecEnv_t *env, PkgInfo *pkg, char *output, int outlen)
+bool swmod_du_type_capable(int type)
 {
-	int ret = -1;
-
-	if (env == NULL || output == NULL) {
-		PRINT_ERR("No environment or output buffer");
-		return ret;
-	}
-
-	if (pkg == NULL) {
-		snprintf(output, outlen, "Internal Error");
-		return ret;
-	}
-
-	if (env->exists == false) {
-		snprintf(output, outlen, "ExecEnv not exists");
-		return ret;
-	}
-
-	PRINT_INFO("update [%s] in[%s]", pkg->url, env->name);
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-#ifdef SWMOD_CRUN
-		snprintf(output, outlen, "DU update not supported on Host system");
-#endif
-		break;
-	case EE_TYPE_LXC:
-#ifdef SWMOD_LXC
-		ret = swmod_lxc_install_update_remove_package(pkg, output, outlen, env->name, SWMOD_UPDATE);
-#else
-		ret = -1;
-#endif
-		break;
-	default:
-		ret = -1;
-	}
+	if (strlen(swmod_config.ee_cap[type].spec) != 0)
+		return true;
 
-	return ret;
+	return false;
 }
 
-int swmod_remove_package(ExecEnv_t *env, const PkgInfo *pkg, char *output, int outlen)
+int swmod_check_capability(ExecEnvCap_t *capab)
 {
 	int ret = -1;
+	int i;
+	char buff[256] = {0};
 
-	if (env == NULL || output == NULL) {
-		PRINT_ERR("No environment or output buffer");
+	if (capab == NULL)
 		return ret;
-	}
-
-	if (pkg == NULL) {
-		snprintf(output, outlen, "Internal Error");
-		return ret;
-	}
 
-	if (env->exists == false) {
-		snprintf(output, outlen, "ExecEnv not exists");
-		return ret;
-	}
-
-	PRINT_INFO("remove [%s] from[%s]", pkg->url, env->name);
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-#ifdef SWMOD_CRUN
-		ret = swmod_crun_perform_remove(pkg->url, output, outlen);
-#endif
-		break;
-	case EE_TYPE_LXC:
+	for (i = 0; i < DU_TYPE_MAX; i++) {
+		memset(&capab[i], 0, sizeof(ExecEnvCap_t));
+
+		switch (i) {
+		case DU_TYPE_CRUN:
+			run_cmd("crun -V 2>/dev/null | grep spec:", buff, sizeof(buff));
+			if (strlen(buff) != 0) {
+				sscanf(buff, "spec: %255s", capab[i].ver);
+				snprintf(capab[i].spec, sizeof(capab[i].spec), "OCIImage");
+				snprintf(capab[i].uri, sizeof(capab[i].uri),
+					"https://github.com/opencontainers/runtime-spec/releases/download/v%s", capab[i].ver);
+				ret = 0;
+			}
+			break;
+		case DU_TYPE_LXC:
 #ifdef SWMOD_LXC
-		ret = swmod_lxc_install_update_remove_package(pkg, output, outlen, env->name, SWMOD_REMOVE);
-#else
-		ret = -1;
+			snprintf(capab[i].ver, sizeof(capab[i].ver), "%s", swmod_get_lxc_version());
+			snprintf(capab[i].spec, sizeof(capab[i].spec), "LXC");
+			snprintf(capab[i].uri, sizeof(capab[i].uri), "https://linuxcontainers.org/lxc");
+			ret = 0;
 #endif
-		break;
-	default:
-		ret = -1;
+			break;
+		default:
+			ret = -1;
+		}
 	}
 
 	return ret;
 }
 
-void swmod_change_ee_state(ExecEnv_t *env, char *state, struct blob_buf *bb)
-{
-	if (bb == NULL)
-		return;
-	if (env == NULL || state == NULL) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "Insufficient information");
-		return;
-	}
-
-	if (env->exists == false) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "ExecEnv not exists");
-		return;
-	}
-
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-	{
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "request can not be performed on host system");
-		break;
-	}
-	case EE_TYPE_LXC:
-	{
-#ifdef SWMOD_LXC
-		int err;
-
-		PRINT_INFO("changing state of [%s] to [%s]", env->name, state);
-		err = swmod_set_lxc_ee_state(env, state, swmod_config.lxc_bundle_root);
-		blobmsg_add_u8(bb, "status", (err == 0) ? true : false);
-		blobmsg_add_string(bb, "reason", ee_state_failure_reason(err));
-#else
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "LXC service not present");
-#endif
-		break;
-	}
-	default:
-		break;
-	}
-
-	return;
-}
-
-void populate_execution_unit(ExecEnv_t *env)
+void swmod_sync_envs(void)
 {
-	if (env == NULL)
-		return;
+	struct uci_section *s = NULL;
+	struct uci_section *d = NULL;
+	struct list_head du_head;
 
-	if (env->exists == false)
-		return;
-
-	INIT_LIST_HEAD(&env->eu_list);
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-		/* Host system */
-#ifdef SWMOD_CRUN
-		populate_crun_eu(env, swmod_config.oci_bundle_root);
-#endif
-		break;
-	case EE_TYPE_LXC:
-		/* Linux containers */
-#ifdef SWMOD_LXC
-		populate_lxc_eu(env, swmod_config.lxc_bundle_root);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-void swmod_get_pid_detail(ExecEnv_t *env, int pid, char *cmdline, int cmd_len, int *vsize)
-{
-	if (env == NULL || cmdline == NULL || vsize == NULL)
+	if (swmod_uci_init(STD_UCI_PATH) != 0)
 		return;
 
-	switch (env->ee_type) {
-	case EE_TYPE_LXC:
-#ifdef SWMOD_LXC
-		get_pid_details_lxc(env, pid, cmdline, cmd_len, vsize);
-#endif
-		break;
-	case EE_TYPE_HOST:
-		break;
-	default:
-		break;
-	}
-}
+	memset(&du_head, 0, sizeof(struct list_head));
+	INIT_LIST_HEAD(&du_head);
 
-void swmod_set_service_state(ExecEnv_t *env, char *name, bool state, struct blob_buf *bb)
-{
-	if (bb == NULL) {
-		PRINT_ERR("Status buffer is null");
-		return;
-	}
+	swmod_uci_foreach_section(SWMOD_UCI_FILE, "execenv", s) {
+		const char *name = swmod_uci_get_value_by_section(s, "name");
 
-	if (env == NULL) {
-		PRINT_ERR("No environment info received");
-		return;
-	}
+		if (!dir_exist(name)) {
+			swmod_uci_foreach_section(SWMOD_UCI_FILE, "du_eu_assoc", d) {
+				const char *ee_name = swmod_uci_get_value_by_section(d, "ee_name");
 
-	if (env->exists == false) {
-		PRINT_ERR("No environment exists");
-		return;
-	}
-
-	if (name == NULL) {
-		PRINT_ERR("No eu name found");
-		return;
-	}
+				if (strcmp(ee_name, name) != 0)
+					continue;
 
-	int err = -1;
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-#ifdef SWMOD_CRUN
-		err = swmod_set_crun_service_state(env, name, state, swmod_config.oci_bundle_root);
-#endif
-		break;
-	case EE_TYPE_LXC:
-#ifdef SWMOD_LXC
-		err = swmod_set_lxc_service_state(env, name, state, swmod_config.lxc_bundle_root);
-#endif
-		break;
-	default:
-		break;
-	}
+				swmod_uci_delete_by_section(d, NULL, NULL);
+			}
 
-	if (err != 0) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "Internal Error");
-	} else {
-		blobmsg_add_u8(bb, "status", true);
-		blobmsg_add_string(bb, "reason", "");
+			swmod_uci_delete_by_section(s, NULL, NULL);
+		} else {
+			/* EE exist in device, check if all DU-EUs are updated and reset run level */
+			const char *eu_runlevel = swmod_uci_get_value_by_section(s, "initial_eu_runlevel");
+			swmod_reset_ee_runlevel(s);
+			swmod_get_du_list(name, eu_runlevel, &du_head);
+		}
 	}
 
-	return;
-}
-
-void swmod_get_env_info(ExecEnv_t *env)
-{
-	if (env == NULL)
-		return;
+	swmod_update_du_eu_assoc(&du_head);
+	swmod_uci_fini(SWMOD_UCI_FILE);
 
-	switch (env->ee_type) {
-	case EE_TYPE_LXC:
-#ifdef SWMOD_LXC
-		get_lxc_environment_info(env, swmod_config.lxc_bundle_root);
-#endif
-		break;
-	case EE_TYPE_HOST:
-		get_host_system_info(env);
-		break;
-	default:
-		break;
-	}
+	swmod_free_du_list(&du_head);
 }
 
-void swmod_set_ee_alias(ExecEnv_t *env, const char *alias, struct blob_buf *bb)
+void swmod_du_pending_uninstallation(void)
 {
+	struct uci_section *s = NULL;
 
-	if (bb == NULL)
+	if (swmod_uci_init(STD_UCI_PATH) != 0)
 		return;
 
-	if (env == NULL || alias == NULL) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "Insufficient information");
-		return;
-	}
-
-	if (env->exists == false) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "ExecEnv not exists");
-		return;
-	}
+	swmod_uci_foreach_section(SWMOD_UCI_FILE, "du_eu_assoc", s) {
+		const char *status = swmod_uci_get_value_by_section(s, "status");
 
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "Set alias for Host is not allowed");
-		break;
-	case EE_TYPE_LXC:
-	{
-#ifdef SWMOD_LXC
-		int ret = set_lxc_alias(env->name, alias, swmod_config.lxc_bundle_root);
-		if (ret != 0) {
-			blobmsg_add_u8(bb, "status", false);
-			blobmsg_add_string(bb, "reason", "ExecEnv is unknown");
-		} else {
-			blobmsg_add_u8(bb, "status", true);
-			blobmsg_add_string(bb, "reason", "");
+		if (strcmp(status, "Uninstalling") == 0) {
+			swmod_du_remove(s);
 		}
-#else
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "ExecEnv is unknown");
-#endif
-	}
-		break;
-	default:
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "ExecEnv is unknown");
 	}
 
-	return;
+	swmod_uci_fini(SWMOD_UCI_FILE);
 }
 
-void swmod_set_du_alias(ExecEnv_t *env, const char *uuid, const char *alias, struct blob_buf *bb)
+void swmod_execenv_actions(void)
 {
-	int ret = -1;
+	struct uci_section *s = NULL;
 
-	if (bb == NULL)
+	if (swmod_uci_init(STD_UCI_PATH) != 0)
 		return;
 
-	if (env == NULL || alias == NULL || uuid == NULL) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "Insufficient information");
-		return;
-	}
+	swmod_uci_foreach_section(SWMOD_UCI_FILE, "execenv", s) {
+		const char *action = swmod_uci_get_value_by_section(s, "action");
 
-	if (env->exists == false) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "ExecEnv not exists");
-		return;
-	}
+		if (strcmp(action, "add") == 0) {
+			swmod_execenv_add(s);
+			continue;
+		}
 
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-#ifdef SWMOD_CRUN
-		ret = set_du_alias_to_config(env->name, uuid, alias,
-					swmod_config.oci_bundle_root, SWMOD_OCI_DU_UCI);
-#endif
-		break;
-	case EE_TYPE_LXC:
-#ifdef SWMOD_LXC
-		ret = set_du_alias_to_config(env->name, uuid, alias,
-					swmod_config.lxc_bundle_root, SWMOD_LXC_DU_UCI);
-#endif
-		break;
-	default:
-		PRINT_ERR("Unknown ENV type");
-	}
+		if (strcmp(action, "remove") == 0) {
+			swmod_execenv_remove(s, false);
+			continue;
+		}
 
-	if (ret != 0) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "DU is unknown");
-	} else {
-		blobmsg_add_u8(bb, "status", true);
-		blobmsg_add_string(bb, "reason", "");
+		if (strcmp(action, "force_remove") == 0) {
+			swmod_execenv_remove(s, true);
+			continue;
+		}
 	}
 
-	return;
+	swmod_uci_fini(SWMOD_UCI_FILE);
 }
 
-void swmod_set_eu_alias(ExecEnv_t *env, const char *eu_name, const char *alias, struct blob_buf *bb)
+void swmod_stop_execunit(const char *env, const char *eu_name, const char *du_type)
 {
-	int ret = -1;
-
-	if (bb == NULL)
-		return;
-
-	if (env == NULL || alias == NULL || eu_name == NULL) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "Insufficient information");
+	if (!eu_name || !env || !du_type)
 		return;
-	}
 
-	if (env->exists == false) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "ExecEnv not exists");
-		return;
-	}
+	int type = swmod_get_container_type(du_type);
 
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-#ifdef SWMOD_CRUN
-		ret = set_eu_alias_to_config(env->name, eu_name, alias,
-					swmod_config.oci_bundle_root, SWMOD_OCI_DU_UCI);
-#endif
+	switch (type) {
+	case DU_TYPE_CRUN:
+		swmod_set_crun_state(eu_name, EU_STOP);
 		break;
-	case EE_TYPE_LXC:
+	case DU_TYPE_LXC:
 #ifdef SWMOD_LXC
-		ret = set_eu_alias_to_config(env->name, eu_name, alias,
-					swmod_config.lxc_bundle_root, SWMOD_LXC_DU_UCI);
+		swmod_set_lxc_state(eu_name, env, EU_STOP);
 #endif
 		break;
-	default:
-		PRINT_ERR("Unknown ENV type");
-	}
-
-	if (ret != 0) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "EU is unknown");
-	} else {
-		blobmsg_add_u8(bb, "status", true);
-		blobmsg_add_string(bb, "reason", "");
 	}
 
 	return;
 }
 
-void swmod_set_eu_autostart(ExecEnv_t *env, const char *eu_name, bool enable, struct blob_buf *bb)
-{
-	int ret = -1;
-
-	if (bb == NULL)
-		return;
-
-	if (env == NULL || eu_name == NULL) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "Insufficient information");
-		return;
-	}
-
-	if (env->exists == false) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "ExecEnv not exists");
-		return;
-	}
-
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-#ifdef SWMOD_CRUN
-		ret = set_eu_autostart_to_config(env->name, eu_name, enable,
-					swmod_config.oci_bundle_root, SWMOD_OCI_DU_UCI);
-#endif
-		break;
-	case EE_TYPE_LXC:
-#ifdef SWMOD_LXC
-		ret = set_eu_autostart_to_config(env->name, eu_name, enable,
-					swmod_config.lxc_bundle_root, SWMOD_LXC_DU_UCI);
-#endif
-		break;
-	default:
-		PRINT_ERR("Unknown ENV type");
-	}
-
-	if (ret != 0) {
-		blobmsg_add_u8(bb, "status", false);
-		blobmsg_add_string(bb, "reason", "EU is unknown");
-	} else {
-		blobmsg_add_u8(bb, "status", true);
-		blobmsg_add_string(bb, "reason", "");
-	}
-
-	return;
-}
diff --git a/src/swmod_api.h b/src/swmod_api.h
index 32b93bdc7a5f04e2a90576d09d50e33a4054b931..dfe5780afbd151f0946ee428ee52e55f21721fa0 100644
--- a/src/swmod_api.h
+++ b/src/swmod_api.h
@@ -10,22 +10,14 @@
 
 #ifndef __SWMOD_API_H
 #define __SWMOD_API_H
-#include <stdbool.h>
 #include "swmod.h"
-#include "tools.h"
 
-int swmod_run_cmd(ExecEnv_t *ee, const char *cmd, char *output, int out_len);
-int swmod_install_package(ExecEnv_t *env, PkgInfo *pkg, char *output, int outlen);
-int swmod_update_package(ExecEnv_t *env, PkgInfo *pkg, char *output, int outlen);
-int swmod_remove_package(ExecEnv_t *env, const PkgInfo *pkg, char *output, int outlen);
-void swmod_change_ee_state(ExecEnv_t *env, char *state, struct blob_buf *bb);
-void populate_execution_unit(ExecEnv_t *env);
-void swmod_get_pid_detail(ExecEnv_t *env, int pid, char *cmdline, int cmd_len, int *vsize);
-void swmod_set_service_state(ExecEnv_t *env, char *name, bool state, struct blob_buf *bb);
-void swmod_get_env_info(ExecEnv_t *env);
-void swmod_set_ee_alias(ExecEnv_t *env, const char *alias, struct blob_buf *bb);
-void swmod_set_du_alias(ExecEnv_t *env, const char *uuid, const char *alias, struct blob_buf *bb);
-void swmod_set_eu_alias(ExecEnv_t *env, const char *eu_name, const char *alias, struct blob_buf *bb);
-void swmod_set_eu_autostart(ExecEnv_t *env, const char *eu_name, bool enable, struct blob_buf *bb);
+int swmod_check_capability(ExecEnvCap_t *capab);
+void swmod_sync_envs(void);
+void swmod_execenv_actions(void);
+void swmod_du_pending_uninstallation(void);
+bool swmod_du_type_capable(int type);
+void swmod_stop_execunit(const char *env, const char *eu, const char *du_type);
+int swmod_get_container_type(const char *du_type);
 
 #endif //__SWMOD_API_H
diff --git a/src/swmod_common.h b/src/swmod_common.h
index 261119b20caa0c459224efd9387cfdbe257e987f..8df03fa49621d03447606cdf0c49cfb385c294fa 100644
--- a/src/swmod_common.h
+++ b/src/swmod_common.h
@@ -11,12 +11,13 @@
 #ifndef SWMOD_COMMON_H
 #define SWMOD_COMMON_H
 
-#include <uci.h>
+#include <stdbool.h>
 
-#define PARENT_EEID	1
-#define PROC_PATH "/proc"
-#define DW_TMP_DIR_PATH "/tmp"
-#define DW_PKG_LOCAL_PATH DW_TMP_DIR_PATH"/dw_package.ipk"
+enum eu_state {
+	EU_STOP,
+	EU_START,
+	__SWMOD_EU_STATE_MAX
+};
 
 enum swmod_du_opration_enum {
 	SWMOD_INSTALL,
@@ -26,14 +27,16 @@ enum swmod_du_opration_enum {
 };
 
 typedef struct {
-	time_t start;
 	char url[2049];
 	char uname[257];
 	char psw[257];
 	char uuid[37];
-	char env_name[32];
+	char du_name[256];
+	char version[32];
+	char execenv[256];
+	int du_type;
 	int operation;
-	struct uci_section *section;
+	bool autostart;
 } PkgInfo;
 
 bool memory_available(unsigned long req_kb, const char *dst);
diff --git a/src/swmod_crun.c b/src/swmod_crun.c
index bb01720b98382900af4be6cefe651ae9eb50bb67..05304f4027f7fa6e11bce821399767ee16319b17 100644
--- a/src/swmod_crun.c
+++ b/src/swmod_crun.c
@@ -9,747 +9,28 @@
  */
 
 #include <stdio.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <sys/sysinfo.h>
-#include <sys/utsname.h>
-#include <sys/statvfs.h>
+#include <stdlib.h>
+#include <string.h>
 
-#include "tools.h"
-#include "swmod_uci.h"
-#include "swmod_crun.h"
 #include "swmod_common.h"
+#include "swmod_crun.h"
+#include "tools.h"
 
-static char* get_container_status(const char *c_name)
-{
-	if (c_name == NULL) {
-		return "Error";
-	}
-
-	char cmd[MAX_BUFFER_LEN] = {0};
-	char output[MAX_BUFFER_LEN] = {0};
-
-	snprintf(cmd, sizeof(cmd), "crun state %s 2>&1 | grep status", c_name);
-
-	if (run_cmd(cmd, output, sizeof(output)) != 0) {
-		PRINT_ERR("Failed to read container status");
-		return "Error";
-	}
-
-	if (strlen(output) == 0) {
-		PRINT_ERR("Container status not found");
-		return "Error";
-	}
-
-	if (strstr(output, "error opening") != NULL) {
-		return "Error";
-	}
-
-	if (strstr(output, "\"status\": \"created\"") != NULL) {
-		return "Disabled";
-	}
-
-	if (strstr(output, "\"status\": \"paused\"") != NULL) {
-		return "Paused";
-	}
-
-	return "Up";
-}
-
-static int get_container_pid(const char *c_name)
-{
-	if (c_name == NULL) {
-		return -1;
-	}
-
-	char cmd[MAX_BUFFER_LEN] = {0};
-	char output[MAX_BUFFER_LEN] = {0};
-
-	snprintf(cmd, sizeof(cmd), "crun state %s 2>&1 | grep pid", c_name);
-
-	if (run_cmd(cmd, output, sizeof(output)) != 0) {
-		PRINT_ERR("Failed to read container pid");
-		return -1;
-	}
-
-	if (strlen(output) == 0) {
-		PRINT_DEBUG("Container pid not found");
-		return -1;
-	}
-
-	if (strstr(output, "error opening") != NULL) {
-		return -1;
-	}
-
-	int pid = -1;
-	char *tmp = strstr(output, "\"pid\":");
-	if (tmp != NULL) {
-		sscanf(tmp, "\"pid\": %d", &pid);
-	}
-
-	return pid;
-}
-
-static int crun_run_cmd(const char *ct_name, char *sub_cmd, char *output, size_t len)
-{
-	if (ct_name == NULL || sub_cmd == NULL) {
-		return -1;
-	}
-
-	char cmd[MAX_BUFFER_LEN] = {0};
-	if ((strlen(ct_name) + strlen(sub_cmd) + 11) >= sizeof(cmd)) {
-		PRINT_ERR("Command length too large");
-		return -1;
-	}
-
-	snprintf(cmd, sizeof(cmd), "crun exec %s %s", ct_name, sub_cmd);
-	return run_cmd(cmd, output, len);
-}
-
-static void get_memory_info(const char *ct_name, int *avail_mem, int *alloc_mem)
-{
-	char cmd[1024] = {0};
-	char output[1024] = {0};
-
-	if (ct_name == NULL) {
-		return;
-	}
-
-	snprintf(cmd, sizeof(cmd), "grep MemTotal /proc/meminfo");
-	if (crun_run_cmd(ct_name, cmd, output, sizeof(output)) != 0) {
-		return;
-	}
-
-	if (strstr(output, "MemTotal:") != NULL) {
-		sscanf(output, "MemTotal:%d", alloc_mem);
-	}
-
-	memset(output, 0, sizeof(output));
-	snprintf(cmd, sizeof(cmd), "grep MemFree /proc/meminfo");
-	if (crun_run_cmd(ct_name, cmd, output, sizeof(output)) != 0) {
-		return;
-	}
-
-	if (strstr(output, "MemFree:") != NULL) {
-		sscanf(output, "MemFree:%d", avail_mem);
-	}
-}
-
-static void get_disk_space_info(const char *ct_name, int *avail_disk, int *alloc_disk)
-{
-	char cmd[1024] = {0};
-	char output[MAX_BUFFER_LEN] = {0};
-
-	if (ct_name == NULL) {
-		return;
-	}
-
-	snprintf(cmd, sizeof(cmd), "df -P / | tail -n +2");
-	if (crun_run_cmd(ct_name, cmd, output, sizeof(output)) != 0) {
-		return;
-	}
-
-	if (strlen(output) == 0)
-		return;
-
-	char filesystem[255] = {0};
-	int used_disk = 0;
-	sscanf(output, "%254s %d %d %d", filesystem, alloc_disk, &used_disk, avail_disk);
-}
-
-static void get_host_info(const char *ct_name, char *vendor, int vend_len, char *ver, int ver_len)
-{
-	char cmd[1024] = {0};
-	char output[MAX_BUFFER_LEN] = {0};
-
-	if (ct_name == NULL || vendor == NULL || ver == NULL) {
-		return;
-	}
-
-	snprintf(cmd, sizeof(cmd), "uname -n");
-	if (crun_run_cmd(ct_name, cmd, output, sizeof(output)) != 0) {
-		return;
-	}
-
-	if (strlen(output) != 0) {
-		strncpy(vendor, output, vend_len);
-		remove_new_line(vendor);
-	}
-
-	memset(output, 0, sizeof(output));
-	snprintf(cmd, sizeof(cmd), "uname -r");
-	if (crun_run_cmd(ct_name, cmd, output, sizeof(output)) != 0) {
-		return;
-	}
-
-	if (strlen(output) != 0) {
-		strncpy(ver, output, ver_len);
-		remove_new_line(ver);
-	}
-}
-
-static bool validate_args(const char *url, char *output, int out_len)
-{
-	if (output == NULL || out_len <= 0) {
-		return false;
-	}
-
-	if (url == NULL) {
-		snprintf(output, out_len, "Package path not given");
-		return false;
-	}
-
-	if (url[0] == '\0') {
-		snprintf(output, out_len, "Package path not given");
-		return false;
-	}
-
-	return true;
-}
-
-static int get_filename_from_url(const char *url, char *filename, int len)
-{
-	if (url == NULL || filename == NULL)
-		return -1;
-
-	memset(filename, 0, len);
-
-	char *tmp = strrchr(url, '/');
-	if (tmp == NULL) {
-		tmp = (char*)url;
-	} else {
-		if (tmp == (url + strlen(url) - 1)) {
-			return -1;
-		} else {
-			tmp = tmp + 1;
-		}
-	}
-
-	snprintf(filename, len, "%s", tmp);
-	char *tmp2 = strchr(filename, ':');
-	if (tmp2)
-		*tmp2 = '\0';
-
-	tmp2 = strchr(filename, '.');
-	if (tmp2)
-		*tmp2 = '\0';
-
-	tmp2 = strchr(filename, '@'); /* for docker image there could be @sha after name */
-	if (tmp2)
-		*tmp2 = '\0';
-
-	return 0;
-}
-
-static int swmod_crun_install_tar_package(const PkgInfo *pkg, const char *name, char *output, int out_len)
-{
-	int ret = -1;
-	char package_path[2049] = {0};
-	bool remote_file = false;
-
-	if (pkg == NULL || name == NULL || output == NULL) {
-		return ret;
-	}
-
-	if (strlen(pkg->url) == 0) {
-		snprintf(output, out_len, "Package URL not found");
-		return ret;
-	}
-
-	if (strlen(pkg->uuid) == 0) {
-		snprintf(output, out_len, "Package UUID not found");
-		return ret;
-	}
-
-	if (pkg->section == NULL) {
-		snprintf(output, out_len, "Internal Error");
-		return ret;
-	}
-
-	swmod_uci_set_value_by_section(pkg->section, "du_status", "Installing_start");
-
-	if (strstr(pkg->url, "file://") != NULL) {
-		//local package
-		snprintf(package_path, sizeof(package_path), "%s", pkg->url+6);
-		if (strlen(package_path) == 0) {
-			snprintf(output, out_len, "Invalid package name");
-			return ret;
-		}
-
-		// get filesize
-		unsigned long size = get_file_size_kb(package_path);
-		if (size == 0) {
-			snprintf(output, out_len, "Failed to read package info or package not exist");
-			return ret;
-		}
-
-		/* we need atleast twice the pkg size space in bundle root to extract the tar */
-		if (!memory_available(size * 2, swmod_config.oci_bundle_root)) {
-			snprintf(output, out_len, "No enough space in system to extract the package");
-			return ret;
-		}
-	} else {
-		remote_file = true;
-		unsigned long size = get_remote_file_size(pkg->url, pkg->uname, pkg->psw);
-		if (size == 0) {
-			snprintf(output, out_len, "Failed to read package info or package is empty");
-			return ret;
-		}
-
-		if (!memory_available(size, DW_TMP_DIR_PATH)) {
-			snprintf(output, out_len, "No enough space in system to download the package");
-			return ret;
-		}
-
-		/* we need atleast twice the pkg size space in bundle root to extract the tar */
-		if (!memory_available(size * 2, swmod_config.oci_bundle_root)) {
-			snprintf(output, out_len, "No enough space in system to extract the package");
-			return ret;
-		}
-
-		snprintf(package_path, sizeof(package_path), "%s/%s.tar", DW_TMP_DIR_PATH, name);
-		if (0 != download_remote_package(pkg->url, pkg->uname, pkg->psw, package_path)) {
-			snprintf(output, out_len, "Package download failed from %s", pkg->url);
-			goto err;
-		}
-	}
-
-	char bundle_path[MAX_LEN_1024] = {0};
-	snprintf(bundle_path, sizeof(bundle_path), "%s/%s", swmod_config.oci_bundle_root, name);
-	if (dir_exist(bundle_path)) {
-		snprintf(output, out_len, "DU name %s already exist", name);
-		goto err;
-	}
-
-	if (!create_dir(bundle_path)) {
-		snprintf(output, out_len, "Failed to create dir %s", bundle_path);
-		goto err;
-	}
-
-	char cmd[MAX_LEN_256] = {0};
-	snprintf(cmd, sizeof(cmd), "tar -xf %s -C %s", package_path, bundle_path);
-	if (0 != run_cmd_no_output(cmd)) {
-		snprintf(output, out_len, "Failed to extract package at %s", bundle_path);
-		snprintf(cmd, sizeof(cmd), "rm -rf %s", bundle_path);
-		run_cmd_no_output(cmd);
-		goto err;
-	}
-
-	ret = 0;
-	snprintf(output, out_len, "Tar %s installed", name);
-
-err:
-	if (remote_file && (strlen(package_path) != 0) && file_exists(package_path))
-		remove(package_path);
-
-	return ret;
-}
-
-struct service_input_arg {
-	const char *instance;
-	char *error;
-	int buf_size;
-};
-
-void read_fault_code(struct ubus_request *req, int type, struct blob_attr *msg)
-{
-	if (req == NULL || msg == NULL)
-		return;
-
-	struct service_input_arg *args = (struct service_input_arg *)req->priv;
-	if (args == NULL)
-		return;
-
-	if (args->instance == NULL || args->error == NULL)
-		return;
-
-	snprintf(args->error, args->buf_size, "NoFault");
-
-	enum {
-		SERVICE_NAME,
-		__SERVICE_MAX
-	};
-
-	enum {
-		P_RUN,
-		__P_MAX
-	};
-
-	const struct blobmsg_policy service_policy[__SERVICE_MAX] = {
-		[SERVICE_NAME] = { .name = "crun", .type = BLOBMSG_TYPE_TABLE },
-	};
-
-	const struct blobmsg_policy p[__P_MAX] = {
-		[P_RUN] = { .name = "running", .type = BLOBMSG_TYPE_BOOL },
-	};
-
-	struct blob_attr *tb[ARRAY_SIZE(service_policy)];
-
-	if (blobmsg_parse(service_policy, ARRAY_SIZE(service_policy), tb, blob_data(msg), blob_len(msg)) != 0)
-		return;
-
-	if (!tb[SERVICE_NAME])
-		return;
-
-	struct blob_attr *data = tb[SERVICE_NAME];
-	struct blob_attr *instances, *inst;
-	size_t rem, rem2;
-
-	blobmsg_for_each_attr(instances, data, rem) {
-		if (strcmp(blobmsg_name(instances), "instances") != 0)
-			continue;
-
-		blobmsg_for_each_attr(inst, instances, rem2) {
-			if (strcmp(blobmsg_name(inst), args->instance) != 0)
-				continue;
-
-			struct blob_attr *tb2[__P_MAX] = {NULL};
-			if (blobmsg_parse(p, __P_MAX, tb2, blobmsg_data(inst), blobmsg_len(inst)) != 0)
-				break;
-
-			if (tb2[P_RUN] && blobmsg_get_bool(tb2[P_RUN]) == false)
-				snprintf(args->error, args->buf_size, "FailureOnStart");
-
-			break;
-		}
-		break;
-	}
-}
-
-static void get_crun_fault_code(const char *name, char *fault, int buf_len)
-{
-	uint32_t id;
-	struct service_input_arg input;
-
-	if (fault == NULL)
-		return;
-
-	memset(fault, 0, buf_len);
-
-	if (name == NULL)
-		return;
-
-	if (ubus_ctx == NULL)
-		return;
-
-	memset(&input, 0, sizeof(struct service_input_arg));
-	input.instance = name;
-	input.error = fault;
-	input.buf_size = buf_len;
-
-	struct blob_buf b;
-	memset(&b, 0, sizeof(struct blob_buf));
-
-	blob_buf_init(&b, 0);
-	blobmsg_add_string(&b, "name", "crun");
-
-	if (!ubus_lookup_id(ubus_ctx, "service", &id))
-		ubus_invoke(ubus_ctx, id, "list", b.head, read_fault_code, &input, UBUS_TIMEOUT);
-
-	blob_buf_free(&b);
-}
-
-int swmod_crun_perform_install(const PkgInfo *pkg, char *output, int out_len)
-{
-	int ret = -1;
-	char filename[64] = {0};
-
-	if (output == NULL)
-		return ret;
-
-	if (pkg == NULL) {
-		snprintf(output, out_len, "Internal Error");
-		return ret;
-	}
-
-	if (validate_args(pkg->url, output, out_len) == false)
-		return ret;
-
-	if (get_filename_from_url(pkg->url, filename, sizeof(filename)) != 0) {
-		snprintf(output, out_len, "Invalid filename in %s", pkg->url);
-		return ret;
-	}
-
-	char bundle_path[MAX_LEN_1024] = {0};
-	snprintf(bundle_path, sizeof(bundle_path), "%s/%s", swmod_config.oci_bundle_root, filename);
-
-	if (dir_exist(bundle_path)) {
-		snprintf(output, out_len, "DU name %s already exist", filename);
-		return ret;
-	}
-
-	snprintf(output, out_len, "Container %s to be installed", filename);
-	ret = 0;
-
-	char *tmp = strrchr(pkg->url, '.');
-	if (tmp != NULL && strcmp(tmp, ".tar") == 0) {
-		/* This is a tar package so need to extract */
-		PRINT_DEBUG("Doing DU install with tar");
-		ret = swmod_crun_install_tar_package(pkg, filename, output, out_len);
-	}
-
-	return ret;
-}
-
-int swmod_crun_perform_remove(const char *ct_name, char *output, int out_len)
-{
-	(void)ct_name;
-	if (output == NULL || out_len == 0)
-		return -1;
-
-	// Bundle will be deleted externally
-	snprintf(output, out_len, "Container %s uninstalled", ct_name);
-	return 0;
-}
-
-void populate_crun_eu(ExecEnv_t *ee, const char *oci_uci_path)
-{
-	if (ee == NULL) {
-		PRINT_ERR("No environment information given");
-		return;
-	}
-
-	if (ee->name[0] == '\0') {
-		PRINT_ERR("Environment name unknown");
-		return;
-	}
-
-	if (oci_uci_path == NULL || strlen(oci_uci_path) == 0) {
-		PRINT_ERR("OCI DU UCI file unknown");
-		return;
-	}
-
-	if (0 != swmod_uci_init(oci_uci_path)) {
-		return;
-	}
-
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(SWMOD_OCI_DU_UCI, "du_eu_assoc", stmp, s) {
-		const char *type = swmod_uci_get_value_by_section(s, "type");
-		const char *status = swmod_uci_get_value_by_section(s, "du_status");
-		if (strcmp(type, "crun") == 0 && strcmp(status, "Installed") == 0) {
-			ExecUnit new;
-			memset(&new, 0, sizeof(ExecUnit));
-			new.eu_exists = true;
-
-			const char *name = swmod_uci_get_value_by_section(s, "eu_name");
-			swmod_strncpy(new.name, name, sizeof(new.name));
-
-			const char *alias = swmod_uci_get_value_by_section(s, "eu_alias");
-			swmod_strncpy(new.eu_alias, alias, sizeof(new.eu_alias));
-
-			const char *ee_name = swmod_uci_get_value_by_section(s, "ee_name");
-			swmod_strncpy(new.environment, ee_name, sizeof(new.environment));
-
-			const char *du_name = swmod_uci_get_value_by_section(s, "name");
-			swmod_strncpy(new.du_name, du_name, sizeof(new.du_name));
-
-			const char *req_state = swmod_uci_get_value_by_section(s, "requested_state");
-			swmod_strncpy(new.req_state, req_state, sizeof(new.req_state));
-
-			const char *auto_start = swmod_uci_get_value_by_section(s, "autostart");
-			new.autostart = uci_str_to_bool(auto_start);
-
-			int pid = get_container_pid(name);
-			if (pid == -1) {
-				snprintf(new.euid, sizeof(new.euid), "Unknown");
-			} else {
-				snprintf(new.euid, sizeof(new.euid), "%d", pid);
-			}
-
-			char *ct_status = get_container_status(name);
-			if (strcmp(ct_status, "Up") == 0) {
-				swmod_strncpy(new.state, "Active", sizeof(new.state));
-
-				/* get memory space limits */
-				int avail_memory = 0, alloc_memory = 0;
-				get_memory_info(name, &avail_memory, &alloc_memory);
-				new.memory_space = alloc_memory;
-
-				/* get disk space info */
-				int avail_disk = 0, alloc_disk = 0;
-				get_disk_space_info(name, &avail_disk, &alloc_disk);
-				new.disk_space = alloc_disk;
-
-				/* get vendor and version info */
-				get_host_info(name, new.vendor, sizeof(new.vendor), new.version, sizeof(new.version));
-			} else {
-				swmod_strncpy(new.state, "Idle", sizeof(new.state));
-			}
-
-			swmod_strncpy(new.description, "This is a CRUN container", sizeof(new.description));
-			get_crun_fault_code(name, new.fault_code, sizeof(new.fault_code));
-			swmod_add_eu_in_list(&ee->eu_list, &new);
-		}
-	}
-
-	swmod_uci_fini(SWMOD_OCI_DU_UCI);
-}
-
-int swmod_set_crun_service_state(ExecEnv_t *ee, char *eu, bool state, const char *oci_uci_path)
-{
-	int ret = -1;
-
-	if (ee == NULL) {
-		PRINT_ERR("No environment information given");
-		return ret;
-	}
-
-	if (ee->name[0] == '\0') {
-		PRINT_ERR("Environment name unknown");
-		return ret;
-	}
-
-	if (eu == NULL) {
-		PRINT_ERR("No eu name information");
-		return ret;
-	}
-
-	if (oci_uci_path == NULL || strlen(oci_uci_path) == 0) {
-		PRINT_ERR("OCI DU uci path unknown");
-		return ret;
-	}
-
-	if (0 != swmod_uci_init(oci_uci_path)) {
-		return ret;
-	}
-
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(SWMOD_OCI_DU_UCI, "du_eu_assoc", stmp, s) {
-		const char *name = swmod_uci_get_value_by_section(s, "eu_name");
-		const char *ee_name = swmod_uci_get_value_by_section(s, "ee_name");
-
-		if (strcmp(name, eu) == 0 && strcmp(ee->name, ee_name) == 0) {
-			if (state) {
-				swmod_uci_set_value_by_section(s, "requested_state", "Active");
-				ret = 0;
-			} else {
-				swmod_uci_set_value_by_section(s, "requested_state", "Idle");
-				ret = 0;
-			}
-
-			break;
-		}
-	}
-
-	swmod_uci_fini(SWMOD_OCI_DU_UCI);
-	if (ret == 0) {
-		swmod_uci_commit("crun");
-	}
-
-	return ret;
-}
-
-enum du_status {
-	E_DU_INSTALL_SUCCESS,
-	E_DU_INSTALL_FAILED,
-	E_DU_UNINSTALL_SUCCESS,
-	E_DU_UNINSTALL_FAILED,
-	__DU_STATUS_MAX
-};
-
-char du_status_string[][MAX_LEN_64] = {
-	"Installing_success",
-	"Installing_failed",
-	"Uninstalling_success",
-	"Uninstalling_failed",
-};
-
-static int get_du_status(const char *str)
+void swmod_set_crun_state(const char *cont, int state)
 {
-	int i;
-
-	if (str == NULL)
-		return __DU_STATUS_MAX;
+	char cmd[2056] = {0};
 
-	for (i = E_DU_INSTALL_SUCCESS; i < __DU_STATUS_MAX; i++) {
-		if (strcmp(str, du_status_string[i]) == 0)
-			return i;
-	}
-
-	return __DU_STATUS_MAX;
-}
-
-static void swmod_handle_crun_du_state(struct uci_section *s)
-{
-	if (s == NULL)
+	if (!cont)
 		return;
 
-	int code = 7002;
-	const char *fault_code = NULL, *fault_str = NULL;
-
-	const char *s_time = swmod_uci_get_value_by_section(s, "start_time");
-	const char *uuid = swmod_uci_get_value_by_section(s, "uuid");
-	const char *version = swmod_uci_get_value_by_section(s, "version");
-	const char *status = swmod_uci_get_value_by_section(s, "du_status");
-
-	time_t start_time = convert_str_to_time(s_time);
-	time_t end_time = time(NULL);
-
-	int state = get_du_status(status);
-
 	switch (state) {
-	case E_DU_INSTALL_SUCCESS:
-		swmod_uci_set_value_by_section(s, "du_status", "Installed");
-		swmod_send_event_du_state_change(false, 0, start_time, end_time, uuid,
-					version, SWMOD_INSTALL, "");
-		break;
-	case E_DU_INSTALL_FAILED:
-		PRINT_ERR("DU Installation failed");
-		fault_code = swmod_uci_get_value_by_section(s, "fault_code");
-		fault_str = swmod_uci_get_value_by_section(s, "fault_string");
-		swmod_uci_delete_by_section(s, NULL, NULL);
-
-		if (strlen(fault_code) != 0)
-			code = (int)strtoul(fault_code, NULL, 10);
-
-		if (strlen(fault_str) == 0)
-			fault_str = "Internal Error, see log for more details";
-
-		swmod_send_event_du_state_change(true, code, start_time, end_time, uuid,
-					version, SWMOD_INSTALL, fault_str);
+	case EU_STOP:
+		snprintf(cmd, sizeof(cmd), "crun kill %s 9 2>/dev/null", cont);
+		run_cmd_no_output(cmd);
 		break;
-	case E_DU_UNINSTALL_SUCCESS:
-		swmod_uci_delete_by_section(s, NULL, NULL);
-		swmod_send_event_du_state_change(false, 0, start_time, end_time, uuid,
-					version, SWMOD_REMOVE, "");
+	case EU_START:
 		break;
-	case E_DU_UNINSTALL_FAILED:
-		PRINT_ERR("DU Uninstallation failed");
-		fault_code = swmod_uci_get_value_by_section(s, "fault_code");
-		fault_str = swmod_uci_get_value_by_section(s, "fault_string");
-		swmod_uci_set_value_by_section(s, "du_status", "Installed");
-
-		if (strlen(fault_code) != 0)
-			code = (int)strtoul(fault_code, NULL, 10);
-
-		if (strlen(fault_str) == 0)
-			fault_str = "Internal Error, see log for more details";
-
-		swmod_send_event_du_state_change(true, code, start_time, end_time, uuid,
-					version, SWMOD_REMOVE, fault_str);
-		break;
-	default:
-		PRINT_DEBUG("This sate has nothing to do");
 	}
 }
 
-void swmod_change_crun_du_state(const char *oci_uci_path)
-{
-	if (0 != swmod_uci_init(oci_uci_path)) {
-		return;
-	}
-
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(SWMOD_OCI_DU_UCI, "du_eu_assoc", stmp, s) {
-		const char *type = swmod_uci_get_value_by_section(s, "type");
-		if (strcmp(type, "crun") != 0) {
-			continue;
-		}
-
-		swmod_handle_crun_du_state(s);
-	}
 
-	swmod_uci_fini(SWMOD_OCI_DU_UCI);
-	return;
-}
diff --git a/src/swmod_crun.h b/src/swmod_crun.h
index 7ed09620d2cac1f733dd22636752c70f2ae8574c..a23e327a2fdf3b214dc6d7b30b4bbd7e43c9a135 100644
--- a/src/swmod_crun.h
+++ b/src/swmod_crun.h
@@ -13,12 +13,6 @@
 
 #include "swmod_common.h"
 
-int swmod_crun_perform_install(const PkgInfo *pkg, char *output, int out_len);
-int swmod_crun_perform_remove(const char *ct_name, char *output, int outlen);
-void populate_crun_eu(ExecEnv_t *ee, const char *oci_uci_path);
-int swmod_set_crun_service_state(ExecEnv_t *ee, char *eu, bool state, const char *oci_uci_path);
-void swmod_perform_crun_install(char *section, int len);
-void swmod_change_crun_du_state(const char *oci_uci_path);
-void read_fault_code(struct ubus_request *req, int type, struct blob_attr *msg);
+void swmod_set_crun_state(const char *cont, int state);
 
 #endif // SWMOD_CRUN_H
diff --git a/src/swmod_host.c b/src/swmod_host.c
deleted file mode 100644
index 74cd87a10ae93b57db629d46fd02bcf44c024cfb..0000000000000000000000000000000000000000
--- a/src/swmod_host.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * swmod_host.c: SWMOD deamon
- *
- * Copyright (C) 2020-2023 IOPSYS Software Solutions AB. All rights reserved.
- *
- * Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
- *
- * See LICENSE file for license related information.
- */
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <sys/sysinfo.h>
-#include <sys/utsname.h>
-#include <sys/statvfs.h>
-
-#include "tools.h"
-#include "swmod_uci.h"
-#include "swmod_host.h"
-#include "swmod.h"
-
-void get_host_system_info(ExecEnv_t *host_ee)
-{
-	if (host_ee == NULL)
-		return;
-
-	struct utsname utsname;
-
-	if (uname(&utsname) >= 0) {
-		swmod_strncpy(host_ee->type, "Virtual_EE", MAX_LEN_64);
-		swmod_strncpy(host_ee->vendor, utsname.nodename, MAX_LEN_128);
-		swmod_strncpy(host_ee->version, utsname.release, MAX_LEN_16);
-	}
-
-	struct sysinfo sinfo;
-
-	if (sysinfo(&sinfo) == 0) {
-		host_ee->allocated_memory = (sinfo.totalram / 1024);
-		host_ee->available_memory = (sinfo.freeram / 1024);
-	}
-
-	struct statvfs dinfo;
-	if (statvfs("/", &dinfo) == 0) {
-		host_ee->allocated_disk_space = (dinfo.f_bsize * dinfo.f_blocks) / 1024;
-		host_ee->available_disk_space = (dinfo.f_bsize * dinfo.f_bfree) / 1024;
-	} else {
-		host_ee->allocated_disk_space = 0;
-		host_ee->available_disk_space = 0;
-	}
-}
-
-void populate_host_system_environment(struct list_head *ee_head)
-{
-	ExecEnv_t host_ee;
-	memset(&host_ee, 0, sizeof(ExecEnv_t));
-
-	host_ee.exists = true;
-	host_ee.pause = 0;
-	host_ee.ee_type = EE_TYPE_HOST;
-	host_ee.autoboot = 1;
-	host_ee.eeid = PARENT_EEID;
-	host_ee.parent_eeid = 0;
-	swmod_strncpy(host_ee.name, HOST_SYSTEM, MAX_LEN_32);
-	swmod_strncpy(host_ee.status, "Up", MAX_LEN_32);
-
-	swmod_add_ee_in_list(ee_head, &host_ee);
-}
diff --git a/src/swmod_host.h b/src/swmod_host.h
deleted file mode 100644
index ce2164d85136fb548fd72408f36566962518da75..0000000000000000000000000000000000000000
--- a/src/swmod_host.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * swmod_host.h: Host specific details
- *
- * Copyright (C) 2020-2023 IOPSYS Software Solutions AB. All rights reserved.
- *
- * Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
- *
- * See LICENSE file for license related information.
- */
-
-#ifndef HOST_H
-#define HOST_H
-#include "swmod.h"
-#include <libubox/list.h>
-
-void populate_host_system_environment(struct list_head *ee_list);
-void get_host_system_info(ExecEnv_t *host_ee);
-
-#endif //HOST_H
diff --git a/src/swmod_lxc.c b/src/swmod_lxc.c
index 2f626ad19af74ee1adc77a13d502080d21218cee..176dc322e6b6f372702cafccf81aa91f26c2d0d3 100644
--- a/src/swmod_lxc.c
+++ b/src/swmod_lxc.c
@@ -13,813 +13,55 @@
 #endif
 
 #include <stdio.h>
-#include <unistd.h>
-#include <sys/sysinfo.h>
-#include <sys/statvfs.h>
-#include <sys/utsname.h>
-#include <errno.h>
-#include <fcntl.h>
+#include <stdlib.h>
 
-#include "tools.h"
-#include "swmod_uci.h"
-#include "swmod_opkg.h"
-#include "swmod.h"
+#include "swmod_common.h"
 #include "swmod_lxc.h"
-#include "swmod_api.h"
-
-#define LXC_CONFIG_PATH "/etc/lxc/lxc.conf"
-#define LXC_PATH "lxc.lxcpath"
-
-static char g_lxc_buff[MAX_BUFFER_LEN];
-
-typedef struct lxc_attach_args {
-	const char *lxcpath;
-	const char *value;
-	int action;
-	int pid;
-	int fd;
-	const char *user;
-	const char *pwd;
-	const char *service;
-} lxc_attach_args;
-
-struct service_state {
-	char *name;
-	bool state;
-};
-
-const char *get_lxc_path_from_config(void)
-{
-	return lxc_get_global_config_item(LXC_PATH);
-}
-
-bool lxc_is_supported(const char **lxcpath)
-{
-	if (!file_exists(LXC_CONFIG_PATH))
-		return false;
-
-	*lxcpath = get_lxc_path_from_config();
-
-	if (!(*lxcpath) || !file_exists(*lxcpath))
-		return false;
-
-	return true;
-}
-
-static int lxc_attach_func(struct lxc_container *ct, lxc_attach_exec_t exec_function,
-			   lxc_attach_args *command, bool get_output)
-{
-	int ret;
-	pid_t pid;
-	int pipefd[2];
-	lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
-	lxc_attach_args lxc_input;
-
-	memset(&lxc_input, 0, sizeof(lxc_attach_args));
-
-	g_lxc_buff[0] = '\0';
-	ret = pipe2(pipefd, O_NONBLOCK);
-	if (ret < 0) {
-		PRINT_ERR("Failed to create pipe");
-		return -1;
-	}
-
-	if (command) {
-		lxc_input.lxcpath = command->lxcpath;
-		lxc_input.value = command->value;
-		lxc_input.action = command->action;
-		lxc_input.pid = command->pid;
-		lxc_input.user = command->user;
-		lxc_input.pwd = command->pwd;
-		lxc_input.service = command->service;
-	}
-	lxc_input.fd = pipefd[1];
-
-	const char *state = ct->state(ct);
-
-	if (strcmp(state, "RUNNING") != 0) {
-		PRINT_ERR("Container might be frozen");
-		goto err;
-	}
-
-	ret = ct->attach(ct, exec_function, &lxc_input, &attach_options, &pid);
-	if (ret < 0)
-		goto err;
-
-	wait_for_pid(pid);
-
-	if (get_output == true) {
-		ret = read(pipefd[0], &g_lxc_buff, sizeof(g_lxc_buff)-1);
-		if (ret != -1) { // error on read
-			g_lxc_buff[ret] = '\0';
-		}
-		PRINT_DEBUG("== Attach Result buff [%s] ##", g_lxc_buff);
-	}
-
-err:
-	close(pipefd[0]);
-	close(pipefd[1]);
-	return ret;
-}
-
-static void dump_output_fd(int fd, const char *str)
-{
-	if (str == NULL)
-		return;
-
-	write(fd, str, strlen(str));
-	close(fd);
-}
-
-/************************** Execution Environments **************************/
-static int lxc_attach_run_env_func(void *args)
-{
-	char buff[MAX_LEN_1024];
-	struct utsname utsname;
-	char vendor[MAX_LEN_128] = {0}, version[MAX_LEN_16] = {0};
-	lxc_attach_args *data = (lxc_attach_args *) args;
-
-	if (uname(&utsname) >= 0) {
-		swmod_strncpy(vendor, utsname.nodename, MAX_LEN_128);
-		swmod_strncpy(version, utsname.release, MAX_LEN_16);
-	}
-
-	struct sysinfo sinfo;
-	unsigned long alloc_mem = 0, avail_mem = 0;
-
-	if (sysinfo(&sinfo) == 0) {
-		alloc_mem = (sinfo.totalram / 1024);
-		avail_mem = (sinfo.freeram / 1024);
-	}
-
-	struct statvfs dinfo;
-	unsigned long allocated_disk_space = 0;
-	unsigned long available_disk_space = 0;
-
-	if (statvfs("/", &dinfo) == 0) {
-		allocated_disk_space = (dinfo.f_bsize * dinfo.f_blocks) / 1024;
-		available_disk_space = (dinfo.f_bsize * dinfo.f_bfree) / 1024;
-	}
-
-	/* lxc_attach_result buffer format */
-	/* type=<ENV_TYPE> vendor=<ENV_VENDOR> version=<ENV_VERSION>
-	 *  alloc_mem=<ENV_ALLOCATED_MEMORY> avail_mem=<ENV_AVAILABLE_MEMORY> */
-	snprintf(buff, sizeof(buff), "vendor=%s version=%s alloc_mem=%lu avail_mem=%lu alloc_disk=%lu avail_disk=%lu",
-			vendor, version, alloc_mem, avail_mem, allocated_disk_space, available_disk_space);
-
-	dump_output_fd(data->fd, buff);
-
-	return 0;
-}
-
-unsigned long long lxc_get_cgroup_item_ull(struct lxc_container *ct, const char *config)
-{
-	unsigned long long value = 0;
-	char buffer[MAX_LEN_32] = {0};
-
-	int res = ct->get_cgroup_item(ct, config, buffer, sizeof(buffer));
-	if (res >= 0) {
-		sscanf(buffer, "%llu", &value);
-	}
-	return value;
-}
-
-void get_lxc_environment_info(ExecEnv_t *ee, const char *lxc_uci_path)
-{
-	if (lxc_uci_path == NULL || strlen(lxc_uci_path) == 0)
-		return;
-
-	if (ee == NULL)
-		return;
-
-	struct lxc_container *ct = lxc_container_new(ee->name, NULL);
-	if (!ct) {
-		swmod_strncpy(ee->status, "Error", MAX_LEN_32);
-		PRINT_ERR("Failed in opening container: %s", ee->name);
-		return;
-	}
-
-	bool ct_running = ct->is_running(ct);
-
-	ee->autoboot = get_autoboot_from_config_file(ct->name, lxc_uci_path);
-	swmod_strncpy(ee->status, ct_running ? "Up" : "Disabled", MAX_LEN_32);
-
-	if (ct_running && ((strcmp(ct->state(ct), "FROZEN") == 0) ||
-			strcmp(ct->state(ct), "FREEZING") == 0)) {
-		ee->pause = 1;
-	}
-
-	if (!ct_running || ee->pause) {
-		PRINT_INFO("lxc container not running or frozen");
-		lxc_container_put(ct);
-		return;
-	}
-
-	/* get memory space limit in cgroup */
-	unsigned long long val = 0;
-	val = lxc_get_cgroup_item_ull(ct, "memory.limit_in_bytes");
-	ee->allocated_memory = val / 1024;
-
-	/* get free space from lxc info */
-	val = lxc_get_cgroup_item_ull(ct, "memory.usage_in_bytes");
-	ee->available_memory = ee->allocated_memory - val / 1024;
-
-	int ret = lxc_attach_func(ct, lxc_attach_run_env_func, NULL, true);
-	if (ret >= 0 && strlen(g_lxc_buff)) {
-		sscanf(g_lxc_buff, "vendor=%127s version=%15s alloc_mem=%lu avail_mem=%lu alloc_disk=%lu avail_disk=%lu",
-			ee->vendor, ee->version, &ee->allocated_memory, &ee->available_memory,
-				&ee->allocated_disk_space, &ee->available_disk_space);
-	}
-
-	if (ret == -1) {
-		swmod_strncpy(ee->status, "Error", MAX_LEN_32);
-	}
-
-	lxc_container_put(ct);
-}
-
-void populate_lxc_environment(struct list_head *ee_head, const char *lxc_uci_path)
-{
-	const char *lxcpath = NULL;
-
-	if (lxc_uci_path == NULL)
-		return;
-
-	if (strlen(lxc_uci_path) == 0)
-		return;
-
-	if (!lxc_is_supported(&lxcpath))
-		return;
-
-	if (0 != swmod_uci_init(lxc_uci_path))
-		return;
-
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(SWMOD_LXC_DU_UCI, "container", stmp, s) {
-		const char *name = swmod_uci_get_value_by_section(s, "name");
-		const char *type = swmod_uci_get_value_by_section(s, "type");
-		const char *eeid = swmod_uci_get_value_by_section(s, "eeid");
-		const char *alias = swmod_uci_get_value_by_section(s, "alias");
-
-		if (strlen(name) != 0 && strcmp(type, "lxc") == 0) {
-			ExecEnv_t ee;
-			memset(&ee, 0, sizeof(ExecEnv_t));
-
-			ee.exists = true;
-			ee.ee_type = EE_TYPE_LXC;
-			ee.parent_eeid = PARENT_EEID;
-
-			if (strlen(eeid) != 0)
-				ee.eeid = strtol(eeid, NULL, 10);
-
-			swmod_strncpy(ee.type, "Linux Container", MAX_LEN_64);
-			swmod_strncpy(ee.name, name, MAX_LEN_32);
-			swmod_strncpy(ee.alias, alias, MAX_LEN_65);
-			swmod_add_ee_in_list(ee_head, &ee);
-		}
-	}
-
-	swmod_uci_fini(SWMOD_LXC_DU_UCI);
-}
-
-void lxc_service_get_cb(struct ubus_request *req, int type, struct blob_attr *msg)
-{
-	char *str;
-	lxc_attach_args *input = (lxc_attach_args *) req->priv;
-
-	str = blobmsg_format_json(msg, true);
-	if (str != NULL) {
-		write(input->fd, str, strlen(str));
-		free(str);
-	}
-}
-
-static int lxc_attach_pid(void *args)
-{
-	char buff[MAX_LEN_1024];
-	char cmdline[MAX_LEN_32] = {0};
-	int vsize = 0;
-	lxc_attach_args *lxc_input = (lxc_attach_args *) args;
-
-	get_pid_details(lxc_input->pid, cmdline, MAX_LEN_32, &vsize);
-	/* lxc_attach_result buffer format */
-	/* type=<ENV_TYPE> vendor=<ENV_VENDOR> version=<ENV_VERSION>
-	 *  alloc_mem=<ENV_ALLOCATED_MEMORY> avail_mem=<ENV_AVAILABLE_MEMORY> */
-	snprintf(buff, sizeof(buff), "cmdline=%s vsize=%d", cmdline, vsize);
-
-	dump_output_fd(lxc_input->fd, buff);
-
-	return 0;
-}
-
-void get_pid_details_lxc(ExecEnv_t *env, int pid, char *cmdline, int cmd_len, int *vsize)
-{
-	if (env == NULL || cmdline == NULL || cmd_len < MAX_LEN_32 || vsize == NULL)
-		return;
-
-	if (env->name[0] == '\0')
-		return;
-
-	struct lxc_container *ct = lxc_container_new(env->name, NULL);
-	if (!ct) {
-		PRINT_ERR("Failed in opening container: %s", env->name);
-		return;
-	}
-
-	if (!ct->is_running(ct)) {
-		lxc_container_put(ct);
-		return;
-	}
-
-	lxc_attach_args lxc_data;
-
-	memset(&lxc_data, 0, sizeof(lxc_attach_args));
-	lxc_data.pid = pid;
-	int ret = lxc_attach_func(ct, lxc_attach_pid, &lxc_data, true);
-	if (ret >= 0 && strlen(g_lxc_buff)) {
-		sscanf(g_lxc_buff, "cmdline=%31s vsize=%d", cmdline, vsize);
-	}
-
-	lxc_container_put(ct);
-}
+#include "tools.h"
 
-static int lxc_attach_eu_list(void *args)
+const char *swmod_get_lxc_version(void)
 {
-	get_service_list("service", "list", lxc_service_get_cb, args);
-	return 0;
+	return lxc_get_version();
 }
 
-void populate_lxc_eu(ExecEnv_t *env, const char *lxc_uci_path)
+void swmod_set_lxc_state(const char *cont, const char *execenv, int state)
 {
-	struct blob_buf bb;
-
-	if (lxc_uci_path == NULL || strlen(lxc_uci_path) == 0) {
-		PRINT_ERR("LXC DU uci path unknown");
-		return;
-	}
-
-	if (env == NULL) {
-		PRINT_ERR("No environment information given");
-		return;
-	}
+	int timeout = 300;
+	int ret = 0;
+	struct lxc_container *ct = NULL;
 
-	if (env->name[0] == '\0' || env->exists == false) {
-		PRINT_ERR("Environment name unknown or not exists");
+	if (!cont || !execenv)
 		return;
-	}
 
-	struct lxc_container *ct = lxc_container_new(env->name, NULL);
+	ct = lxc_container_new(cont, execenv);
 	if (!ct) {
-		PRINT_ERR("Failed in opening container: %s", env->name);
-		return;
-	}
-
-	if (!ct->is_running(ct)) {
-		lxc_container_put(ct);
+		PRINT_ERR("Failed in opening container: %s", cont);
 		return;
 	}
 
-	if (0 != swmod_uci_init(lxc_uci_path)) {
-		lxc_container_put(ct);
-		return;
-	}
-
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(SWMOD_LXC_DU_UCI, "du_eu_assoc", stmp, s) {
-		const char *type = swmod_uci_get_value_by_section(s, "type");
-		const char *status = swmod_uci_get_value_by_section(s, "du_status");
-
-		if (strcmp(type, "lxc") == 0 && strcmp(status, "Installed") == 0) {
-			const char *eu_name = swmod_uci_get_value_by_section(s, "eu_name");
-			if (strlen(eu_name) == 0)
-				continue;
-
-			const char *ee_name = swmod_uci_get_value_by_section(s, "ee_name");
-			if (strcmp(ee_name, env->name) != 0)
-				continue;
-
-			const char *req_state = swmod_uci_get_value_by_section(s, "requested_state");
-			const char *auto_start = swmod_uci_get_value_by_section(s, "autostart");
-			const char *du_name = swmod_uci_get_value_by_section(s, "name");
-			const char *eu_alias = swmod_uci_get_value_by_section(s, "eu_alias");
-
-			lxc_attach_args lxc_data;
-			memset(&lxc_data, 0, sizeof(lxc_attach_args));
-			lxc_data.service = eu_name;
-			int ret = lxc_attach_func(ct, lxc_attach_eu_list, (lxc_attach_args *)&lxc_data, true);
-			if (ret >= 0 && strlen(g_lxc_buff)) {
-				memset(&bb, 0, sizeof(struct blob_buf));
-				blob_buf_init(&bb, 0);
-				blobmsg_add_json_from_string(&bb, g_lxc_buff);
-
-				ExecUnit node;
-				memset(&node, 0, sizeof(ExecUnit));
-				if (0 == update_eu_from_blob(env, bb.head, &node)) {
-					if (req_state)
-						swmod_strncpy(node.req_state, req_state, sizeof(node.req_state));
-
-					if (du_name)
-						swmod_strncpy(node.du_name, du_name, sizeof(node.du_name));
-
-					if (eu_alias)
-						swmod_strncpy(node.eu_alias, eu_alias, sizeof(node.eu_alias));
-
-					node.autostart = uci_str_to_bool(auto_start);
-
-					swmod_add_eu_in_list(&env->eu_list, &node);
-				}
-				blob_buf_free(&bb);
-			}
-		}
-	}
-
-	swmod_uci_fini(SWMOD_LXC_DU_UCI);
-	lxc_container_put(ct);
-}
-
-/************************** Deployment/Execution Unit **************************/
-/************************** Install/Remove **************************/
-static int lxc_attach_run_opkg_method_func(void *args)
-{
-	lxc_attach_args *data = (lxc_attach_args *)args;
-
-	if (!data || *(data->value) == '\0') {
-		PRINT_ERR("No data available");
-		return -1;
-	}
-
-	int err = -1;
-
-	char output[MAX_LEN_1024] = {0};
-	if (data->action == SWMOD_INSTALL)
-		err = swmod_perform_installation(data->value, data->user, data->pwd, output, sizeof(output));
-	else if (data->action == SWMOD_UPDATE)
-		err = swmod_perform_upgrade(data->value, data->user, data->pwd, output, sizeof(output));
-	else if (data->action == SWMOD_REMOVE)
-		err = swmod_perform_uninstall(data->value, output, sizeof(output));
-	else
-		err = -1;
-
-	dump_output_fd(data->fd, output);
-	return err;
-}
-
-int swmod_lxc_install_update_remove_package(const PkgInfo *pkg, char *out, int outlen, const char *ct_name, int action)
-{
-	int err = -1;
-	struct lxc_container *ct = NULL;
-
-	if (out == NULL) {
-		PRINT_ERR("No output buffer");
-		return err;
-	}
-
-	if (pkg == NULL) {
-		snprintf(out, outlen, "Internal Error");
-		PRINT_ERR("No package information");
-		return err;
-	}
-
-	if (ct_name == NULL) {
-		snprintf(out, outlen, "No ExecEnv information received");
-		PRINT_ERR("No environment information given");
-		return err;
-	}
-
-	if (ct_name[0] == '\0') {
-		snprintf(out, outlen, "ExecEnv name unknown");
-		PRINT_ERR("No environment name given");
-		return err;
-	}
-
-	ct = lxc_container_new(ct_name, NULL);
-	if (!ct) {
-		snprintf(out, outlen, "Error in opening container: %s", ct_name);
-		PRINT_ERR("Failed in opening container: %s", ct_name);
-		return err;
-	}
-
-	if (!ct->is_running(ct)) {
-		snprintf(out, outlen, "ExecEnv not running");
-		lxc_container_put(ct);
-		return err;
-	}
-
-	PRINT_DEBUG("## Container %s", ct->name);
-	lxc_attach_args lxc_args = (lxc_attach_args){.value = pkg->url, .action = action, .user = pkg->uname, .pwd = pkg->psw};
-	err = lxc_attach_func(ct, lxc_attach_run_opkg_method_func, &lxc_args, true);
-	PRINT_DEBUG("# Reading i/u/r %d, lxc[%s], err %d", action, ct->name, err);
-	if (err >= 0  && strlen(g_lxc_buff)) {
-		err = 0;
-		snprintf(out, outlen, "%s", g_lxc_buff);
-	}
-
-	lxc_container_put(ct);
-
-	return err;
-}
-
-static int lxc_attach_service_state_func(void *args)
-{
-	struct service_state *st = (struct service_state *)args;
-
-	return ubus_call_service_state(st->name, st->state);
-}
-
-int swmod_set_lxc_ee_state(ExecEnv_t *env, char *state, const char *lxc_uci_path)
-{
-	int timeout;
-	int ret = SUCCESS;
-
-	if (lxc_uci_path == NULL || strlen(lxc_uci_path) == 0) {
-		ret = INVALID_REQUEST;
-		PRINT_ERR("LXC DU uci path unknown");
-		return ret;
-	}
-
-	struct lxc_container *ct = NULL;
-	if (env == NULL) {
-		ret = INVALID_REQUEST;
-		PRINT_ERR("No environment information given");
-		return ret;
-	}
-
-	if (env->name[0] == '\0'|| state == NULL) {
-		ret = INVALID_REQUEST;
-		PRINT_ERR("No environment information or state given");
-		return ret;
-	}
-
-	ct = lxc_container_new(env->name, NULL);
-	if (!ct) {
-		ret = NOT_FOUND;
-		PRINT_ERR("Failed in opening container: %s", env->name);
-		return ret;
-	}
-
-	int req_state = get_requested_container_state(state);
-
-	switch (req_state) {
-	case CONT_START:
-		set_autoboot_to_config_file(ct->name, true, lxc_uci_path);
-
-		if (ct->is_running(ct)) {
-			ret = ALREADY_RUNNING;
-			break;
-		}
-
-		ct->want_close_all_fds(ct, true);
-		ret = ct->start(ct, 0, NULL) ? SUCCESS: FAILURE;
+	switch (state) {
+	case EU_START:
 		break;
-	case CONT_STOP:
-		timeout = get_timeout_from_config_file(ct->name, lxc_uci_path);
-
-		set_autoboot_to_config_file(ct->name, false, lxc_uci_path);
-
+	case EU_STOP:
 		if (!ct->is_running(ct)) {
-			ret = NOT_RUNNING;
 			break;
 		}
 
 		if (strcmp(ct->state(ct), "FROZEN") == 0 || strcmp(ct->state(ct), "FREEZING") == 0) {
 			/* to stop a frozen container first need to unfreeze it */
 			if (!ct->unfreeze(ct)) {
-				ret = FAILURE;
 				break;
 			}
 		}
 
-		ret = ct->shutdown(ct, timeout) ? SUCCESS : FAILURE;
-		if (ret == FAILURE) {
+		ret = ct->shutdown(ct, timeout);
+		if (ret == 0) {
 			PRINT_DEBUG("Going to force stop [%s]", ct->name);
-			ret = ct->stop(ct) ? SUCCESS : FAILURE;
+			ct->stop(ct);
 		}
 		break;
-	case CONT_PAUSE:
-		if (!ct->is_running(ct)) {
-			ret = NOT_RUNNING;
-			break;
-		}
-
-		ret = ct->freeze(ct) ? SUCCESS : FAILURE;
-		break;
-	case CONT_RESUME:
-		if (!ct->is_running(ct)) {
-			ret = NOT_RUNNING;
-			break;
-		}
-
-		ret = ct->unfreeze(ct) ? SUCCESS : FAILURE;
-		break;
-	default:
-		ret = INVALID_REQUEST;
 	}
 
 	lxc_container_put(ct);
-
-	return ret;
 }
 
-int swmod_set_lxc_service_state(ExecEnv_t *env, char *name, bool state, const char *lxc_uci_path)
-{
-	int ret = -1;
-	struct lxc_container *ct = NULL;
-
-	if (lxc_uci_path == NULL || strlen(lxc_uci_path) == 0) {
-		PRINT_ERR("LXC DU uci path unknown");
-		return ret;
-	}
-
-	if (env == NULL) {
-		PRINT_ERR("No environment info");
-		return ret;
-	}
-
-	if (env->name[0] == '\0') {
-		PRINT_ERR("No ExecEnv name found");
-		return ret;
-	}
-
-	if (name == NULL) {
-		PRINT_ERR("No eu name information");
-		return ret;
-	}
-
-	if (0 != swmod_uci_init(lxc_uci_path)) {
-		PRINT_ERR("Failed to write the requested value");
-		return ret;
-	}
-
-	struct uci_section *s = NULL, *stmp = NULL;
-	bool found = false;
-	swmod_uci_foreach_section_safe(SWMOD_LXC_DU_UCI, "du_eu_assoc", stmp, s) {
-		const char *eu = swmod_uci_get_value_by_section(s, "eu_name");
-		const char *ee_name = swmod_uci_get_value_by_section(s, "ee_name");
-
-		if (strcmp(name, eu) == 0 && strcmp(env->name, ee_name) == 0) {
-			found = true;
-			if (state) {
-				swmod_uci_set_value_by_section(s, "requested_state", "Active");
-			} else {
-				swmod_uci_set_value_by_section(s, "requested_state", "Idle");
-			}
-
-			break;
-		}
-	}
-
-	swmod_uci_fini(SWMOD_LXC_DU_UCI);
-
-	if (found == false) {
-		PRINT_ERR("No DU exist with name: %s in ExecEnv: %s", name, env->name);
-		return ret;
-	}
-
-	ct = lxc_container_new(env->name, NULL);
-	if (!ct) {
-		PRINT_ERR("Failed in opening container: %s", env->name);
-		return ret;
-	}
-
-	if (!ct->is_running(ct)) {
-		PRINT_INFO("lxc container not running");
-		lxc_container_put(ct);
-		return ret;
-	}
-
-	struct service_state st;
-	st.name = name;
-	st.state = state;
-	ret = lxc_attach_func(ct, lxc_attach_service_state_func, (lxc_attach_args *)&st, false);
-	lxc_container_put(ct);
-
-	return ret;
-}
-
-static int lxc_attach_run_cmd(void *args)
-{
-	lxc_attach_args *lxc_input = (lxc_attach_args *) args;
-	FILE *pp; // program pointer
-	const char *cmd;
-
-	cmd = lxc_input->value;
-	if (cmd == NULL) { // null command to run, silently ignore
-		PRINT_ERR("Empty command to run");
-		return 0;
-	}
-
-	pp = popen(cmd, "r");
-	if (pp != NULL) {
-		char line[MAX_LEN_512] = {0};
-
-		while(fgets(line, sizeof(line), pp) != NULL) {
-			write(lxc_input->fd, line, strlen(line));
-		}
-		pclose(pp);
-	}
-
-	return 0;
-}
-
-int lxc_run_cmd(ExecEnv_t *ee, const char *cmd, char *output, int out_len)
-{
-	struct lxc_container *ct;
-	lxc_attach_args lxc_data;
-
-	if (ee->exists == false || ee->ee_type != EE_TYPE_LXC) {
-		PRINT_ERR("lxc not enabled");
-		return -1;
-	}
-
-	memset(&lxc_data, 0, sizeof(lxc_attach_args));
-	lxc_data.value = cmd;
-	ct = lxc_container_new(ee->name, NULL);
-	if (!ct) {
-		PRINT_ERR("failed to open container");
-		return -1;
-	}
-
-	if (!ct->is_running(ct)) {
-		PRINT_ERR("container not running");
-		lxc_container_put(ct);
-		return -1;
-	}
-
-	int ret = lxc_attach_func(ct, lxc_attach_run_cmd, &lxc_data, true);
-	if (ret >= 0 && strlen(g_lxc_buff)) {
-		snprintf(output, out_len, "%s", g_lxc_buff);
-	}
-
-	lxc_container_put(ct);
-
-	return ret;
-}
-
-void get_service_list(char *object, char *method, ubus_data_handler_t callback, void *data)
-{
-	/* This function will be called inside LXC, so need a new ubux ctx */
-	uint32_t id;
-	int fault = 0;
-	struct ubus_context *ctx = ubus_connect(NULL);
-	struct blob_buf bb;
-
-	fault = ubus_lookup_id(ctx, object, &id);
-	if (fault) {
-		PRINT_ERR("ubus service not found %d", fault);
-		ubus_free(ctx);
-		return;
-	}
-
-	lxc_attach_args *input = (lxc_attach_args *)data;
-	if (input == NULL) {
-		PRINT_ERR("Service not found");
-		ubus_free(ctx);
-		return;
-	}
-
-	if (input->service == NULL) {
-		PRINT_ERR("Service name not found");
-		ubus_free(ctx);
-		return;
-	}
-
-	memset(&bb, 0, sizeof(struct blob_buf));
-	blob_buf_init(&bb, 0);
-	blobmsg_add_string(&bb, "name", input->service);
-
-	// Invoke Ubus to get data from uspd
-	fault = ubus_invoke(ctx, id, method, bb.head, callback, data, UBUS_TIMEOUT);
-
-	blob_buf_free(&bb);
-	ubus_free(ctx);
-}
-
-int set_lxc_alias(const char *ee_name, const char *alias, const char *bundle)
-{
-	int ret = -1;
-
-	if (ee_name == NULL || alias == NULL || bundle == NULL)
-		return ret;
-
-	if (strlen(bundle) == 0)
-		return ret;
-
-	if (swmod_uci_init(bundle) != 0)
-		return ret;
-
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(SWMOD_LXC_DU_UCI, "container", stmp, s) {
-		char *name = swmod_uci_get_value_by_section(s, "name");
-		char *type = swmod_uci_get_value_by_section(s, "type");
-
-		if (strcmp(ee_name, name) == 0 && strcmp(type, "lxc") == 0) {
-			swmod_uci_set_value_by_section(s, "alias", alias);
-			ret = 0;
-			break;
-		}
-	}
-
-	swmod_uci_fini(SWMOD_LXC_DU_UCI);
-
-	return ret;
-}
diff --git a/src/swmod_lxc.h b/src/swmod_lxc.h
index f47fdac7b70489001413e3a21674570b54ee2317..1c9b2d25a50fe80cc96f1033947d6fb78c3c99c6 100644
--- a/src/swmod_lxc.h
+++ b/src/swmod_lxc.h
@@ -18,18 +18,7 @@
 
 #include "swmod_common.h"
 
-bool lxc_is_supported(const char **lxcpath);
-const char *get_lxc_path_from_config(void);
-void populate_lxc_environment(struct list_head *ee_list, const char *lxc_oci_path);
-void populate_lxc_du(void);
-int swmod_lxc_install_update_remove_package(const PkgInfo *pkg, char *out, int outlen, const char *ct_name, int action);
-void populate_lxc_eu(ExecEnv_t *env, const char *lxc_uci_path);
-void get_pid_details_lxc(ExecEnv_t *env, int pid, char *cmdline, int cmd_len, int *vsize);
-int swmod_set_lxc_service_state(ExecEnv_t *env, char *name, bool state, const char *lxc_uci_path);
-int swmod_set_lxc_ee_state(ExecEnv_t *env, char *state, const char *lxc_uci_path);
-int lxc_run_cmd(ExecEnv_t *ee, const char *cmd, char *output, int out_len);
-void get_lxc_environment_info(ExecEnv_t *ee, const char *lxc_uci_path);
-void get_service_list(char *object, char *method, ubus_data_handler_t callback, void *data);
-int set_lxc_alias(const char *ee_name, const char *alias, const char *bundle);
+const char *swmod_get_lxc_version(void);
+void swmod_set_lxc_state(const char *cont, const char *execenv, int state);
 
 #endif //LXC_H
diff --git a/src/swmod_opkg.c b/src/swmod_opkg.c
deleted file mode 100644
index 0582f2c02985148c88895fd0bb5e7977051ed00c..0000000000000000000000000000000000000000
--- a/src/swmod_opkg.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * swmod_opkg.c: SWMOD deamon
- *
- * Copyright (C) 2020-2023 IOPSYS Software Solutions AB. All rights reserved.
- *
- * Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
- *
- * See LICENSE file for license related information.
- */
-
-#include "tools.h"
-#include "swmod.h"
-#include "swmod_uci.h"
-#include "swmod_opkg.h"
-#include "swmod_common.h"
-#include "opkg_utils.h"
-#include "swmod_api.h"
-
-static bool validate_args(const char *url, char *output, int out_len)
-{
-	if (output == NULL || out_len <= 0) {
-		return false;
-	}
-
-	if (url == NULL) {
-		snprintf(output, out_len, "Package path not given");
-		return false;
-	}
-
-	if (url[0] == '\0') {
-		snprintf(output, out_len, "Package path not given");
-		return false;
-	}
-
-	return true;
-}
-
-int swmod_perform_installation(const char *url, const char *uname, const char *pwd, char *output, int out_len)
-{
-	int err = -1;
-	char package_path[2049] = {0};
-
-	if (validate_args(url, output, out_len) == false)
-		return err;
-
-	if (strstr(url, "file://") != NULL) {
-		/* This is a local file */
-		snprintf(package_path, sizeof(package_path), "%s", url+6);
-	} else {
-		unsigned long size = get_remote_file_size(url, uname, pwd);
-		if (size == 0) {
-			snprintf(output, out_len, "Failed to read package info or package is empty");
-			return err;
-		}
-
-		if (!memory_available(size, DW_TMP_DIR_PATH)) {
-			snprintf(output, out_len, "No enough space in system to download the package");
-			return err;
-		}
-
-		/* This is a remote package, need to download first */
-		if(0 != download_remote_package(url, uname, pwd, DW_PKG_LOCAL_PATH)) {
-			snprintf(output, out_len, "Package download failed from %s", url);
-			goto end;
-		}
-
-		snprintf(package_path, sizeof(package_path), "%s", DW_PKG_LOCAL_PATH);
-	}
-
-	if (strlen(package_path) == 0) {
-		snprintf(output, out_len, "Invalid package name");
-		goto end;
-	}
-
-	err = opkg_install_pkg(package_path, output, out_len);
-	if (0 != err) {
-		snprintf(output, out_len, "Internal Error");
-	}
-
-end:
-	/* Remove the downloaded package if it is in local dir of host or container */
-	if (file_exists(DW_PKG_LOCAL_PATH)) {
-		remove(DW_PKG_LOCAL_PATH);
-	}
-
-	return err;
-}
-
-int swmod_perform_upgrade(const char *url, const char *uname, const char *pwd, char *output, int out_len)
-{
-	int err = -1;
-	char package_path[2049] = {0};
-
-	if (validate_args(url, output, out_len) == false)
-		return err;
-
-	if (strchr(url, ':') != NULL) {
-		/* This is a remote package, need to download first */
-		if(0 != download_remote_package(url, uname, pwd, DW_PKG_LOCAL_PATH)) {
-			snprintf(output, out_len, "Package download failed from %s", url);
-			return err;
-		}
-
-		snprintf(package_path, sizeof(package_path), "%s", DW_PKG_LOCAL_PATH);
-	} else {
-		snprintf(package_path, sizeof(package_path), "%s", url);
-	}
-
-	err = opkg_update_pkg(package_path, output, out_len);
-	if (0 != err) {
-		snprintf(output, out_len, "Internal Error");
-	}
-
-	/* Remove the downloaded package if it is in local dir of host or container */
-	if (file_exists(DW_PKG_LOCAL_PATH)) {
-		remove(DW_PKG_LOCAL_PATH);
-	}
-
-	return err;
-}
-
-int swmod_perform_uninstall(const char *pname, char *output, int outlen)
-{
-	int err = -1;
-
-	if (validate_args(pname, output, outlen) == false)
-		return err;
-
-	char version[MAX_LEN_64] = {0};
-	char line[MAX_LEN_512] = {0};
-	opkg_get_version(pname, version, sizeof(version));
-	snprintf(line, sizeof(line), "\nPackage Name:%s Version:%s\n", pname, version);
-
-	err = opkg_remove_pkg(pname, output, outlen);
-	if (0 != err) {
-		snprintf(output, outlen, "Internal Error");
-	}
-
-	int line_len = strlen(line);
-	if (strlen(output) + line_len < outlen) {
-		strncat(output, line, line_len);
-	}
-
-	return err;
-}
diff --git a/src/swmod_opkg.h b/src/swmod_opkg.h
deleted file mode 100644
index 5b67674894246861ce5247e6ad209c0f4dd03ef1..0000000000000000000000000000000000000000
--- a/src/swmod_opkg.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * swmod_opkg.h: opkg utilities
- *
- * Copyright (C) 2020-2023 IOPSYS Software Solutions AB. All rights reserved.
- *
- * Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
- *
- * See LICENSE file for license related information.
- */
-
-#ifndef __SWMOD_OPKG_H
-#define __SWMOD_OPKG_H
-
-int swmod_perform_installation(const char *url, const char *uname, const char *pwd, char *output, int out_len);
-int swmod_perform_upgrade(const char *url, const char *uname, const char *pwd, char *output, int out_len);
-int swmod_perform_uninstall(const char *pname, char *output, int out_len);
-
-#endif //__SWMOD_OPKG_H
diff --git a/src/swmod_uci.c b/src/swmod_uci.c
index 8bfee0ac337cc59c7c7302e638abb4c3e534737a..847a5994482dc2743b277439e19444bc6e22776e 100644
--- a/src/swmod_uci.c
+++ b/src/swmod_uci.c
@@ -267,7 +267,7 @@ char *swmod_uci_set_value_by_section_list(struct uci_section *section, const cha
 	return "";
 }
 
-struct uci_section *swmod_uci_add_section(const char *package, const char *section_type, bool rename)
+struct uci_section *swmod_uci_add_section(const char *package, const char *section_type, const char *sec_name)
 {
 	struct uci_ptr ptr;
 	struct uci_section *s = NULL;
@@ -287,14 +287,14 @@ struct uci_section *swmod_uci_add_section(const char *package, const char *secti
 		return NULL;
 	}
 
-	if (rename == true) {
+	if (sec_name) {
 		ptr.package = s->package->e.name;
 		ptr.p = s->package;
 
 		ptr.section = s->e.name;
 		ptr.s = s;
 
-		ptr.value = section_type;
+		ptr.value = sec_name;
 		ptr.target = UCI_TYPE_SECTION;
 
 		if (uci_lookup_ptr(uci_ctx_swmod, &ptr, NULL, true) == UCI_OK) {
@@ -327,9 +327,9 @@ int swmod_uci_delete_by_section(struct uci_section *section, const char *option,
 	return 0;
 }
 
-bool check_section_exist_by_option(const char *section, const char *section_type, const char *option, const char *val_check, struct uci_section **s)
+bool check_section_exist_by_option(const char *package, const char *section_type, const char *option, const char *val_check, struct uci_section **s)
 {
-	swmod_uci_foreach_section(section, section_type, *s) {
+	swmod_uci_foreach_section(package, section_type, *s) {
 		const char *val = swmod_uci_get_value_by_section(*s, option);
 
 		if (strcmp(val, val_check) == 0)
diff --git a/src/swmod_uci.h b/src/swmod_uci.h
index 3454b26195095f2d10bf3bb59b5a2a8d0a3d0988..456e1ee01f2017345bb54dd1b4ec47f22108a42c 100644
--- a/src/swmod_uci.h
+++ b/src/swmod_uci.h
@@ -16,7 +16,7 @@
 int swmod_uci_init(const char *conf_path);
 int swmod_uci_fini(const char *package_name);
 
-struct uci_section *swmod_uci_add_section(const char *package, const char *section_type, bool rename);
+struct uci_section *swmod_uci_add_section(const char *package, const char *section_type, const char *sec_name);
 int swmod_uci_delete_by_section(struct uci_section *section, const char *option, const char *value);
 
 char *swmod_uci_get_value_by_section(struct uci_section *section, const char *option);
diff --git a/src/tools.c b/src/tools.c
index 53d30371b0b48b2255dc6579279da5ffabd745d4..3885accc57aad96913b901157e197c1a742d1799 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -15,6 +15,8 @@
 #include <stdlib.h>
 #include <dirent.h>
 #include <unistd.h>
+#include <ctype.h>
+#include <sys/prctl.h>
 #include <sys/stat.h>
 #include <sys/statvfs.h>
 #include <sys/types.h>
@@ -28,9 +30,6 @@
 #include <curl/curl.h>
 
 #include "swmod_uci.h"
-#include "swmod_opkg.h"
-#include "opkg_utils.h"
-#include "swmod_host.h"
 #include "tools.h"
 #include "swmod_api.h"
 
@@ -38,38 +37,38 @@
 
 static unsigned char gLogLevel = DEFAULT_LOG_LEVEL;
 
-int get_requested_container_state(char *state)
+static int get_filename_from_url(const char *url, char *filename, int len)
 {
-	if (strcmp(state, "start") == 0) {
-		return CONT_START;
-	} else if (strcmp(state, "stop") == 0) {
-		return CONT_STOP;
-	} else if (strcmp(state, "pause") == 0) {
-		return CONT_PAUSE;
-	} else if (strcmp(state, "resume") == 0) {
-		return CONT_RESUME;
+	if (url == NULL || filename == NULL)
+		return -1;
+
+	memset(filename, 0, len);
+
+	char *tmp = strrchr(url, '/');
+	if (tmp == NULL) {
+		tmp = (char*)url;
 	} else {
-		return __CONT_STATE_MAX;
+		if (tmp == (url + strlen(url) - 1)) {
+			return -1;
+		} else {
+			tmp = tmp + 1;
+		}
 	}
-}
 
-char ee_set_state_error_msg[__ERROR_MAX][MAX_LEN_64] = {
-	"",
-	"internal failure",
-	"LXC not supported",
-	"ExecEnv not found",
-	"ExecEnv already running",
-	"ExecEnv not running",
-	"invalid request",
-	"CRUN not supported",
-};
-
-const char *ee_state_failure_reason(int err)
-{
-	if (err >= __ERROR_MAX || err < 0)
-		return "unknown";
+	snprintf(filename, len, "%s", tmp);
+	char *tmp2 = strchr(filename, ':');
+	if (tmp2)
+		*tmp2 = '\0';
 
-	return ee_set_state_error_msg[err];
+	tmp2 = strchr(filename, '.');
+	if (tmp2)
+		*tmp2 = '\0';
+
+	tmp2 = strchr(filename, '@'); /* for docker image there could be @sha after name */
+	if (tmp2)
+		*tmp2 = '\0';
+
+	return 0;
 }
 
 // Logging utilities
@@ -198,6 +197,49 @@ bool create_dir(const char *path)
 	return true;
 }
 
+void remove_dir(const char *path)
+{
+	DIR *dir;
+	struct stat stat_path, stat_entry;
+	struct dirent *entry;
+
+	stat(path, &stat_path);
+
+	if (S_ISDIR(stat_path.st_mode) == 0) {
+		return;
+	}
+
+	if ((dir = opendir(path)) == NULL) {
+		return;
+	}
+
+	// iteration through entries in the directory
+	while ((entry = readdir(dir)) != NULL) {
+		// skip entries "." and ".."
+		if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
+			continue;
+
+		// determinate a full path of an entry
+		char full_path[5096] = {0};
+		snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
+
+		// stat for the entry
+		stat(full_path, &stat_entry);
+
+		// recursively remove a nested directory
+		if (S_ISDIR(stat_entry.st_mode) != 0) {
+			remove_dir(full_path);
+			continue;
+		}
+
+		// remove a file object
+		unlink(full_path);
+	}
+
+	rmdir(path);
+	closedir(dir);
+}
+
 void swmod_strncpy(char *dst, const char *src, size_t n)
 {
 	strncpy(dst, src, n - 1);
@@ -215,28 +257,26 @@ char *generate_uuid(void)
 	return uuid;
 }
 
-char *generate_duid(bool sysnchronise, int number)
+char *generate_duid(const char *ee_name, const char *du_name)
 {
-	const char buf[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-	int div = sizeof(buf) - 1;
-	char euid[16] = {0};
-	int i;
-
-	srand(time(NULL));
-	if (sysnchronise) {
-		char euid_num[8] = {0};
-
-		for (i = 0; i < 3; i++)
-			euid[i] = buf[rand() % div];
-		snprintf(euid_num, sizeof(euid_num), "%04d", number);
-		strncat(euid, euid_num, 4);
-	} else {
-		for (i = 0; i < 7; i++)
-			euid[i] = buf[rand() % div];
+	char duid[512] = {0};
+	int i = 0;
+
+	if (ee_name == NULL || du_name == NULL)
+		return strdup(duid);
+
+	snprintf(duid, sizeof(duid), "%s_%s", ee_name, du_name);
+	while (duid[i] != '\0') {
+		if (isalnum(duid[i]) || duid[i] == '_') {
+			i++;
+			continue;
+		}
+
+		duid[i] = '_';
+		i++;
 	}
-	euid[7] = '\0';
 
-	return strdup(euid);
+	return strdup(duid);
 }
 
 /*
@@ -297,147 +337,7 @@ int run_cmd_no_output(const char *cmd)
 	return 0;
 }
 
-int get_env_type(const char *type)
-{
-	if (strcmp(type, "lxc") == 0)
-		return EE_TYPE_LXC;
-	else if (strcmp(type, "host") == 0)
-		return EE_TYPE_HOST;
-	else
-		return EE_TYPE_UNKNOWN;
-}
-
-void sync_eeid_with_uci(struct list_head *ee_list, ExecEnv_t *environments, const char *lxc_uci_path)
-{
-	if (list_empty(ee_list))
-		return;
-
-	if (lxc_uci_path == NULL)
-		return;
-
-	if (strlen(lxc_uci_path) == 0)
-		return;
-
-	if (0 != swmod_uci_init(lxc_uci_path)) {
-		return;
-	}
-
-	char eeid_str[12] = {0};
-	unsigned int new_eeid = 3;
-	struct uci_section *s = NULL, *stmp = NULL;
-	int index = 0;
-	bool global_context_exist = false;
-
-	swmod_uci_foreach_section_safe(SWMOD_LXC_DU_UCI, "globals", stmp, s) {
-		if (strcmp(s->e.name, "globals") == 0) {
-			const char *next_eeid = swmod_uci_get_value_by_section(s, "next_eeid");
-			if (next_eeid != NULL && strlen(next_eeid) != 0) {
-				new_eeid = (unsigned int)strtoul(next_eeid, NULL, 10);
-			}
-
-			global_context_exist = true;
-			break;
-		}
-	}
-
-	/* check the ee that has valid eeid, then put it in g_environments (upto MAX_ENV) */
-	ExecEnvNode *iter = NULL;
-	list_for_each_entry(iter, ee_list, list) {
-		if (iter->env.eeid != 0) {
-			if (index < MAX_ENV) {
-				memcpy(&environments[index], &iter->env, sizeof(ExecEnv_t));
-				index ++;
-			}
-		}
-	}
-
-	/* now those have no eeid, initialize eeid and put in g_environments (upto MAX_ENV),
-	 * as well make entry in uci file.
-	 */
-	iter = NULL;
-	list_for_each_entry(iter, ee_list, list) {
-		if (index == MAX_ENV)
-			break;
-
-		if (iter->env.eeid == 0) {
-			struct uci_section *sc = NULL, *sctmp = NULL;
-			swmod_uci_foreach_section_safe(SWMOD_LXC_DU_UCI, "container", sctmp, sc) {
-				const char *name = swmod_uci_get_value_by_section(sc, "name");
-				const char *type = swmod_uci_get_value_by_section(sc, "type");
-				if (strcmp(name, iter->env.name) == 0 && iter->env.ee_type == get_env_type(type)) {
-					iter->env.eeid = new_eeid;
-					new_eeid = new_eeid + 1;
-
-					snprintf(eeid_str, sizeof(eeid_str), "%u", iter->env.eeid);
-					swmod_uci_set_value_by_section(sc, "eeid", eeid_str);
-					memcpy(&environments[index], &iter->env, sizeof(ExecEnv_t));
-					index ++;
-					break;
-				}
-			}
-		}
-	}
-
-	PRINT_DEBUG("Total %d number of ExecEnv populated", index);
-	/* now keep the record for next eeid, so that if any ee is removed or added then the
-	 * eeid of newly created ee shall be synchronised */
-	if (global_context_exist == false) {
-		s = swmod_uci_add_section(SWMOD_LXC_DU_UCI, "globals", true);
-	}
-
-	snprintf(eeid_str, sizeof(eeid_str), "%u", new_eeid);
-	swmod_uci_set_value_by_section(s, "next_eeid", eeid_str);
-
-	swmod_uci_fini(SWMOD_LXC_DU_UCI);
-}
-
-void set_autoboot_to_config_file(const char *env, bool state, const char *lxc_uci_path)
-{
-	if (lxc_uci_path == NULL || strlen(lxc_uci_path) == 0)
-		return;
-
-	if (0 != swmod_uci_init(lxc_uci_path))
-		return;
-
-	struct uci_section *s = NULL;
-	swmod_uci_foreach_section(SWMOD_LXC_DU_UCI, "container", s) {
-		const char *name = swmod_uci_get_value_by_section(s, "name");
-		const char *type = swmod_uci_get_value_by_section(s, "type");
-		if (strcmp(name, env) == 0 && strcmp(type, "lxc") == 0) {
-			swmod_uci_set_value_by_section(s, "autostart", state ? "1" : "0");
-			swmod_uci_set_value_by_section(s, "timeout", "300");
-			break;
-		}
-	}
-
-	swmod_uci_fini(SWMOD_LXC_DU_UCI);
-}
-
-bool get_autoboot_from_config_file(const char *env, const char *lxc_uci_path)
-{
-	bool found = false;
-
-	if (lxc_uci_path == NULL || strlen(lxc_uci_path) == 0)
-		return found;
-
-	if (swmod_uci_init(lxc_uci_path) != 0)
-		return found;
-
-	struct uci_section *s = NULL;
-	swmod_uci_foreach_section(SWMOD_LXC_DU_UCI, "container", s) {
-		const char *name = swmod_uci_get_value_by_section(s, "name");
-		const char *type = swmod_uci_get_value_by_section(s, "type");
-		const char *autostart = swmod_uci_get_value_by_section(s, "autostart");
-		if (strcmp(name, env) == 0 && strcmp(type, "lxc") == 0 && uci_str_to_bool(autostart)) {
-			found = true;
-			break;
-		}
-	}
-
-	swmod_uci_fini(SWMOD_LXC_DU_UCI);
-	return found;
-}
-
+#if 0
 int get_pid_details(int pid, char *cmdline, int cmd_len, int *vsize)
 {
 	char fcmd[512];
@@ -487,6 +387,7 @@ int get_pid_details(int pid, char *cmdline, int cmd_len, int *vsize)
 
 	return 0;
 }
+#endif
 
 int wait_for_pid(pid_t pid)
 {
@@ -510,79 +411,6 @@ again:
 	return 0;
 }
 
-int update_eu_from_blob(ExecEnv_t *env, struct blob_attr *msg, ExecUnit *node)
-{
-	struct blob_attr *service, *instances, *inst;
-	size_t rem, rem2, rem3;
-	enum {
-		P_RUN,
-		P_PID,
-		__P_MAX
-	};
-	const struct blobmsg_policy p[__P_MAX] = {
-		{ "running", BLOBMSG_TYPE_BOOL },
-		{ "pid", BLOBMSG_TYPE_INT32 },
-	};
-
-	if (env == NULL) {
-		PRINT_ERR("Environment info not provided");
-		return -1;
-	}
-
-	if (env->exists == false) {
-		PRINT_ERR("Environment not exists");
-		return -1;
-	}
-
-	if (node == NULL) {
-		PRINT_ERR("Node not provided");
-		return -1;
-	}
-
-	blobmsg_for_each_attr(service, msg, rem) {
-		blobmsg_for_each_attr(instances, service, rem2) {
-			memset(node, 0, sizeof(ExecUnit));
-			node->eu_exists = true;
-			swmod_strncpy(node->name, blobmsg_name(service), sizeof(node->name));
-			swmod_strncpy(node->environment, env->name, sizeof(node->environment));
-			node->disk_space = -1;
-
-			blobmsg_for_each_attr(inst, instances, rem3) {
-				struct blob_attr *tb[__P_MAX] = {NULL};
-
-				if (blobmsg_parse(p, __P_MAX, tb, blobmsg_data(inst), blobmsg_len(inst)) != 0)
-					continue;
-
-				if (tb[P_PID]) {
-					int euid = blobmsg_get_u32(tb[P_PID]);
-					snprintf(node->euid, sizeof(node->euid), "%d", euid);
-					swmod_get_pid_detail(env, euid, node->command, sizeof(node->command), &node->memory_space);
-				} else {
-					snprintf(node->euid, sizeof(node->euid), "Unknown");
-				}
-
-				if (tb[P_RUN] && blobmsg_get_bool(tb[P_RUN])) {
-					swmod_strncpy(node->state, "Active", sizeof(node->state));
-				} else {
-					swmod_strncpy(node->state, "Idle", sizeof(node->state));
-				}
-
-				swmod_strncpy(node->vendor, "", sizeof(node->vendor));  // TODO
-				break;
-			}
-
-			return 0;
-		}
-	}
-	/*
-	swmod_strncpy(exec_units[0].version[nbr], version, 32);
-	exec_units[0].disk_space[nbr] = disk_space;
-	swmod_strncpy(exec_units[0].description[nbr], spch+14, 1024);
-	swmod_strncpy(exec_units[0].config[nbr], spch+12, 32);
-	*/
-	return -1;
-}
-
 int ubus_call_service_state(char *service, bool state)
 {
 	uint32_t id;
@@ -610,299 +438,35 @@ int ubus_call_service_state(char *service, bool state)
 	return rc;
 }
 
-int get_timeout_from_config_file(const char *env, const char *lxc_uci_path)
-{
-	long timeout = 300; /* default timeout */
-
-	if (lxc_uci_path == NULL || strlen(lxc_uci_path) == 0) {
-		return timeout;
-	}
-
-	if (swmod_uci_init(lxc_uci_path) != 0) {
-		return timeout;
-	}
-
-	struct uci_section *s = NULL;
-	swmod_uci_foreach_section(SWMOD_LXC_DU_UCI, "container", s) {
-		const char *name = swmod_uci_get_value_by_section(s, "name");
-		const char *type = swmod_uci_get_value_by_section(s, "type");
-		if (strcmp(name, env) == 0 && strcmp(type, "lxc") == 0) {
-			const char *time = swmod_uci_get_value_by_section(s, "timeout");
-			if (time != NULL && time[0] != '\0') {
-				timeout = strtol(time, NULL, 10);
-			}
-			break;
-		}
-	}
-
-	swmod_uci_fini(SWMOD_LXC_DU_UCI);
-	return timeout;
-}
-
-void swmod_add_ee_in_list(struct list_head *ee_list, ExecEnv_t *ee)
-{
-	if (ee == NULL) {
-		return;
-	}
-
-	ExecEnvNode *node = (ExecEnvNode *)malloc(sizeof(ExecEnvNode));
-	if (node == NULL) {
-		PRINT_ERR("Out of memory");
-		return;
-	}
-
-	memcpy(&node->env, ee, sizeof(ExecEnv_t));
-	INIT_LIST_HEAD(&node->list);
-	list_add_tail(&node->list, ee_list);
-}
-
-void swmod_delete_ee_list(struct list_head *ee_list)
-{
-	ExecEnvNode *iter = NULL, *node = NULL;
-
-	list_for_each_entry_safe (iter, node, ee_list, list) {
-		list_del(&iter->list);
-		free(iter);
-	}
-}
-
-void swmod_add_eu_in_list(struct list_head *eu_list, ExecUnit *eu)
-{
-	if (eu == NULL) {
-		return;
-	}
-
-	EuNode *node = (EuNode *)malloc(sizeof(EuNode));
-	if (node == NULL) {
-		PRINT_ERR("Out of memory");
-		return;
-	}
-
-	memcpy(&node->eu, eu, sizeof(ExecUnit));
-	INIT_LIST_HEAD(&node->list);
-	list_add_tail(&node->list, eu_list);
-}
-
-void swmod_delete_eu_list(struct list_head *eu_list)
-{
-	EuNode *iter = NULL, *node;
-
-	list_for_each_entry_safe (iter, node, eu_list, list) {
-		list_del(&iter->list);
-		free(iter);
-	}
-}
-
-void get_swmod_config_params(ConfigParams *cfg)
-{
-	if (cfg == NULL)
-		exit(0);
-
-	if (swmod_uci_init(STD_UCI_PATH) != 0)
-		exit(0);
-
-	struct uci_section *s = NULL;
-	swmod_uci_foreach_section(SWMOD_UCI_FILE, "globals", s) {
-		if (strcmp(s->e.name, "globals") == 0) {
-			const char *oci_bundle_root = swmod_uci_get_value_by_section(s, "oci_bundle_root");
-			snprintf(cfg->oci_bundle_root, MAX_LEN_32, "%s", oci_bundle_root);
-
-			const char *lxc_bundle_root = swmod_uci_get_value_by_section(s, "lxc_bundle_root");
-			snprintf(cfg->lxc_bundle_root, MAX_LEN_32, "%s", lxc_bundle_root);
-			break;
-		}
-	}
-	swmod_uci_fini(SWMOD_UCI_FILE);
-
-	if (strlen(cfg->oci_bundle_root) == 0)
-		exit(0);
-
-	if (!dir_exist(cfg->oci_bundle_root))
-		exit(0);
-
-	char oci_du_uci[MAX_LEN_256] = {0};
-	snprintf(oci_du_uci, sizeof(oci_du_uci), "%s/%s", cfg->oci_bundle_root, SWMOD_OCI_DU_UCI);
-	if (!file_exists(oci_du_uci)) {
-		/* oci du uci file not present so create an empty one */
-		FILE *fp = fopen(oci_du_uci, "w");
-		if (fp == NULL)
-			exit(0);
-		fclose(fp);
-	}
-
-	if (strlen(cfg->lxc_bundle_root) == 0)
-		exit(0);
-
-	if (!dir_exist(cfg->lxc_bundle_root))
-		exit(0);
-
-	char lxc_du_uci[MAX_LEN_256] = {0};
-	snprintf(lxc_du_uci, sizeof(lxc_du_uci), "%s/%s", cfg->lxc_bundle_root, SWMOD_LXC_DU_UCI);
-	if (!file_exists(lxc_du_uci)) {
-		/* lxc container uci file not present so create an empty one */
-		FILE *fp = fopen(lxc_du_uci, "w");
-		if (fp == NULL)
-			exit(0);
-		fclose(fp);
-	}
-
-	return;
-}
-
-static bool validate_uuid_in_uci(const char *uuid, const char *uci_path, const char *uci_file)
+bool valid_uuid(char *uuid)
 {
 	bool ret = true;
 
-	if (uuid == NULL || uci_path == NULL || uci_file == NULL ||
-			strlen(uci_file) == 0 || strlen(uci_path) == 0) {
+	if (uuid == NULL)
+		return !ret;
+
+	int len = strlen(uuid);
+	if (len != 36)
 		return !ret;
-	}
 
-	if (swmod_uci_init(uci_path) != 0)
+	/* check if already exists */
+	if (swmod_uci_init(STD_UCI_PATH) != 0)
 		return !ret;
 
 	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(uci_file, "du_eu_assoc", stmp, s) {
+	swmod_uci_foreach_section_safe(SWMOD_UCI_FILE, "du_eu_assoc", stmp, s) {
 		char *id = swmod_uci_get_value_by_section(s, "uuid");
 		if (strcmp(id, uuid) == 0) {
 			ret = false;
 			break;
 		}
 	}
-	swmod_uci_fini(uci_file);
-
-	return ret;
-}
 
-bool valid_uuid(char *uuid, const char *lxc_uci_path, const char *oci_uci_path)
-{
-	bool ret = true;
-
-	if (uuid == NULL)
-		return !ret;
-
-	int len = strlen(uuid);
-	if (len != 36 && len != 0)
-		return !ret;
-
-	if (len != 0) {
-		/* check if already exists */
-		if (lxc_uci_path != NULL && strlen(lxc_uci_path) != 0) {
-			ret = validate_uuid_in_uci(uuid, lxc_uci_path, SWMOD_LXC_DU_UCI);
-		}
-
-		if (oci_uci_path != NULL && strlen(oci_uci_path) != 0) {
-			ret &= validate_uuid_in_uci(uuid, oci_uci_path, SWMOD_OCI_DU_UCI);
-		}
-	}
+	swmod_uci_fini(SWMOD_UCI_FILE);
 
 	return ret;
 }
 
-void get_opkg_description(ExecEnv_t *env, const char *pkg_name, char *desc, size_t desc_size)
-{
-	char cmd[MAX_LEN_256];
-	char output[MAX_LEN_1024];
-
-	if (env == NULL || pkg_name == NULL || desc == NULL)
-		return;
-
-	memset(desc, 0, desc_size);
-	memset(cmd, 0, sizeof(cmd));
-	memset(output, 0, sizeof(output));
-
-	snprintf(cmd, sizeof(cmd), "grep Description: /usr/lib/opkg/info/%s.control", pkg_name);
-	swmod_run_cmd(env, cmd, output, sizeof(output));
-	char *spch = strstr(output, "Description:");
-	if (spch) {
-		remove_new_line(spch);
-		snprintf(desc, desc_size, "%s", spch+14);
-	}
-}
-
-void buffer_add_line(struct list_head *head, char *entry)
-{
-	struct buffer_list *node = NULL;
-
-	if (entry == NULL)
-		return;
-
-	node = (struct buffer_list *) malloc(sizeof(*node));
-	if (!node) {
-		PRINT_ERR("Out of memory!");
-		return;
-	}
-
-	swmod_strncpy(node->line, entry, MAX_LEN_128);
-
-	INIT_LIST_HEAD(&node->list);
-	list_add_tail(&node->list, head);
-}
-
-void create_buffer_list(struct list_head *opkg_list, char *buffer)
-{
-	char *token = NULL;
-
-	if (buffer == NULL)
-		return;
-
-	if (strlen(buffer) == 0)
-		return;
-
-	token = strtok(buffer, "\n");
-	while (token != NULL) {
-		buffer_add_line(opkg_list, token);
-		token = strtok(NULL, "\n");
-	}
-}
-
-void delete_buffer_list(struct list_head *opkg_list)
-{
-	struct buffer_list *iter, *node;
-
-	list_for_each_entry_safe (iter, node, opkg_list, list) {
-		list_del(&iter->list);
-		free(iter);
-	}
-}
-
-void get_opkg_service_name(ExecEnv_t *env, const char *pkg_name, char *service, size_t serv_size)
-{
-	char cmd[MAX_LEN_256];
-	char output[MAX_LEN_1024];
-
-	if (env == NULL || pkg_name == NULL || service == NULL)
-		return;
-
-	memset(service, 0, serv_size);
-	memset(cmd, 0, sizeof(cmd));
-	memset(output, 0, sizeof(output));
-
-	snprintf(cmd, sizeof(cmd), "opkg files %s 2>&1", pkg_name);
-	swmod_run_cmd(env, cmd, output, sizeof(output));
-
-	if (strlen(output) == 0)
-		return;
-
-	LIST_HEAD(opkg_files_list);
-	create_buffer_list(&opkg_files_list, output);
-
-	if (!list_empty(&opkg_files_list)) {
-		struct buffer_list *iter;
-
-		list_for_each_entry(iter, &opkg_files_list, list) {
-			char *spch = strstr(iter->line, SWMOD_INIT_PATH);
-			if (spch) {
-				remove_new_line(spch);
-				snprintf(service, serv_size, "%s", spch+strlen(SWMOD_INIT_PATH));
-				break;
-			}
-		}
-	}
-
-	delete_buffer_list(&opkg_files_list);
-}
-
 time_t convert_str_to_time(const char *time)
 {
 	unsigned long tm = 0;
@@ -1027,141 +591,750 @@ int download_remote_package(const char *url, const char *username, const char *p
 	return -1;
 }
 
-int swmod_ee_uci_init(ExecEnv_t *env, char *uci_file, int len)
+void swmod_reset_ee_runlevel(struct uci_section *sec)
 {
-	int ret = -1;
+	if (sec == NULL)
+		return;
 
-	if (env == NULL || uci_file == NULL)
-		return ret;
+	const char *cur_level = swmod_uci_get_value_by_section(sec, "current_runlevel");
+	if (strcmp(cur_level, "-1") != 0) {
+		const char *init_level = swmod_uci_get_value_by_section(sec, "initial_runlevel");
+		swmod_uci_set_value_by_section(sec, "current_runlevel", init_level);
+	}
+}
 
-	switch (env->ee_type) {
-	case EE_TYPE_HOST:
-#ifdef SWMOD_CRUN
-		if (strlen(swmod_config.oci_bundle_root) != 0) {
-			snprintf(uci_file, len, "%s", SWMOD_OCI_DU_UCI);
-			ret = swmod_uci_init(swmod_config.oci_bundle_root);
+void swmod_update_du_eu_assoc(struct list_head *du_head)
+{
+	struct uci_section *d = NULL;
+	bool found = false;
+	duInfoNode_t *iter = NULL;
+	time_t now;
+	char ctime[MAX_LEN_32] = {0};
+	char *duid = NULL;
+
+	swmod_uci_foreach_section(SWMOD_UCI_FILE, "du_eu_assoc", d) {
+		/* if du installation is pending, nothing to do */
+		const char *du_status = swmod_uci_get_value_by_section(d, "status");
+		if (strcmp(du_status, "Installing") == 0)
+			continue;
+
+		/* If du not exist in list then remove from uci */
+		if (list_empty(du_head)) {
+			swmod_uci_delete_by_section(d, NULL, NULL);
+			continue;
 		}
-#endif
-		break;
-	case EE_TYPE_LXC:
-#ifdef SWMOD_LXC
-		if (strlen(swmod_config.lxc_bundle_root) != 0) {
-			snprintf(uci_file, len, "%s", SWMOD_LXC_DU_UCI);
-			ret = swmod_uci_init(swmod_config.lxc_bundle_root);
+
+		const char *execenv = swmod_uci_get_value_by_section(d, "execenv");
+		found = false;
+		iter = NULL;
+
+		list_for_each_entry(iter, du_head, list) {
+			if (strcmp(iter->du.du_name, d->e.name) == 0 &&
+			    strcmp(iter->du.execenv, execenv) == 0) {
+				found = true;
+				break;
+			}
+		}
+
+		if (found == false)
+			swmod_uci_delete_by_section(d, NULL, NULL);
+		else {
+			/* If du type is not in capability */
+			bool du_capable = false;
+			const char *type = swmod_uci_get_value_by_section(d, "du_type");
+
+			if (strcmp(type, "OCIImage") == 0)
+				du_capable = swmod_du_type_capable(DU_TYPE_CRUN);
+			else if (strcmp(type, "LXC") == 0)
+				du_capable = swmod_du_type_capable(DU_TYPE_LXC);
+
+			if (!du_capable)
+				swmod_du_remove(d);
 		}
-#endif
-		break;
-	default:
-		ret = -1;
 	}
 
-	return ret;
+	/* Now if any new du found in build-root then add it in uci */
+	if (list_empty(du_head))
+		return;
+
+	iter = NULL;
+	list_for_each_entry(iter, du_head, list) {
+		found = false;
+		swmod_uci_foreach_section(SWMOD_UCI_FILE, "du_eu_assoc", d) {
+			if (strcmp(iter->du.du_name, d->e.name) == 0) {
+				found = true;
+				break;
+			}
+		}
+
+		if (found == false) {
+			if (!swmod_du_type_capable(iter->du.du_type)) {
+				char path[2056] = {0};
+				snprintf(path, sizeof(path), "%s/%s", iter->du.execenv, iter->du.du_name);
+				remove_dir(path);
+				continue;
+			}
+
+			duid = generate_duid(iter->du.execenv, iter->du.du_name);
+
+			struct uci_section *s = swmod_uci_add_section(SWMOD_UCI_FILE, "du_eu_assoc", iter->du.du_name);
+			swmod_uci_set_value_by_section(s, "uuid", generate_uuid());
+			swmod_uci_set_value_by_section(s, "duid", duid);
+			swmod_uci_set_value_by_section(s, "status", "Installed");
+			swmod_uci_set_value_by_section(s, "url", "");
+			swmod_uci_set_value_by_section(s, "description", "");
+			swmod_uci_set_value_by_section(s, "version", "");
+			swmod_uci_set_value_by_section(s, "du_type", (iter->du.du_type == DU_TYPE_CRUN) ? "OCIImage" : "LXC");
+			now = time(NULL);
+			strftime(ctime, sizeof(ctime), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
+			swmod_uci_set_value_by_section(s, "installed_at", ctime);
+			swmod_uci_set_value_by_section(s, "eu_autostart", "1");
+			swmod_uci_set_value_by_section(s, "eu_runlevel", strlen(iter->du.eu_runlevel) ? iter->du.eu_runlevel : "0");
+			swmod_uci_set_value_by_section(s, "execenv", iter->du.execenv);
+			FREE(duid);
+		}
+	}
 }
 
-int set_du_alias_to_config(const char *ee_name, const char *uuid,
-			const char *alias, const char *bundle, const char *uci_file)
+int swmod_du_type(char *du_path)
 {
-	int ret = -1;
+	char conf_path[5012] = {0};
+	int du_type;
+	int flag = 0;
 
-	if (ee_name == NULL || uuid == NULL || alias == NULL ||
-			bundle == NULL || uci_file == NULL)
-		return ret;
+	if (!du_path)
+		return DU_TYPE_MAX;
 
-	if (strlen(bundle) == 0)
-		return ret;
+	snprintf(conf_path, sizeof(conf_path), "%s/%s", du_path, "config.json");
+	if (file_exists(conf_path)) {
+		du_type = DU_TYPE_CRUN;
+		flag++;
+	}
 
-	if (strlen(uci_file) == 0)
-		return ret;
+	snprintf(conf_path, sizeof(conf_path), "%s/%s", du_path, "config");
+	if (file_exists(conf_path)) {
+		du_type = DU_TYPE_LXC;
+		flag++;
+	}
+	
+	if (flag != 1)
+		return DU_TYPE_MAX;
 
-	if (swmod_uci_init(bundle) != 0)
-		return ret;
+	return du_type;
+}
 
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(uci_file, "du_eu_assoc", stmp, s) {
-		char *name = swmod_uci_get_value_by_section(s, "ee_name");
-		char *du_uuid = swmod_uci_get_value_by_section(s, "uuid");
+void swmod_get_du_list(const char *base_path, const char *eu_runlevel, struct list_head *du_head)
+{
+	struct dirent *dp;
+	DIR *dir;
 
-		if (strcmp(ee_name, name) == 0 && strcmp(uuid, du_uuid) == 0) {
-			swmod_uci_set_value_by_section(s, "du_alias", alias);
-			ret = 0;
-			break;
+	if (!base_path || !du_head)
+		return;
+
+	dir = opendir(base_path);
+	if (dir == NULL)
+		return;
+
+	while ((dp = readdir(dir)) != NULL) {
+		char full_path[2056] = {0};
+		int du_type = DU_TYPE_MAX;
+
+		// skip entries "." and ".."
+		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
+			continue;
+
+		snprintf(full_path, sizeof(full_path), "%s/%s", base_path, dp->d_name);
+		du_type = swmod_du_type(full_path);
+
+		if (dir_exist(full_path) && du_type != DU_TYPE_MAX) {
+			duInfoNode_t *node = (duInfoNode_t *)malloc(sizeof(duInfoNode_t));
+			if (node == NULL)
+				continue;
+
+			snprintf(node->du.du_name, sizeof(node->du.du_name), "%s", dp->d_name);
+			snprintf(node->du.eu_runlevel, sizeof(node->du.eu_runlevel), "%s", eu_runlevel);
+			node->du.du_type = du_type;
+			snprintf(node->du.execenv, sizeof(node->du.execenv), "%s", base_path);
+
+			INIT_LIST_HEAD(&node->list);
+			list_add_tail(&node->list, du_head);
 		}
 	}
+}
 
-	swmod_uci_fini(uci_file);
+void swmod_free_du_list(struct list_head *du_head)
+{
+	duInfoNode_t *iter = NULL, *node = NULL;
 
-	return ret;
+	list_for_each_entry_safe(iter, node, du_head, list) {
+		list_del(&iter->list);
+		FREE(iter);
+	}
 }
 
-int set_eu_alias_to_config(const char *ee_name, const char *eu_name,
-			const char *alias, const char *bundle, const char *uci_file)
+int swmod_du_remove(struct uci_section *sec)
 {
-	int ret = -1;
+	char path[2056] = {0};
 
-	if (ee_name == NULL || eu_name == NULL || alias == NULL ||
-			bundle == NULL || uci_file == NULL)
-		return ret;
+	if (!sec)
+		return -1;
 
-	if (strlen(bundle) == 0)
-		return ret;
+	const char *execenv = swmod_uci_get_value_by_section(sec, "execenv");
 
-	if (strlen(uci_file) == 0)
-		return ret;
+	snprintf(path, sizeof(path), "%s/%s", execenv, sec->e.name);
+	remove_dir(path);
+	swmod_uci_delete_by_section(sec, NULL, NULL);
 
-	if (swmod_uci_init(bundle) != 0)
-		return ret;
+	return 0;
+}
 
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(uci_file, "du_eu_assoc", stmp, s) {
-		char *ee = swmod_uci_get_value_by_section(s, "ee_name");
-		char *eu = swmod_uci_get_value_by_section(s, "eu_name");
+void swmod_execenv_add(struct uci_section *sec)
+{
+	struct list_head du_head;
+	duInfoNode_t *iter = NULL, *node = NULL;
+	struct uci_section *d;
+	char *duid = NULL;
+	char ctime[MAX_LEN_32] = {0};
+
+	if (!sec)
+		return;
+
+	const char *name = swmod_uci_get_value_by_section(sec, "name");
+	if (strlen(name) == 0) {
+		return;
+	}
+
+	if (!dir_exist(name)) {
+		/* Create non existing execenv */
+		if (!create_dir(name))
+			swmod_uci_set_value_by_section(sec, "status", "Error");
+
+		swmod_uci_set_value_by_section(sec, "action", "");
+		return;
+	}
+
+	const char *eu_runlevel = swmod_uci_get_value_by_section(sec, "initial_eu_runlevel");
+	/* dir already exists, need to sync DUs */
+	memset(&du_head, 0, sizeof(struct list_head));
+	INIT_LIST_HEAD(&du_head);
+
+	swmod_get_du_list(name, eu_runlevel, &du_head);
+
+	list_for_each_entry_safe(iter, node, &du_head, list) {
+		bool found = false;
+		swmod_uci_foreach_section(SWMOD_UCI_FILE, "du_eu_assoc", d) {
+			if (strcmp(iter->du.du_name, d->e.name) == 0) {
+				found = true;
+				break;
+			}
+		}
+
+		if (found == false) {
+			if (!swmod_du_type_capable(iter->du.du_type)) {
+				char path[2056] = {0};
+				snprintf(path, sizeof(path), "%s/%s", iter->du.execenv, iter->du.du_name);
+				remove_dir(path);
+				continue;
+			}
+
+			duid = generate_duid(iter->du.execenv, iter->du.du_name);
+
+			struct uci_section *s = swmod_uci_add_section(SWMOD_UCI_FILE, "du_eu_assoc", iter->du.du_name);
+			swmod_uci_set_value_by_section(s, "uuid", generate_uuid());
+			swmod_uci_set_value_by_section(s, "duid", duid ? duid : "");
+			swmod_uci_set_value_by_section(s, "status", "Installed");
+			swmod_uci_set_value_by_section(s, "url", "");
+			swmod_uci_set_value_by_section(s, "description", "");
+			swmod_uci_set_value_by_section(s, "version", "");
+			swmod_uci_set_value_by_section(s, "du_type", (iter->du.du_type == DU_TYPE_CRUN) ? "OCIImage" : "LXC");
+			time_t now = time(NULL);
+			strftime(ctime, sizeof(ctime), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
+			swmod_uci_set_value_by_section(s, "installed_at", ctime);
+			swmod_uci_set_value_by_section(s, "eu_autostart", "1");
+			swmod_uci_set_value_by_section(s, "eu_runlevel", strlen(iter->du.eu_runlevel) ? iter->du.eu_runlevel : "0");
+			swmod_uci_set_value_by_section(s, "execenv", iter->du.execenv);
+			FREE(duid);
+		}
+	}
+
+	swmod_free_du_list(&du_head);
+	swmod_uci_set_value_by_section(sec, "action", "");
+}
+
+void swmod_execenv_remove(struct uci_section *sec, bool force)
+{
+	struct uci_section *d;
+	int du_count = 0;
+	bool env_busy = false;
+	
+	if (!sec)
+		return;
+
+	const char *name = swmod_uci_get_value_by_section(sec, "name");
+	if (strlen(name) == 0) {
+		swmod_uci_set_value_by_section(sec, "action", "");
+		return;
+	}
+
+	if (!dir_exist(name)) {
+		swmod_uci_delete_by_section(sec, NULL, NULL);
+		return;
+	}
+
+	swmod_uci_foreach_section(SWMOD_UCI_FILE, "du_eu_assoc", d) {
+		const char *execenv = swmod_uci_get_value_by_section(d, "execenv");
+		if (strcmp(execenv, name) == 0) {
+			du_count++;
+			char *du_status = swmod_uci_get_value_by_section(d, "status");
+			if (strcmp(du_status, "Installed") != 0) {
+				env_busy = true;
+				break;
+			}
+		}
+	}
+
+	if (env_busy || (du_count > 0 && force == false)) {
+		swmod_uci_set_value_by_section(sec, "action", "");
+		return;
+	}
+
+	if (du_count == 0) {
+		swmod_uci_delete_by_section(sec, NULL, NULL);
+		remove_dir(name);
+		return;
+	}
+
+	/* Stop all EUs then remove execenv */
+	swmod_uci_foreach_section(SWMOD_UCI_FILE, "du_eu_assoc", d) {
+		const char *execenv = swmod_uci_get_value_by_section(d, "execenv");
+		const char *type = swmod_uci_get_value_by_section(d, "du_type");
+		if (strcmp(execenv, name) == 0) {
+			swmod_stop_execunit(execenv, d->e.name, type);
+			swmod_uci_delete_by_section(d, NULL, NULL);
+		}
+	}
+
+	swmod_uci_delete_by_section(sec, NULL, NULL);
+	remove_dir(name);
+}
+
+void swmod_perform_du_operation(struct ubus_context *ubus_ctx, PkgInfo *pkg, size_t size)
+{
+	int fd[2];
+
+	if (!pkg) {
+		PRINT_ERR("No package info!");
+		return;
+	}
+
+	if (pipe(fd) < 0) {
+		PRINT_ERR("Pipe failed!");
+		return;
+	}
+
+	pid_t child = fork();
+	if (child == -1) {
+		PRINT_ERR("Fork error!");
+		return;
+	} else if(child != 0) {
+		// parent
+		close(fd[0]);
+		write(fd[1], pkg, size);
+		close(fd[1]);
+	} else {
+		// child
+		prctl(PR_SET_NAME, "swmod_du_operation");
+		ubus_shutdown(ubus_ctx);
+		uloop_done();
+		close(fd[1]);
+
+		char fault[256] = {0};
+		int fault_code = 0;
+		PkgInfo p_info;
+		time_t start;
+
+		memset(&p_info, 0, sizeof(PkgInfo));
+		if (read(fd[0], &p_info, sizeof(PkgInfo)) == -1) {
+			close(fd[0]);
+			PRINT_ERR("Package info read failed!");
+			exit(EXIT_FAILURE);
+		}
+
+		close(fd[0]);
+
+		start = time(NULL);
+		fault_code = invalid_du_request(&p_info, fault);
+
+		if (fault_code) {
+			swmod_send_event_du_state_change(&p_info, fault_code, fault, start);
+			exit(EXIT_SUCCESS);
+		}
 
-		if (strcmp(ee_name, ee) == 0 && strcmp(eu_name, eu) == 0) {
-			swmod_uci_set_value_by_section(s, "eu_alias", alias);
-			ret = 0;
+		switch (p_info.operation) {
+		case SWMOD_INSTALL:
+			swmod_perform_du_install(&p_info, start);
+			break;
+		case SWMOD_REMOVE:
 			break;
 		}
+
+		exit(EXIT_SUCCESS);
 	}
+}
 
-	swmod_uci_fini(uci_file);
+void swmod_send_event_du_state_change(PkgInfo *pkg, int err_code, char *msg, time_t start)
+{
+	char start_time[MAX_LEN_32] = {0};
+	char end_time[MAX_LEN_32] = {0};
+	time_t end;
+	struct ubus_context *ctx; // This function will be invoked from child so need ubus context */
+	char *operation = NULL;
+	char *state = NULL;
+	struct blob_buf bb;
+	unsigned int id;
+
+	if (!pkg)
+		return;
 
-	return ret;
+	ctx = ubus_connect(NULL);
+
+	if (!ctx)
+		return;
+
+	end = time(NULL);
+
+	strftime(start_time, sizeof(start_time), "%Y-%m-%dT%H:%M:%SZ", gmtime(&start));
+	strftime(end_time, sizeof(end_time), "%Y-%m-%dT%H:%M:%SZ", gmtime(&end));
+
+	switch (pkg->operation) {
+	case SWMOD_INSTALL:
+		operation = "Install";
+		state = (err_code) ? "Failed" : "Installed";
+		break;
+	case SWMOD_REMOVE:
+		operation = "Uninstall";
+		state = (err_code) ? "Failed" : "Installed";
+		break;
+	}
+
+	memset(&bb, 0, sizeof(struct blob_buf));
+	blob_buf_init(&bb, 0);
+
+	blobmsg_add_string(&bb, "name", "Device.SoftwareModules.DUStateChange!");
+
+	void *tbl = blobmsg_open_table(&bb, "input");
+	blobmsg_add_string(&bb, "UUID", pkg->uuid);
+	blobmsg_add_string(&bb, "Version", pkg->version);
+	blobmsg_add_string(&bb, "CurrentState", state);
+	blobmsg_add_string(&bb, "Resolved", err_code ? "0" : "1");
+	blobmsg_add_string(&bb, "StartTime", start_time);
+	blobmsg_add_string(&bb, "CompleteTime", end_time);
+	blobmsg_add_string(&bb, "OperationPerformed", operation);
+	blobmsg_add_u32(&bb, "Fault.FaultCode", err_code);
+	blobmsg_add_string(&bb, "Fault.FaultString", err_code ? msg : "");
+
+	blobmsg_close_table(&bb, tbl);
+
+	if (!ubus_lookup_id(ctx, "bbfdm", &id))
+		ubus_invoke(ctx, id, "notify_event", bb.head, NULL, NULL, UBUS_TIMEOUT);
+
+	blob_buf_free(&bb);
+	ubus_free(ctx);
+
+	return;
 }
 
-int set_eu_autostart_to_config(const char *ee_name, const char *eu_name,
-			bool enable, const char *bundle, const char *uci_file)
+int invalid_du_request(PkgInfo *pkg, char *fault)
 {
-	int ret = -1;
+	char du_name[256] = {0};
+	char du_path[2056] = {0};
+	struct uci_section *sec = NULL;
 
-	if (ee_name == NULL || eu_name == NULL ||
-			bundle == NULL || uci_file == NULL)
-		return ret;
+	if (!pkg) {
+		snprintf(fault, MAX_LEN_256, "Internal error");
+		return 7002;
+	}
 
-	if (strlen(bundle) == 0)
-		return ret;
+	switch (pkg->operation) {
+	case SWMOD_INSTALL:
+		if (swmod_uci_init(STD_UCI_PATH) != 0) {
+			snprintf(fault, MAX_LEN_256, "Internal error");
+			return 7002;
+		}
 
-	if (strlen(uci_file) == 0)
-		return ret;
+		if (strlen(pkg->url) == 0) {
+			snprintf(fault, MAX_LEN_256, "DU URL is empty");
+			swmod_uci_fini(SWMOD_UCI_FILE);
+			return 7002;
+		}
 
-	if (swmod_uci_init(bundle) != 0)
-		return ret;
+		/* extract du name from url and validate */
+		if (get_filename_from_url(pkg->url, du_name, sizeof(du_name)) != 0) {
+			snprintf(fault, MAX_LEN_256, "DU name invalid");
+			swmod_uci_fini(SWMOD_UCI_FILE);
+			return 7002;
+		}
 
-	struct uci_section *s = NULL, *stmp = NULL;
-	swmod_uci_foreach_section_safe(uci_file, "du_eu_assoc", stmp, s) {
-		char *ee = swmod_uci_get_value_by_section(s, "ee_name");
-		char *eu = swmod_uci_get_value_by_section(s, "eu_name");
+		snprintf(du_path, sizeof(du_path), "%s/%s", pkg->execenv, du_name);
+		if (dir_exist(du_path)) {
+			snprintf(fault, MAX_LEN_256, "DU with name (%s) already exist.", du_name);
+			swmod_uci_fini(SWMOD_UCI_FILE);
+			return 7226;
+		}
+
+		sec = NULL;
+		swmod_uci_foreach_section(SWMOD_UCI_FILE, "du_eu_assoc", sec) {
+			if (strcmp(du_name, sec->e.name) == 0) {
+				snprintf(fault, MAX_LEN_256, "DU with name (%s) already exist.", du_name);
+				swmod_uci_fini(SWMOD_UCI_FILE);
+				return 7226;
+			}
+		}
+
+		snprintf(pkg->du_name, sizeof(pkg->du_name), "%s", du_name);
+
+		/* Check if URL has user info */
+		if (strncmp(pkg->url, "docker://", 9) != 0 && strchr(pkg->url, '@') != NULL) {
+			/* In docker link there could be '@' for specific sha */
+			snprintf(fault, MAX_LEN_256, "URL contains user info");
+			swmod_uci_fini(SWMOD_UCI_FILE);
+			return 7004;
+		}
+
+		if (strlen(pkg->execenv) == 0) {
+			snprintf(fault, MAX_LEN_256, "No suitable execution environment, may be all are busy as of now.");
+			swmod_uci_fini(SWMOD_UCI_FILE);
+			return 7225;
+		} else {
+			/* Check if the execenv exists then it is enabled and not busy in any operation */
+			int err_code = 7223;
+			sec = NULL;
+
+			snprintf(fault, MAX_LEN_256, "Unknown execution environment.");
+
+			swmod_uci_foreach_section(SWMOD_UCI_FILE, "execenv", sec) {
+				const char *execenv = swmod_uci_get_value_by_section(sec, "name");
+
+				if (strcmp(execenv, pkg->execenv) == 0) {
+					const char *enable = swmod_uci_get_value_by_section(sec, "enable");
+					const char *action = swmod_uci_get_value_by_section(sec, "action");
+					if (strlen(action) == 0 && enable[0] == '1')
+						err_code = 0;
+					else {
+						snprintf(fault, MAX_LEN_256, "Execution environment is busy or disabled.");
+						err_code = 7002;
+					}
+
+					break;
+				}
+
+			}
+
+			if (err_code != 0) {
+				swmod_uci_fini(SWMOD_UCI_FILE);
+				return err_code;
+			}
+		}
+
+		swmod_uci_fini(SWMOD_UCI_FILE);
+		if (!valid_uuid(pkg->uuid)) {
+			snprintf(fault, MAX_LEN_256, "Invalid UUID.");
+			return 7002;
+		}
+
+		break;
+	case SWMOD_REMOVE:
+		break;
+	}
+
+	return 0;
+}
+
+void swmod_perform_du_install(PkgInfo *pkg, time_t start)
+{
+	int err = 7002;
+	char msg[256] = {0};
+	char *duid = NULL;
+	struct uci_section *sec = NULL;
+	char ctime[MAX_LEN_32] = {0};
+
+	snprintf(msg, sizeof(msg), "Internal error!");
+
+	if (swmod_uci_init(STD_UCI_PATH) != 0) {
+		swmod_send_event_du_state_change(pkg, err, msg, start);
+		return;
+	}
+
+	duid = generate_duid(pkg->execenv, pkg->du_name);
+
+	sec = swmod_uci_add_section(SWMOD_UCI_FILE, "du_eu_assoc", pkg->du_name);
+	swmod_uci_set_value_by_section(sec, "url", pkg->url);
+	swmod_uci_set_value_by_section(sec, "uuid", pkg->uuid);
+	swmod_uci_set_value_by_section(sec, "status", "Installing");
+	swmod_uci_set_value_by_section(sec, "duid", duid ? duid : "");
+	swmod_uci_set_value_by_section(sec, "execenv", pkg->execenv);
+
+	err = swmod_install_package(pkg);
 
-		if (strcmp(ee_name, ee) == 0 && strcmp(eu_name, eu) == 0) {
-			swmod_uci_set_value_by_section(s, "autostart", enable ? "1" : "0");
-			ret = 0;
+	time_t now = time(NULL);
+	strftime(ctime, sizeof(ctime), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
+
+	if (!err) {
+		struct uci_section *env = NULL;
+
+		swmod_uci_set_value_by_section(sec, "status", "Installed");
+		swmod_uci_set_value_by_section(sec, "du_type", (pkg->du_type == DU_TYPE_CRUN) ? "OCIImage" : "LXC");
+		swmod_uci_set_value_by_section(sec, "installed_at", ctime);
+		swmod_uci_set_value_by_section(sec, "eu_autostart", pkg->autostart ? "1" : "0");
+
+		check_section_exist_by_option("swmodd", "execenv", "name", pkg->execenv, &env);
+		if (env) {
+			const char *eu_runlevel = swmod_uci_get_value_by_section(env, "initial_eu_runlevel");
+			swmod_uci_set_value_by_section(sec, "eu_runlevel", eu_runlevel);
+		}
+
+		swmod_send_event_du_state_change(pkg, err, "", start);
+	} else {
+		switch (err) {
+		case 7227:
+			snprintf(msg, sizeof(msg), "Memory not available.");
+			break;
+		case 7225:
+			snprintf(msg, sizeof(msg), "DU type to execution environment mismatch");
+			break;
+		case 7033:
+			snprintf(msg, sizeof(msg), "Download failure from server");
+			break;
+		case 7035:
+			snprintf(msg, sizeof(msg), "Corrupt of empty package or the package is not available.");
 			break;
 		}
+
+		swmod_send_event_du_state_change(pkg, err, msg, start);
+		swmod_uci_delete_by_section(sec, NULL, NULL);
 	}
 
-	swmod_uci_fini(uci_file);
+	FREE(duid);
+	swmod_uci_fini(SWMOD_UCI_FILE);
+}
+
+int swmod_install_package(PkgInfo *pkg)
+{
+	int ret = 0;
+
+	if (!pkg)
+		return 7002;
+
+	char *tmp = strrchr(pkg->url, '.');
+	if (tmp != NULL && strcmp(tmp, ".tar") == 0) {
+		char path[2056] = {0};
+		bool remote_file = false;
+
+		/* This is a tar package need to extract */
+		if (strstr(pkg->url, "file://") == NULL) {
+			// remote tar package download
+			remote_file = true;
+			ret = download_remote_du(pkg);
+			snprintf(path, sizeof(path), "/tmp/%s.tar", pkg->du_name);
+		} else {
+			snprintf(path, sizeof(path), "%s", pkg->url+6);
+		}
+
+		if (ret)
+			return ret;
 
-	if (ret == 0)
-		swmod_uci_commit("crun");
+		ret = install_du_package(path, pkg);
+		if (remote_file && file_exists(path))
+			remove(path);
+	} else {
+		// registry image
+	}
 
 	return ret;
 }
+
+int install_du_package(char *url, PkgInfo *pkg)
+{
+	char cmd[2056] = {0};
+	char bundle_dir[515] = {0};
+
+	if (!url || strlen(url) == 0 || !pkg || strlen(pkg->execenv) == 0)
+		return 7002;
+
+	unsigned long size = get_file_size_kb(url);
+	if (size == 0)
+		return 7035;
+
+	if (!memory_available(size * 2, pkg->execenv))
+		return 7227;
+
+	snprintf(bundle_dir, sizeof(bundle_dir), "%s/%s", pkg->execenv, pkg->du_name);
+	if (!create_dir(bundle_dir))
+		return 7002;
+
+	snprintf(cmd, sizeof(cmd), "tar -xf %s -C %s", url, bundle_dir);
+
+	if (0 != run_cmd_no_output(cmd)) {
+		remove_dir(bundle_dir);
+		return 7002;
+	}
+
+	pkg->du_type = swmod_du_type(bundle_dir);
+	if (pkg->du_type == DU_TYPE_MAX || !swmod_du_type_capable(pkg->du_type)) {
+		remove_dir(bundle_dir);
+		return 7225;
+	}
+
+	return 0;
+}
+
+int download_remote_du(PkgInfo *pkg)
+{
+	char path[515] = {0};
+
+	if (!pkg)
+		return 7002;
+
+	unsigned long size = get_remote_file_size(pkg->url, pkg->uname, pkg->psw);
+	if (size == 0)
+		return 7002;
+
+	if (!memory_available(size, "/tmp"))
+		return 7227;
+
+	snprintf(path, sizeof(path), "/tmp/%s.tar", pkg->du_name);
+	if (0 != download_remote_package(pkg->url, pkg->uname, pkg->psw, path)) {
+		if (file_exists(path))
+			remove(path);
+
+		return 7033;
+	}
+
+	return 0;
+}
+
+char *swmod_select_env(void)
+{
+	/* Select an execenv which is not busy and enabled */
+	char *env = NULL;
+	struct uci_section *sec = NULL;
+
+	if (swmod_uci_init(STD_UCI_PATH) != 0) {
+		return env;
+	}
+
+	swmod_uci_foreach_section(SWMOD_UCI_FILE, "execenv", sec) {
+		const char *execenv = swmod_uci_get_value_by_section(sec, "name");
+		const char *enable = swmod_uci_get_value_by_section(sec, "enable");
+		const char *action = swmod_uci_get_value_by_section(sec, "action");
+
+		if (strlen(action) == 0 && enable[0] == '1') {
+			env = strdup(execenv);
+			break;
+		}
+	}
+
+	swmod_uci_fini(STD_UCI_PATH);
+
+	return env;
+}
diff --git a/src/tools.h b/src/tools.h
index 07b012236317a56830303070d166f3a92df27833..bfba14082d306c13745b2fd1d42ac04ecea59fc8 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -16,55 +16,17 @@
 #include <time.h>
 #include <libubox/list.h>
 #include <syslog.h>
+#include <uci.h>
 
 #include "swmod.h"
 
-#define OPKG_INFO_PATH "/usr/lib/opkg/info/"
 #define STD_UCI_PATH "/etc/config/"
 #define SWMOD_UCI_FILE "swmodd"
-#define SWMOD_OCI_DU_UCI "ocicontainer"
-#define SWMOD_LXC_DU_UCI "lxccontainer"
-#define SWMOD_INIT_PATH "/etc/init.d/"
-
-#define SYSFS_FOREACH_FILE(path, dir, ent) \
-	if ((dir = opendir(path)) == NULL) return 0; \
-	while ((ent = readdir (dir)) != NULL) \
 
 #ifndef FREE
 #define FREE(x) do { if(x) {free(x); x = NULL;} } while (0)
 #endif
 
-enum swmod_action_enum {
-	SWMOD_DEPLOYMENT_UNIT,
-	SWMOD_EXECUTION_UNIT
-};
-
-enum {
-	SUCCESS,
-	FAILURE,
-	LXC_NOT_SUPPORTED,
-	NOT_FOUND,
-	ALREADY_RUNNING,
-	NOT_RUNNING,
-	INVALID_REQUEST,
-	CRUN_NOT_SUPPORTED,
-	__ERROR_MAX
-};
-
-enum {
-	CONT_START,
-	CONT_STOP,
-	CONT_PAUSE,
-	CONT_RESUME,
-	__CONT_STATE_MAX
-};
-
-struct buffer_list
-{
-	struct list_head list;
-	char line[MAX_LEN_128];
-};
-
 bool file_exists(const char *path);
 unsigned long get_file_size_kb(const char *path);
 bool create_dir(const char *path);
@@ -74,7 +36,7 @@ void remove_new_line(char *buf);
 void create_file(const char *path);
 void swmod_strncpy(char *dst, const char *src, size_t n);
 char *generate_uuid(void);
-char *generate_duid(bool sysnchronise, int number);
+char *generate_duid(const char *ee_name, const char *du_name);
 int wait_for_pid(pid_t pid);
 
 void configure_debug_level(unsigned char level);
@@ -82,36 +44,29 @@ void print_error(const char *format, ...);
 void print_warning(const char *format, ...);
 void print_info(const char *format, ...);
 void print_debug(const char *format, ...);
-int get_pid_details(int pid, char *cmdline, int cmd_len, int *vsize);
-int update_eu_from_blob(ExecEnv_t *env, struct blob_attr *msg, ExecUnit *node);
+//int get_pid_details(int pid, char *cmdline, int cmd_len, int *vsize);
 int ubus_call_service_state(char *service, bool state);
 bool dir_exist(const char *dir);
-bool get_autoboot_from_config_file(const char *env, const char *lxc_uci_path);
-void set_autoboot_to_config_file(const char *env, bool state, const char *lxc_uci_path);
-int get_timeout_from_config_file(const char *env, const char *lxc_uci_path);
-void swmod_add_eu_in_list(struct list_head *eu_list, ExecUnit *eu);
-void swmod_delete_eu_list(struct list_head *eu_list);
-void swmod_add_ee_in_list(struct list_head *ee_list, ExecEnv_t *eu);
-void swmod_delete_ee_list(struct list_head *ee_list);
-void sync_eeid_with_uci(struct list_head *ee_list, ExecEnv_t *environments, const char *lxc_uci_path);
-void get_swmod_config_params(ConfigParams *cfg);
-const char* ee_state_failure_reason(int err);
-int get_requested_container_state(char *state);
-int get_env_type(const char *type);
-bool valid_uuid(char *uuid, const char *lxc_uci_path, const char *oci_uci_path);
-void get_opkg_description(ExecEnv_t *env, const char *pkg_name, char *desc, size_t desc_size);
-void get_opkg_service_name(ExecEnv_t *env, const char *pkg_name, char *service, size_t serv_size);
-void buffer_add_line(struct list_head *head, char *entry);
-void create_buffer_list(struct list_head *opkg_list, char *buffer);
-void delete_buffer_list(struct list_head *opkg_list);
+bool valid_uuid(char *uuid);
 time_t convert_str_to_time(const char *time);
-int swmod_ee_uci_init(ExecEnv_t *env, char *uci_file, int len);
-int set_du_alias_to_config(const char *ee_name, const char *uuid,
-			   const char *alias, const char *bundle, const char *uci_file);
-int set_eu_alias_to_config(const char *ee_name, const char *eu_name,
-			   const char *alias, const char *bundle, const char *uci_file);
-int set_eu_autostart_to_config(const char *ee_name, const char *eu_name,
-				bool enable, const char *bundle, const char *uci_file);
+
+void remove_dir(const char *path);
+void swmod_reset_ee_runlevel(struct uci_section *sec);
+void swmod_update_du_eu_assoc(struct list_head *du_head);
+int swmod_du_type(char *du_path);
+void swmod_get_du_list(const char *base_path, const char *eu_runlevel, struct list_head *du_head);
+void swmod_free_du_list(struct list_head *du_head);
+int swmod_du_remove(struct uci_section *sec);
+void swmod_execenv_add(struct uci_section *sec);
+void swmod_execenv_remove(struct uci_section *sec, bool force);
+char *swmod_select_env(void);
+void swmod_perform_du_operation(struct ubus_context *ubus_ctx, PkgInfo *pkg, size_t size);
+int invalid_du_request(PkgInfo *pkg, char *fault);
+void swmod_send_event_du_state_change(PkgInfo *pkg, int err_code, char *msg, time_t start);
+void swmod_perform_du_install(PkgInfo *pkg, time_t start);
+int swmod_install_package(PkgInfo *pkg);
+int install_du_package(char *url, PkgInfo *pkg);
+int download_remote_du(PkgInfo *pkg);
 
 #define PRINT_DEBUG(fmt, args...) \
 	print_debug("[%s:%d]"fmt, __func__, __LINE__, ##args)