diff --git a/libbbfdm-api/legacy/dmapi.c b/libbbfdm-api/legacy/dmapi.c index ce971926..91837a2b 100644 --- a/libbbfdm-api/legacy/dmapi.c +++ b/libbbfdm-api/legacy/dmapi.c @@ -351,7 +351,7 @@ static char *find_path_recursive(json_object *curr, char **parts, int index, int return NULL; } -char *bbfdm_resolve_external_reference(struct dmctx *ctx, const char *linker_path, const char *linker_value) +char *bbfdm_resolve_external_reference_via_json(struct dmctx *ctx, const char *linker_path, const char *linker_value) { char file_path[256] = {0}; char *reference_path = NULL; @@ -379,11 +379,50 @@ char *bbfdm_resolve_external_reference(struct dmctx *ctx, const char *linker_pat return reference_path; } +static char *bbfdm_resolve_external_reference_via_dmmap(struct dmctx *ctx, const char *linker_path, const char *linker_name, const char *linker_value) +{ + struct uci_section *dmmap_obj = NULL; + size_t count = 0; + + if (DM_STRLEN(linker_path) == 0 || DM_STRLEN(linker_name) == 0 || DM_STRLEN(linker_value) == 0) + return NULL; + + char **parts = strsplit(linker_path, ".", &count); + if (count < 2) + return NULL; + + uci_path_foreach_sections(bbfdm, parts[1], parts[count - 1], dmmap_obj) { + char *curr_value = NULL; + + dmuci_get_value_by_section_string(dmmap_obj, linker_name, &curr_value); + if (DM_STRCMP(curr_value, linker_value) == 0) { + char *linker_instance = NULL; + char *reference_path = NULL; + + dmuci_get_value_by_section_string(dmmap_obj, "__instance__", &linker_instance); + dmasprintf(&reference_path, "%s%s", linker_path, linker_instance); + return reference_path; + } + } + + return NULL; +} + int bbfdm_get_references(struct dmctx *ctx, int match_action, const char *base_path, const char *key_name, char *key_value, char *out, size_t out_len) { char param_path[1024] = {0}; char *value = NULL; + if (!out || !out_len) { + BBF_ERR("Output buffer is NULL or has zero length. A valid buffer with sufficient size is required"); + return -1; + } + + size_t len = strlen(out); + + if (match_action == MATCH_FIRST && len > 0) // Reference path is already resolved + return 0; + if (DM_STRLEN(base_path) == 0) { BBF_ERR("Reference base path should not be empty!!!"); return -1; @@ -399,16 +438,6 @@ int bbfdm_get_references(struct dmctx *ctx, int match_action, const char *base_p return -1; } - if (!out || !out_len) { - BBF_ERR("Output buffer is NULL or has zero length. A valid buffer with sufficient size is required"); - return -1; - } - - size_t len = strlen(out); - - if (match_action == MATCH_FIRST && len > 0) // Reference path is already resolved - return 0; - snprintf(param_path, sizeof(param_path), "%s*.%s", base_path, key_name); adm_entry_get_reference_param(ctx, param_path, key_value, &value); @@ -424,7 +453,13 @@ int bbfdm_get_references(struct dmctx *ctx, int match_action, const char *base_p return 0; } - char *external_reference = bbfdm_resolve_external_reference(ctx, param_path, key_value); + char *external_reference = NULL; + + if (ctx->bbfdm_api_version == BBFDM_API_V1) + external_reference = bbfdm_resolve_external_reference_via_dmmap(ctx, base_path, key_name, key_value); + else + external_reference = bbfdm_resolve_external_reference_via_json(ctx, param_path, key_value); + if (external_reference != NULL) { if (out_len - len < strlen(external_reference)) { diff --git a/libbbfdm-api/legacy/dmapi.h b/libbbfdm-api/legacy/dmapi.h index de0cac01..f4a317d5 100644 --- a/libbbfdm-api/legacy/dmapi.h +++ b/libbbfdm-api/legacy/dmapi.h @@ -170,6 +170,11 @@ struct dm_reference { bool is_valid_path; }; +enum { + BBFDM_API_V0, + BBFDM_API_V1 +}; + struct dmctx { bool stop; bool match; @@ -188,6 +193,7 @@ struct dmctx { int faultcode; int setaction; unsigned int dm_type; + unsigned int bbfdm_api_version; unsigned char inparam_isparam; unsigned char findparam; @@ -207,7 +213,8 @@ struct dmctx { struct ubus_context *ubus_ctx; struct list_head *memhead; - char *inst_buf[16]; + const char *obj_buf[16]; + const char *inst_buf[16]; char fault_msg[256]; }; @@ -215,6 +222,7 @@ typedef struct dmnode { DMOBJ *obj; struct dmnode *parent; char *current_object; + char *current_object_file; void *prev_data; char *prev_instance; unsigned char instance_level; diff --git a/libbbfdm-api/legacy/dmbbf.c b/libbbfdm-api/legacy/dmbbf.c index 35875250..16c01d56 100644 --- a/libbbfdm-api/legacy/dmbbf.c +++ b/libbbfdm-api/legacy/dmbbf.c @@ -431,6 +431,7 @@ static void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *ent node.matched = parent_node->matched; node.prev_data = data; node.prev_instance = instance; + node.current_object_file = parent_node->current_object_file; if (!bbfdatamodel_matches(dmctx->dm_type, entryobj->bbfdm_type)) { *err = FAULT_9005; @@ -447,6 +448,10 @@ static void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *ent else dmasprintf(&(node.current_object), "%s%s.", parent_obj, entryobj->obj); + if (DM_STRCMP(parent_obj, ROOT_NODE) == 0) { + node.current_object_file = entryobj->obj; + } + if (dmctx->checkobj) { *err = dmctx->checkobj(dmctx, &node, entryobj->permission, entryobj->addobj, entryobj->delobj, entryobj->get_linker, data, instance); if (*err) @@ -526,7 +531,7 @@ int dm_link_inst_obj(struct dmctx *dmctx, DMNODE *parent_node, void *data, char char *parent_obj; DMNODE node = {0}; - if (parent_node->browse_type == BROWSE_FIND_MAX_INST) { + if (parent_node->browse_type == BROWSE_FIND_MAX_INST) { // To be removed later!!!!!!!!!!!! int curr_inst = (instance && *instance != '\0') ? DM_STRTOL(instance) : 0; if (curr_inst > parent_node->max_instance) parent_node->max_instance = curr_inst; @@ -534,7 +539,7 @@ int dm_link_inst_obj(struct dmctx *dmctx, DMNODE *parent_node, void *data, char } parent_node->num_of_entries++; - if (parent_node->browse_type == BROWSE_NUM_OF_ENTRIES) + if (parent_node->browse_type == BROWSE_NUM_OF_ENTRIES) // To be removed later!!!!!!!!!!!! return 0; DMOBJ *prevobj = parent_node->obj; @@ -546,6 +551,7 @@ int dm_link_inst_obj(struct dmctx *dmctx, DMNODE *parent_node, void *data, char node.instance_level = parent_node->instance_level + 1; node.is_instanceobj = 1; node.matched = parent_node->matched; + node.current_object_file = parent_node->current_object_file; parent_obj = parent_node->current_object; if (instance == NULL) @@ -595,8 +601,53 @@ int get_number_of_entries(struct dmctx *ctx, void *data, char *instance, int (*b { DMNODE node = {0}; - node.browse_type = BROWSE_NUM_OF_ENTRIES; - (browseinstobj)(ctx, &node, data, instance); + if (browseinstobj == NULL) { + int instance_level = 0; + size_t count = 0; + + if (!ctx->addobj_instance) + return 0; + + char **parts = strsplit(ctx->addobj_instance, ".", &count); + if (count < 2) + return -1; + + for (int idx = 0; idx < count - 1; idx++) { + + int i = 0; + bool is_instance = false; + while (parts[idx][i] != 0) { + if (isdigit(parts[idx][i]) != 0) { + is_instance = true; + break; + } + i++; + } + + if (is_instance) instance_level++; + } + + char *p = DM_STRSTR(parts[count - 1], "NumberOfEntries"); + if (p) *p = 0; + + node.obj = dmcalloc(1, sizeof(struct dm_obj_s)); + if (node.obj == NULL) { + BBF_ERR("Failed to allocate memory"); + return 0; + } + + node.current_object_file = parts[1]; + node.obj->obj = parts[count - 1]; + node.instance_level = instance_level; + + node.browse_type = BROWSE_NUM_OF_ENTRIES; + generic_browse(ctx,&node, data, instance); + } else { + node.browse_type = BROWSE_NUM_OF_ENTRIES; + (browseinstobj)(ctx, &node, data, instance); + } + + node.browse_type = BROWSE_NORMAL; return node.num_of_entries; } @@ -637,6 +688,100 @@ char *handle_instance(struct dmctx *dmctx, DMNODE *parent_node, struct uci_secti return instance ? instance : ""; } +struct uci_section *create_dmmap_obj(struct dmctx *dmctx, unsigned char instance_level, + const char *obj_file, const char *obj_name, struct uci_section *config_sec, + char **instance) +{ + struct uci_section *s = NULL, *dmmap_section = NULL; + char config_sec_name[128] = {0}; + int max_instance = 0; + + if (!dmctx || !obj_file || !obj_name || !instance) + return NULL; + + if (config_sec != NULL) { + snprintf(config_sec_name, sizeof(config_sec_name), "%s.%s", section_config(config_sec), section_name(config_sec)); + } + + uci_path_foreach_sections(bbfdm, obj_file, obj_name, s) { + bool is_same_parent = true; + + for (int i = 0; i < instance_level; i++) { + char *curr_obj_inst = NULL; + dmuci_get_value_by_section_string(s, dmctx->obj_buf[i], &curr_obj_inst); + if (DM_STRCMP(curr_obj_inst, dmctx->inst_buf[i]) != 0) { + is_same_parent = false; + break; + } + } + + if (is_same_parent == false) + continue; + + char *curr_instance = NULL; + dmuci_get_value_by_section_string(s, "__instance__", &curr_instance); + int curr_instance_int = (curr_instance && *curr_instance != '\0') ? DM_STRTOL(curr_instance) : 0; + if (curr_instance_int > max_instance) + max_instance = curr_instance_int; + + if (config_sec != NULL) { + char *curr_sec_name = NULL; + dmuci_get_value_by_section_string(s, "__section_name__", &curr_sec_name); + if (DM_STRCMP(curr_sec_name, config_sec_name) == 0) { + dmctx->obj_buf[instance_level] = obj_name; + dmctx->inst_buf[instance_level] = curr_instance; + *instance = curr_instance; + return dmmap_section; + } + } + } + + dmasprintf(instance, "%d", max_instance + 1); + + if (dmmap_section == NULL) { + // Section not found -> create it + char s_name[64] = {0}; + int pos = 0; + + dmuci_add_section_bbfdm(obj_file, obj_name, &dmmap_section); + + for (int i = 0; i < instance_level; i++) { + dmuci_set_value_by_section(dmmap_section, dmctx->obj_buf[i], dmctx->inst_buf[i]); + pos += snprintf(&s_name[pos], sizeof(s_name) - pos, "%s_%s", dmctx->obj_buf[i], dmctx->inst_buf[i]); + } + + snprintf(&s_name[pos], sizeof(s_name) - pos, "%s_%s", obj_name, *instance); + + dmuci_rename_section_by_section(dmmap_section, s_name); + + dmuci_set_value_by_section(dmmap_section, "__section_name__", config_sec_name); + dmuci_set_value_by_section(dmmap_section, "__instance__", *instance); + } + + dmctx->obj_buf[instance_level] = obj_name; + dmctx->inst_buf[instance_level] = *instance; + + return dmmap_section; +} + +char *uci_handle_instance(struct dmctx *dmctx, DMNODE *parent_node, struct dm_data *data) +{ + char *instance = NULL; + + switch(parent_node->browse_type) { + case BROWSE_NORMAL: // To be removed later!!!!!!!!!!!! + dmuci_get_value_by_section_string(data->dmmap_section, "__instance__", &instance); + dmctx->obj_buf[parent_node->instance_level] = parent_node->obj->obj; + dmctx->inst_buf[parent_node->instance_level] = instance ? instance : ""; + break; + case BROWSE_FIND_MAX_INST: // To be removed later!!!!!!!!!!!! + case BROWSE_NUM_OF_ENTRIES: // To be removed later!!!!!!!!!!!! + break; + } + + return instance ? instance : ""; +} + char *handle_instance_without_section(struct dmctx *dmctx, DMNODE *parent_node, int inst_nbr) { char *instance = NULL; @@ -655,6 +800,42 @@ char *handle_instance_without_section(struct dmctx *dmctx, DMNODE *parent_node, return instance ? instance : ""; } +int generic_browse(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + struct dm_data curr_data = {0}; + char *instance = NULL; + + // This check is added to prevent crashes if the object is updated to new design but forgot to update its NumberOfEntries parameter maps to it + if (parent_node->obj == NULL) + return 0; + + uci_path_foreach_sections(bbfdm, parent_node->current_object_file, parent_node->obj->obj, curr_data.dmmap_section) { + char *config_sec_name = NULL; + bool is_same_parent = true; + + for (int i = 0; i < parent_node->instance_level; i++) { + char *curr_obj_inst = NULL; + dmuci_get_value_by_section_string(curr_data.dmmap_section, dmctx->obj_buf[i], &curr_obj_inst); + if (DM_STRCMP(curr_obj_inst, dmctx->inst_buf[i]) != 0) { + is_same_parent = false; + break; + } + } + + if (is_same_parent == false) + continue; + + dmuci_get_value_by_section_string(curr_data.dmmap_section, "__section_name__", &config_sec_name); + curr_data.config_section = get_config_section_from_dmmap_section_name(config_sec_name); + + instance = uci_handle_instance(dmctx, parent_node, &curr_data); + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_data, instance) == DM_STOP) + break; + } + + return 0; +} + int get_empty(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { *value = dmstrdup(""); @@ -901,10 +1082,12 @@ static int get_value_obj(DMOBJECT_ARGS) static int get_value_param(DMPARAM_ARGS) { - char full_param[MAX_DM_PATH] = {0}; + char *full_param = NULL; char *value = dmstrdup(""); - snprintf(full_param, sizeof(full_param), "%s%s", node->current_object, leaf->parameter); + dmasprintf(&full_param, "%s%s", node->current_object, leaf->parameter); + + dmctx->addobj_instance = full_param; // This assignment is needed to pass the refparam in order to calculate the NumberOfEntries param (leaf->getvalue)(full_param, dmctx, data, instance, &value); @@ -926,10 +1109,10 @@ static int mobj_get_value_in_param(DMOBJECT_ARGS) } static int mparam_get_value_in_param(DMPARAM_ARGS) { - char full_param[MAX_DM_PATH] = {0}; + char *full_param = NULL; char *value = dmstrdup(""); - snprintf(full_param, sizeof(full_param), "%s%s", node->current_object, leaf->parameter); + dmasprintf(&full_param, "%s%s", node->current_object, leaf->parameter); if (dmctx->iswildcard) { if (dm_strcmp_wildcard(dmctx->in_param, full_param) != 0) @@ -939,6 +1122,8 @@ static int mparam_get_value_in_param(DMPARAM_ARGS) return FAULT_9005; } + dmctx->addobj_instance = full_param; // This assignment is needed to pass the refparam in order to calculate the NumberOfEntries param + (leaf->getvalue)(full_param, dmctx, data, instance, &value); if ((leaf->dm_flags & DM_FLAG_SECURE) && (dmctx->dm_type == BBFDM_CWMP)) { @@ -1351,6 +1536,7 @@ static int mobj_add_object(DMOBJECT_ARGS) char *refparam = node->current_object; char *perm = permission->val; char *new_instance = NULL; + char file_path[64] = {0}; int fault = 0; if (DM_STRCMP(refparam, dmctx->in_param) != 0) @@ -1365,16 +1551,43 @@ static int mobj_add_object(DMOBJECT_ARGS) if (perm[0] == '0' || addobj == NULL) return FAULT_9005; - int max_inst = find_max_instance(dmctx, node); - fault = dmasprintf(&new_instance, "%d", max_inst); - if (fault) - return fault; + snprintf(file_path, sizeof(file_path), "/etc/bbfdm/dmmap/%s", node->current_object_file); - dmctx->stop = 1; + if (file_exists(file_path)) { + struct dm_data curr_data = {0}; - fault = (addobj)(refparam, dmctx, data, &new_instance); - if (fault) - return fault; + curr_data.dmmap_section = create_dmmap_obj(dmctx, node->instance_level, node->current_object_file, node->obj->obj, NULL, &new_instance); + if (DM_STRLEN(new_instance) == 0 || curr_data.dmmap_section == NULL) + return FAULT_9005; + + dmctx->stop = 1; + + // cppcheck-suppress autoVariables + dmctx->addobj_instance = (char *)&curr_data; + + fault = (addobj)(refparam, dmctx, data, &new_instance); + if (fault) + return fault; + + if (curr_data.config_section != NULL) { + char sec_name[128] = {0}; + + snprintf(sec_name, sizeof(sec_name), "%s.%s", section_config(curr_data.config_section), section_name(curr_data.config_section)); + dmuci_set_value_by_section(curr_data.dmmap_section, "__section_name__", sec_name); + } + } else { + int max_inst = find_max_instance(dmctx, node); + fault = dmasprintf(&new_instance, "%d", max_inst); + if (fault) + return fault; + + dmctx->stop = 1; + + fault = (addobj)(refparam, dmctx, data, &new_instance); + if (fault) + return fault; + + } dmctx->addobj_instance = new_instance; return 0; diff --git a/libbbfdm-api/legacy/dmbbf.h b/libbbfdm-api/legacy/dmbbf.h index 1f1e3824..e18ed115 100644 --- a/libbbfdm-api/legacy/dmbbf.h +++ b/libbbfdm-api/legacy/dmbbf.h @@ -27,9 +27,17 @@ #include "dmmem.h" #include "dmapi.h" -int get_number_of_entries(struct dmctx *ctx, void *data, char *instance, int (*browseinstobj)(struct dmctx *ctx, struct dmnode *node, void *data, char *instance)); +int get_number_of_entries(struct dmctx *ctx, void *data, char *instance, int (*browseinstobj)(struct dmctx *ctx, struct dmnode *node, void *data, char *instance)); // To be removed later!!!!!!!!!!!! + char *handle_instance(struct dmctx *dmctx, DMNODE *parent_node, struct uci_section *s, const char *inst_opt, const char *alias_opt); char *handle_instance_without_section(struct dmctx *dmctx, DMNODE *parent_node, int inst_nbr); + +struct uci_section *create_dmmap_obj(struct dmctx *dmctx, unsigned char instance_level, + const char *obj_file, const char *obj_name, struct uci_section *config_sec, + char **instance); +int generic_browse(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance); +char *uci_handle_instance(struct dmctx *dmctx, DMNODE *parent_node, struct dm_data *data); + int get_empty(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value); void fill_blob_param(struct blob_buf *bb, const char *path, const char *data, const char *type, uint32_t dm_flags); diff --git a/libbbfdm-api/legacy/dmcommon.c b/libbbfdm-api/legacy/dmcommon.c index 6c239088..ff1bd07b 100644 --- a/libbbfdm-api/legacy/dmcommon.c +++ b/libbbfdm-api/legacy/dmcommon.c @@ -314,6 +314,18 @@ void free_dmmap_config_dup_list(struct list_head *dup_list) /* * Function allows to synchronize config section with dmmap config */ + +struct uci_section *get_config_section_from_dmmap_section_name(const char *config_sec_name) +{ + if (DM_STRLEN(config_sec_name) == 0) + return NULL; + + char *p = strchr(config_sec_name, '.'); + if (p) *p = 0; + + return dmuci_get_section(config_sec_name, p ? p + 1 : ""); +} + struct uci_section *get_origin_section_from_config(const char *package, const char *section_type, const char *orig_section_name) { struct uci_section *s = NULL; diff --git a/libbbfdm-api/legacy/dmcommon.h b/libbbfdm-api/legacy/dmcommon.h index 502bf82e..a3ae02b3 100644 --- a/libbbfdm-api/legacy/dmcommon.h +++ b/libbbfdm-api/legacy/dmcommon.h @@ -173,6 +173,7 @@ bool value_exists_in_uci_list(struct uci_list *list, const char *value); bool value_exits_in_str_list(const char *str_list, const char *delimitor, const char *str); char *add_str_to_str_list(const char *str_list, const char *delimitor, const char *str); char *remove_str_from_str_list(const char *str_list, const char *delimitor, const char *str); +struct uci_section *get_config_section_from_dmmap_section_name(const char *config_sec_name); struct uci_section *get_origin_section_from_config(const char *package, const char *section_type, const char *orig_section_name); struct uci_section *get_origin_section_from_dmmap(const char *package, const char *section_type, const char *orig_section_name); struct uci_section *get_dup_section_in_dmmap(const char *dmmap_package, const char *section_type, const char *orig_section_name); @@ -212,7 +213,7 @@ int bbfdm_validate_string_list(struct dmctx *ctx, const char *value, int min_ite int bbfdm_validate_hexBinary_list(struct dmctx *ctx, const char *value, int min_item, int max_item, int max_size, struct range_args r_args[], int r_args_size); int bbf_get_alias(struct dmctx *ctx, struct uci_section *s, const char *option_name, const char *instance, char **value); int bbf_set_alias(struct dmctx *ctx, struct uci_section *s, const char *option_name, const char *instance, const char *value); -char *bbfdm_resolve_external_reference(struct dmctx *ctx, const char *linker_path, const char *linker_value); +char *bbfdm_resolve_external_reference_via_json(struct dmctx *ctx, const char *linker_path, const char *linker_value); int bbfdm_get_references(struct dmctx *ctx, int match_action, const char *base_path, const char *key_name, char *key_value, char *out, size_t out_len); int _bbfdm_get_references(struct dmctx *ctx, const char *base_path, const char *key_name, char *key_value, char **value); int bbfdm_get_reference_linker(struct dmctx *ctx, char *reference_path, struct dm_reference *reference_args); diff --git a/libbbfdm-api/legacy/plugin/dotso_plugin.c b/libbbfdm-api/legacy/plugin/dotso_plugin.c index d8afb968..efed5582 100644 --- a/libbbfdm-api/legacy/plugin/dotso_plugin.c +++ b/libbbfdm-api/legacy/plugin/dotso_plugin.c @@ -128,6 +128,9 @@ int load_dotso_plugins(DMOBJ *entryobj, const char *plugin_path) } } + + if (dynamic_obj[i].init_module) + dynamic_obj[i].init_module(NULL); } add_list_loaded_libraries(&loaded_library_list, handle); diff --git a/libbbfdm-api/legacy/plugin/json_plugin.c b/libbbfdm-api/legacy/plugin/json_plugin.c index a58fbfe2..2a4027cd 100644 --- a/libbbfdm-api/legacy/plugin/json_plugin.c +++ b/libbbfdm-api/legacy/plugin/json_plugin.c @@ -674,7 +674,7 @@ static char *handle_reference_value(struct dmctx *ctx, struct json_object *linke if (DM_STRLEN(pref) != 0) return pref; - pref = bbfdm_resolve_external_reference(ctx, linker_path, key_value); + pref = bbfdm_resolve_external_reference_via_json(ctx, linker_path, key_value); return pref ? pref : ""; } diff --git a/libbbfdm/device.c b/libbbfdm/device.c index fcac4b64..d601bc85 100644 --- a/libbbfdm/device.c +++ b/libbbfdm/device.c @@ -78,13 +78,27 @@ static int operate_Device_FactoryReset(char *refparam, struct dmctx *ctx, void * return !res ? 0 : USP_FAULT_COMMAND_FAILURE; } +/************************************************************* +* Init & Clean Module +**************************************************************/ +int init_core_module(void *data) +{ + struct dmctx bbf_ctx = {0}; + + bbf_ctx_init(&bbf_ctx, NULL); + dmmap_synchronizeSchedulesSchedule(&bbf_ctx); + bbf_ctx_clean(&bbf_ctx); + + return 0; +} + /********************************************************************************************************************************** * OBJ & LEAF DEFINITION ***********************************************************************************************************************************/ /* *** BBFDM *** */ DM_MAP_OBJ tDynamicObj[] = { /* parentobj, nextobject, parameter */ -{"Device.", tDMRootObj, tDMRootParams}, +{"Device.", tDMRootObj, tDMRootParams, init_core_module, NULL}, {0} }; diff --git a/libbbfdm/schedules.c b/libbbfdm/schedules.c index 933f2f3c..b7ad666f 100644 --- a/libbbfdm/schedules.c +++ b/libbbfdm/schedules.c @@ -138,27 +138,24 @@ static char *get_status(char *start, char *period, char *day) **************************************************************/ static int addSchedule(char *refparam, struct dmctx *ctx, void *data, char **instance) { - struct uci_section *s = NULL, *dmmap_s = NULL; - char s_name[16] = {0}; - int i; + struct dm_data *curr_data = (struct dm_data *)ctx->addobj_instance; + char sec_name[32] = {0}; - snprintf(s_name, sizeof(s_name), "schedule_%s", *instance); + snprintf(sec_name, sizeof(sec_name), "schedule_%s", *instance); - dmuci_add_section("schedules", "schedule", &s); - dmuci_rename_section_by_section(s, s_name); + // Create and Set default config option + dmuci_add_section("schedules", "schedule", &curr_data->config_section); + dmuci_rename_section_by_section(curr_data->config_section, sec_name); - dmuci_set_value_by_section(s, "enable", "0"); - - for (i = 0; allowed_days[i] != NULL; i++) { - dmuci_add_list_value_by_section(s, "day", allowed_days[i]); - } + dmuci_set_value_by_section(curr_data->config_section, "enable", "0"); + dmuci_set_value_by_section(curr_data->config_section, "duration", "1"); - dmuci_set_value_by_section(s, "duration", "1"); + for (int i = 0; allowed_days[i] != NULL; i++) + dmuci_add_list_value_by_section(curr_data->config_section, "day", allowed_days[i]); + + // dmmap is already created by the core, Set default dmmap option if needed + dmuci_set_value_by_section(curr_data->dmmap_section, "Alias", sec_name); - dmuci_add_section_bbfdm("dmmap_schedules", "schedule", &dmmap_s); - dmuci_set_value_by_section(dmmap_s, "section_name", s_name); - dmuci_set_value_by_section(dmmap_s, "schedule_instance", *instance); - dmuci_set_value_by_section(dmmap_s, "schedule_alias", s_name); return 0; } @@ -173,22 +170,22 @@ static int delSchedule(char *refparam, struct dmctx *ctx, void *data, char *inst /************************************************************* * ENTRY METHODS *************************************************************/ -static int browseScheduleInstance(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +void dmmap_synchronizeSchedulesSchedule(struct dmctx *dmctx) { - struct dm_data *p = NULL; - char *inst = NULL; - LIST_HEAD(dup_list); + struct uci_section *schedule_s = NULL; + char object_name[16] = {0}; + char *instance = NULL; - synchronize_specific_config_sections_with_dmmap("schedules", "schedule", "dmmap_schedules", &dup_list); - list_for_each_entry(p, &dup_list, list) { + bbfdm_create_empty_file("/etc/bbfdm/dmmap/Schedules"); - inst = handle_instance(dmctx, parent_node, p->dmmap_section, "schedule_instance", "schedule_alias"); + snprintf(object_name, sizeof(object_name), "%s", "Schedules"); - if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p, inst) == DM_STOP) - break; + // Device.Schedules.Schedule.{i}. + uci_foreach_sections("schedules", "schedule", schedule_s) { + create_dmmap_obj(dmctx, 0, "Schedules", "Schedule", schedule_s, &instance); } - free_dmmap_config_dup_list(&dup_list); - return 0; + + dmuci_commit_package_bbfdm(object_name); } /************************************************************* @@ -221,8 +218,8 @@ static int set_schedules_enable(char *refparam, struct dmctx *ctx, void *data, c static int get_schedule_number(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - unsigned int cnt = get_number_of_entries(ctx, data, instance, browseScheduleInstance); - dmasprintf(value, "%u", cnt); + int cnt = get_number_of_entries(ctx, data, instance, NULL); + dmasprintf(value, "%d", cnt); return 0; } @@ -253,7 +250,7 @@ static int set_schedule_enable(char *refparam, struct dmctx *ctx, void *data, ch static int get_schedule_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - return bbf_get_alias(ctx, ((struct dm_data *)data)->dmmap_section, "schedule_alias", instance, value); + return bbf_get_alias(ctx, ((struct dm_data *)data)->dmmap_section, "Alias", instance, value); } static int set_schedule_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) @@ -281,8 +278,8 @@ static int set_schedule_alias(char *refparam, struct dmctx *ctx, void *data, cha break; case VALUESET: dmuci_rename_section_by_section(((struct dm_data *)data)->config_section, value); - dmuci_set_value_by_section(((struct dm_data *)data)->dmmap_section, "section_name", value); - dmuci_set_value_by_section(((struct dm_data *)data)->dmmap_section, "schedule_alias", value); + dmuci_set_value_by_section(((struct dm_data *)data)->dmmap_section, "__section_name__", value); + dmuci_set_value_by_section(((struct dm_data *)data)->dmmap_section, "Alias", value); break; } @@ -432,7 +429,7 @@ static int get_schedule_status(char *refparam, struct dmctx *ctx, void *data, ch /* *** Device.Schedules. *** */ DMOBJ tSchedulesObj[] = { /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/ -{"Schedule", &DMWRITE, addSchedule, delSchedule, NULL, browseScheduleInstance, NULL, NULL, NULL, tScheduleParams, NULL, BBFDM_BOTH, NULL}, +{"Schedule", &DMWRITE, addSchedule, delSchedule, NULL, generic_browse, NULL, NULL, NULL, tScheduleParams, NULL, BBFDM_BOTH, NULL}, {0} }; diff --git a/libbbfdm/schedules.h b/libbbfdm/schedules.h index fb429137..26a701a8 100644 --- a/libbbfdm/schedules.h +++ b/libbbfdm/schedules.h @@ -16,5 +16,8 @@ extern DMOBJ tSchedulesObj[]; extern DMLEAF tSchedulesParams[]; extern DMLEAF tScheduleParams[]; + +void dmmap_synchronizeSchedulesSchedule(struct dmctx *dmctx); + #endif