mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Redesign dmmap to be portable and structured
This commit is contained in:
parent
a4f6108138
commit
d4bc6eea94
11 changed files with 360 additions and 66 deletions
|
|
@ -351,7 +351,7 @@ static char *find_path_recursive(json_object *curr, char **parts, int index, int
|
||||||
return NULL;
|
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 file_path[256] = {0};
|
||||||
char *reference_path = NULL;
|
char *reference_path = NULL;
|
||||||
|
|
@ -379,11 +379,50 @@ char *bbfdm_resolve_external_reference(struct dmctx *ctx, const char *linker_pat
|
||||||
return reference_path;
|
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)
|
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 param_path[1024] = {0};
|
||||||
char *value = NULL;
|
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) {
|
if (DM_STRLEN(base_path) == 0) {
|
||||||
BBF_ERR("Reference base path should not be empty!!!");
|
BBF_ERR("Reference base path should not be empty!!!");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -399,16 +438,6 @@ int bbfdm_get_references(struct dmctx *ctx, int match_action, const char *base_p
|
||||||
return -1;
|
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);
|
snprintf(param_path, sizeof(param_path), "%s*.%s", base_path, key_name);
|
||||||
|
|
||||||
adm_entry_get_reference_param(ctx, param_path, key_value, &value);
|
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;
|
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 (external_reference != NULL) {
|
||||||
|
|
||||||
if (out_len - len < strlen(external_reference)) {
|
if (out_len - len < strlen(external_reference)) {
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,11 @@ struct dm_reference {
|
||||||
bool is_valid_path;
|
bool is_valid_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BBFDM_API_V0,
|
||||||
|
BBFDM_API_V1
|
||||||
|
};
|
||||||
|
|
||||||
struct dmctx {
|
struct dmctx {
|
||||||
bool stop;
|
bool stop;
|
||||||
bool match;
|
bool match;
|
||||||
|
|
@ -188,6 +193,7 @@ struct dmctx {
|
||||||
int faultcode;
|
int faultcode;
|
||||||
int setaction;
|
int setaction;
|
||||||
unsigned int dm_type;
|
unsigned int dm_type;
|
||||||
|
unsigned int bbfdm_api_version;
|
||||||
unsigned char inparam_isparam;
|
unsigned char inparam_isparam;
|
||||||
unsigned char findparam;
|
unsigned char findparam;
|
||||||
|
|
||||||
|
|
@ -207,7 +213,8 @@ struct dmctx {
|
||||||
struct ubus_context *ubus_ctx;
|
struct ubus_context *ubus_ctx;
|
||||||
struct list_head *memhead;
|
struct list_head *memhead;
|
||||||
|
|
||||||
char *inst_buf[16];
|
const char *obj_buf[16];
|
||||||
|
const char *inst_buf[16];
|
||||||
char fault_msg[256];
|
char fault_msg[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -215,6 +222,7 @@ typedef struct dmnode {
|
||||||
DMOBJ *obj;
|
DMOBJ *obj;
|
||||||
struct dmnode *parent;
|
struct dmnode *parent;
|
||||||
char *current_object;
|
char *current_object;
|
||||||
|
char *current_object_file;
|
||||||
void *prev_data;
|
void *prev_data;
|
||||||
char *prev_instance;
|
char *prev_instance;
|
||||||
unsigned char instance_level;
|
unsigned char instance_level;
|
||||||
|
|
|
||||||
|
|
@ -431,6 +431,7 @@ static void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *ent
|
||||||
node.matched = parent_node->matched;
|
node.matched = parent_node->matched;
|
||||||
node.prev_data = data;
|
node.prev_data = data;
|
||||||
node.prev_instance = instance;
|
node.prev_instance = instance;
|
||||||
|
node.current_object_file = parent_node->current_object_file;
|
||||||
|
|
||||||
if (!bbfdatamodel_matches(dmctx->dm_type, entryobj->bbfdm_type)) {
|
if (!bbfdatamodel_matches(dmctx->dm_type, entryobj->bbfdm_type)) {
|
||||||
*err = FAULT_9005;
|
*err = FAULT_9005;
|
||||||
|
|
@ -447,6 +448,10 @@ static void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *ent
|
||||||
else
|
else
|
||||||
dmasprintf(&(node.current_object), "%s%s.", parent_obj, entryobj->obj);
|
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) {
|
if (dmctx->checkobj) {
|
||||||
*err = dmctx->checkobj(dmctx, &node, entryobj->permission, entryobj->addobj, entryobj->delobj, entryobj->get_linker, data, instance);
|
*err = dmctx->checkobj(dmctx, &node, entryobj->permission, entryobj->addobj, entryobj->delobj, entryobj->get_linker, data, instance);
|
||||||
if (*err)
|
if (*err)
|
||||||
|
|
@ -526,7 +531,7 @@ int dm_link_inst_obj(struct dmctx *dmctx, DMNODE *parent_node, void *data, char
|
||||||
char *parent_obj;
|
char *parent_obj;
|
||||||
DMNODE node = {0};
|
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;
|
int curr_inst = (instance && *instance != '\0') ? DM_STRTOL(instance) : 0;
|
||||||
if (curr_inst > parent_node->max_instance)
|
if (curr_inst > parent_node->max_instance)
|
||||||
parent_node->max_instance = curr_inst;
|
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++;
|
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;
|
return 0;
|
||||||
|
|
||||||
DMOBJ *prevobj = parent_node->obj;
|
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.instance_level = parent_node->instance_level + 1;
|
||||||
node.is_instanceobj = 1;
|
node.is_instanceobj = 1;
|
||||||
node.matched = parent_node->matched;
|
node.matched = parent_node->matched;
|
||||||
|
node.current_object_file = parent_node->current_object_file;
|
||||||
|
|
||||||
parent_obj = parent_node->current_object;
|
parent_obj = parent_node->current_object;
|
||||||
if (instance == NULL)
|
if (instance == NULL)
|
||||||
|
|
@ -595,8 +601,53 @@ int get_number_of_entries(struct dmctx *ctx, void *data, char *instance, int (*b
|
||||||
{
|
{
|
||||||
DMNODE node = {0};
|
DMNODE node = {0};
|
||||||
|
|
||||||
node.browse_type = BROWSE_NUM_OF_ENTRIES;
|
if (browseinstobj == NULL) {
|
||||||
(browseinstobj)(ctx, &node, data, instance);
|
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;
|
return node.num_of_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -637,6 +688,100 @@ char *handle_instance(struct dmctx *dmctx, DMNODE *parent_node, struct uci_secti
|
||||||
return instance ? instance : "";
|
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 *handle_instance_without_section(struct dmctx *dmctx, DMNODE *parent_node, int inst_nbr)
|
||||||
{
|
{
|
||||||
char *instance = NULL;
|
char *instance = NULL;
|
||||||
|
|
@ -655,6 +800,42 @@ char *handle_instance_without_section(struct dmctx *dmctx, DMNODE *parent_node,
|
||||||
return instance ? instance : "";
|
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)
|
int get_empty(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
{
|
{
|
||||||
*value = dmstrdup("");
|
*value = dmstrdup("");
|
||||||
|
|
@ -901,10 +1082,12 @@ static int get_value_obj(DMOBJECT_ARGS)
|
||||||
|
|
||||||
static int get_value_param(DMPARAM_ARGS)
|
static int get_value_param(DMPARAM_ARGS)
|
||||||
{
|
{
|
||||||
char full_param[MAX_DM_PATH] = {0};
|
char *full_param = NULL;
|
||||||
char *value = dmstrdup("");
|
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);
|
(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)
|
static int mparam_get_value_in_param(DMPARAM_ARGS)
|
||||||
{
|
{
|
||||||
char full_param[MAX_DM_PATH] = {0};
|
char *full_param = NULL;
|
||||||
char *value = dmstrdup("");
|
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 (dmctx->iswildcard) {
|
||||||
if (dm_strcmp_wildcard(dmctx->in_param, full_param) != 0)
|
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;
|
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);
|
(leaf->getvalue)(full_param, dmctx, data, instance, &value);
|
||||||
|
|
||||||
if ((leaf->dm_flags & DM_FLAG_SECURE) && (dmctx->dm_type == BBFDM_CWMP)) {
|
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 *refparam = node->current_object;
|
||||||
char *perm = permission->val;
|
char *perm = permission->val;
|
||||||
char *new_instance = NULL;
|
char *new_instance = NULL;
|
||||||
|
char file_path[64] = {0};
|
||||||
int fault = 0;
|
int fault = 0;
|
||||||
|
|
||||||
if (DM_STRCMP(refparam, dmctx->in_param) != 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)
|
if (perm[0] == '0' || addobj == NULL)
|
||||||
return FAULT_9005;
|
return FAULT_9005;
|
||||||
|
|
||||||
int max_inst = find_max_instance(dmctx, node);
|
snprintf(file_path, sizeof(file_path), "/etc/bbfdm/dmmap/%s", node->current_object_file);
|
||||||
fault = dmasprintf(&new_instance, "%d", max_inst);
|
|
||||||
if (fault)
|
|
||||||
return fault;
|
|
||||||
|
|
||||||
dmctx->stop = 1;
|
if (file_exists(file_path)) {
|
||||||
|
struct dm_data curr_data = {0};
|
||||||
|
|
||||||
fault = (addobj)(refparam, dmctx, data, &new_instance);
|
curr_data.dmmap_section = create_dmmap_obj(dmctx, node->instance_level, node->current_object_file, node->obj->obj, NULL, &new_instance);
|
||||||
if (fault)
|
if (DM_STRLEN(new_instance) == 0 || curr_data.dmmap_section == NULL)
|
||||||
return fault;
|
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;
|
dmctx->addobj_instance = new_instance;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,17 @@
|
||||||
#include "dmmem.h"
|
#include "dmmem.h"
|
||||||
#include "dmapi.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(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);
|
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);
|
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);
|
void fill_blob_param(struct blob_buf *bb, const char *path, const char *data, const char *type, uint32_t dm_flags);
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,18 @@ void free_dmmap_config_dup_list(struct list_head *dup_list)
|
||||||
/*
|
/*
|
||||||
* Function allows to synchronize config section with dmmap config
|
* 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 *get_origin_section_from_config(const char *package, const char *section_type, const char *orig_section_name)
|
||||||
{
|
{
|
||||||
struct uci_section *s = NULL;
|
struct uci_section *s = NULL;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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 *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);
|
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_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_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);
|
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 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_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);
|
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, 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_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);
|
int bbfdm_get_reference_linker(struct dmctx *ctx, char *reference_path, struct dm_reference *reference_args);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
add_list_loaded_libraries(&loaded_library_list, handle);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -674,7 +674,7 @@ static char *handle_reference_value(struct dmctx *ctx, struct json_object *linke
|
||||||
if (DM_STRLEN(pref) != 0)
|
if (DM_STRLEN(pref) != 0)
|
||||||
return pref;
|
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 : "";
|
return pref ? pref : "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,13 +78,27 @@ static int operate_Device_FactoryReset(char *refparam, struct dmctx *ctx, void *
|
||||||
return !res ? 0 : USP_FAULT_COMMAND_FAILURE;
|
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
|
* OBJ & LEAF DEFINITION
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
/* *** BBFDM *** */
|
/* *** BBFDM *** */
|
||||||
DM_MAP_OBJ tDynamicObj[] = {
|
DM_MAP_OBJ tDynamicObj[] = {
|
||||||
/* parentobj, nextobject, parameter */
|
/* parentobj, nextobject, parameter */
|
||||||
{"Device.", tDMRootObj, tDMRootParams},
|
{"Device.", tDMRootObj, tDMRootParams, init_core_module, NULL},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
static int addSchedule(char *refparam, struct dmctx *ctx, void *data, char **instance)
|
||||||
{
|
{
|
||||||
struct uci_section *s = NULL, *dmmap_s = NULL;
|
struct dm_data *curr_data = (struct dm_data *)ctx->addobj_instance;
|
||||||
char s_name[16] = {0};
|
char sec_name[32] = {0};
|
||||||
int i;
|
|
||||||
|
|
||||||
snprintf(s_name, sizeof(s_name), "schedule_%s", *instance);
|
snprintf(sec_name, sizeof(sec_name), "schedule_%s", *instance);
|
||||||
|
|
||||||
dmuci_add_section("schedules", "schedule", &s);
|
// Create and Set default config option
|
||||||
dmuci_rename_section_by_section(s, s_name);
|
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");
|
dmuci_set_value_by_section(curr_data->config_section, "enable", "0");
|
||||||
|
dmuci_set_value_by_section(curr_data->config_section, "duration", "1");
|
||||||
for (i = 0; allowed_days[i] != NULL; i++) {
|
|
||||||
dmuci_add_list_value_by_section(s, "day", allowed_days[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,22 +170,22 @@ static int delSchedule(char *refparam, struct dmctx *ctx, void *data, char *inst
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* ENTRY METHODS
|
* 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;
|
struct uci_section *schedule_s = NULL;
|
||||||
char *inst = NULL;
|
char object_name[16] = {0};
|
||||||
LIST_HEAD(dup_list);
|
char *instance = NULL;
|
||||||
|
|
||||||
synchronize_specific_config_sections_with_dmmap("schedules", "schedule", "dmmap_schedules", &dup_list);
|
bbfdm_create_empty_file("/etc/bbfdm/dmmap/Schedules");
|
||||||
list_for_each_entry(p, &dup_list, list) {
|
|
||||||
|
|
||||||
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)
|
// Device.Schedules.Schedule.{i}.
|
||||||
break;
|
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)
|
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);
|
int cnt = get_number_of_entries(ctx, data, instance, NULL);
|
||||||
dmasprintf(value, "%u", cnt);
|
dmasprintf(value, "%d", cnt);
|
||||||
return 0;
|
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)
|
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)
|
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;
|
break;
|
||||||
case VALUESET:
|
case VALUESET:
|
||||||
dmuci_rename_section_by_section(((struct dm_data *)data)->config_section, value);
|
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, "__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, "Alias", value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -432,7 +429,7 @@ static int get_schedule_status(char *refparam, struct dmctx *ctx, void *data, ch
|
||||||
/* *** Device.Schedules. *** */
|
/* *** Device.Schedules. *** */
|
||||||
DMOBJ tSchedulesObj[] = {
|
DMOBJ tSchedulesObj[] = {
|
||||||
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
|
/* 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}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,8 @@
|
||||||
extern DMOBJ tSchedulesObj[];
|
extern DMOBJ tSchedulesObj[];
|
||||||
extern DMLEAF tSchedulesParams[];
|
extern DMLEAF tSchedulesParams[];
|
||||||
extern DMLEAF tScheduleParams[];
|
extern DMLEAF tScheduleParams[];
|
||||||
|
|
||||||
|
void dmmap_synchronizeSchedulesSchedule(struct dmctx *dmctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue