mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Feature #15266: Add support to assign list of references using JSON plugins
This commit is contained in:
parent
0a33d96b69
commit
47537bb4ab
2 changed files with 179 additions and 85 deletions
|
|
@ -44,8 +44,6 @@ struct dm_json_obj {
|
|||
event_args event_arg;
|
||||
};
|
||||
|
||||
static int handle_linker_json_object(struct json_object *linker_jobj, struct dmctx *ctx, char *in, char **out);
|
||||
|
||||
static void save_json_data(struct list_head *json_list, char *name, json_object *data, int json_version,
|
||||
const char **in_p, const char **out_p, const char **ev_arg)
|
||||
{
|
||||
|
|
@ -656,6 +654,58 @@ static int delete_obj(char *refparam, struct dmctx *ctx, void *data, char *insta
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *handle_reference_value(struct dmctx *ctx, struct json_object *linker_jobj, const char *key_name, char *key_value)
|
||||
{
|
||||
if (!ctx || !linker_jobj || !key_name || !key_value)
|
||||
return "";
|
||||
|
||||
char linker_path[256] = {0};
|
||||
|
||||
char *linker_val = json_object_get_string(linker_jobj);
|
||||
if (!linker_val)
|
||||
return "";
|
||||
|
||||
replace_str(linker_val, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, linker_path, sizeof(linker_path));
|
||||
if (DM_STRLEN(linker_path) == 0)
|
||||
return "";
|
||||
|
||||
char *ext_ref = strstr(linker_path, "==");
|
||||
if (ext_ref == NULL) {
|
||||
char *pref = NULL;
|
||||
|
||||
adm_entry_get_reference_param(ctx, linker_path, key_value, &pref);
|
||||
return pref;
|
||||
} else {
|
||||
char buf_ref[256 + 32] = {0};
|
||||
|
||||
replace_str(linker_path, key_name, key_value, buf_ref, sizeof(buf_ref));
|
||||
return dmstrdup(buf_ref);
|
||||
}
|
||||
}
|
||||
|
||||
static char *handle_reference_list_value(struct dmctx *ctx, struct json_object *linker_jobj, struct uci_list *list)
|
||||
{
|
||||
if (!ctx || !linker_jobj || !list)
|
||||
return "";
|
||||
|
||||
struct uci_element *e = NULL;
|
||||
char list_ref[4096] = {0};
|
||||
unsigned pos = 0;
|
||||
|
||||
list_ref[0] = 0;
|
||||
uci_foreach_element(list, e) {
|
||||
char *ref = handle_reference_value(ctx, linker_jobj, "@list", e->name);
|
||||
|
||||
if (DM_STRLEN(ref))
|
||||
pos += snprintf(&list_ref[pos], sizeof(list_ref) - pos, "%s;", ref);
|
||||
}
|
||||
|
||||
if (pos)
|
||||
list_ref[pos - 1] = 0;
|
||||
|
||||
return dmstrdup(list_ref);
|
||||
}
|
||||
|
||||
static char *uci_get_value(json_object *mapping_obj, int json_version, char *refparam, struct dmctx *ctx, void *data, char *instance)
|
||||
{
|
||||
struct json_object *obj = NULL;
|
||||
|
|
@ -733,7 +783,7 @@ static char *uci_get_value(json_object *mapping_obj, int json_version, char *ref
|
|||
dmuci_get_option_value_string(json_object_get_string(file), uci_type, opt_temp, &res);
|
||||
|
||||
if (linker_jobj)
|
||||
handle_linker_json_object(linker_jobj, ctx, res, &value);
|
||||
value = handle_reference_value(ctx, linker_jobj, "@key", res);
|
||||
else
|
||||
value = res;
|
||||
} else {
|
||||
|
|
@ -742,25 +792,37 @@ static char *uci_get_value(json_object *mapping_obj, int json_version, char *ref
|
|||
dmuci_get_value_by_section_list(((struct dm_data *)data)->config_section, opt_temp, &list_val);
|
||||
if (list_val == NULL)
|
||||
dmuci_get_option_value_list(json_object_get_string(file), uci_type, opt_temp, &list_val);
|
||||
|
||||
if (linker_jobj) {
|
||||
value = handle_reference_list_value(ctx, linker_jobj, list_val);
|
||||
} else {
|
||||
value = dmuci_list_to_string(list_val, ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (file && section_name && opt_temp) {
|
||||
if (option) {
|
||||
char *res = NULL;
|
||||
|
||||
dmuci_get_option_value_string(json_object_get_string(file), json_object_get_string(section_name), opt_temp, &res);
|
||||
|
||||
if (linker_jobj)
|
||||
handle_linker_json_object(linker_jobj, ctx, res, &value);
|
||||
else
|
||||
if (linker_jobj) {
|
||||
value = handle_reference_value(ctx, linker_jobj, "@key", res);
|
||||
} else {
|
||||
value = res;
|
||||
}
|
||||
} else {
|
||||
struct uci_list *list_val;
|
||||
|
||||
dmuci_get_option_value_list(json_object_get_string(file), json_object_get_string(section_name), opt_temp, &list_val);
|
||||
|
||||
if (linker_jobj) {
|
||||
value = handle_reference_list_value(ctx, linker_jobj, list_val);
|
||||
} else {
|
||||
value = dmuci_list_to_string(list_val, ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
FREE(linker);
|
||||
|
|
@ -842,24 +904,6 @@ static char *ubus_get_value(json_object *mapping_obj, int json_version, char *re
|
|||
return value ? value : "";
|
||||
}
|
||||
|
||||
static int handle_linker_json_object(struct json_object *linker_jobj, struct dmctx *ctx, char *in, char **out)
|
||||
{
|
||||
char *link = json_object_get_string(linker_jobj);
|
||||
char linker[256] = {0}, ref[256] = {0};
|
||||
char *external_ref = NULL;
|
||||
|
||||
replace_str(link, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, linker, sizeof(linker));
|
||||
external_ref = strstr(link, "==");
|
||||
if (external_ref == NULL) {
|
||||
adm_entry_get_reference_param(ctx, linker, in, out);
|
||||
} else {
|
||||
replace_str(linker, "@key", in, ref, sizeof(ref));
|
||||
*out = dmstrdup(ref);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *uci_v1_get_value(json_object *mapping_obj, char *refparam, struct dmctx *ctx, void *data, char *instance, bool is_dmmap)
|
||||
{
|
||||
struct json_object *data_s = NULL;
|
||||
|
|
@ -883,7 +927,13 @@ static char *uci_v1_get_value(json_object *mapping_obj, char *refparam, struct d
|
|||
struct uci_list *list_val;
|
||||
|
||||
dmuci_get_value_by_section_list(req_sec, list_value, &list_val);
|
||||
|
||||
if (linker_jobj) {
|
||||
value = handle_reference_list_value(ctx, linker_jobj, list_val);
|
||||
} else {
|
||||
value = dmuci_list_to_string(list_val, ",");
|
||||
}
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -897,7 +947,7 @@ static char *uci_v1_get_value(json_object *mapping_obj, char *refparam, struct d
|
|||
|
||||
dmuci_get_value_by_section_string(req_sec, key_value, &res);
|
||||
if (linker_jobj) {
|
||||
handle_linker_json_object(linker_jobj, ctx, res, &value);
|
||||
value = handle_reference_value(ctx, linker_jobj, "@key", res);
|
||||
} else {
|
||||
value = res;
|
||||
}
|
||||
|
|
@ -928,7 +978,7 @@ static char *ubus_v1_get_value(json_object *mapping_obj, char *refparam, struct
|
|||
json_object *json_obj = get_requested_json_obj(((struct dm_data *)data)->json_object, instance, json_object_get_string(key), key_name, sizeof(key_name));
|
||||
res = dmjson_get_value(json_obj, 1, key_name);
|
||||
if (linker_jobj) {
|
||||
handle_linker_json_object(linker_jobj, ctx, res, &value);
|
||||
value = handle_reference_value(ctx, linker_jobj, "@key", res);
|
||||
} else {
|
||||
value = res;
|
||||
}
|
||||
|
|
@ -1372,6 +1422,9 @@ static int uci_set_value(json_object *mapping_obj, int json_version, char *refpa
|
|||
struct json_object *option_name = NULL;
|
||||
struct json_object *list = NULL;
|
||||
struct json_object *list_name = NULL;
|
||||
struct json_object *linker_jobj = NULL;
|
||||
char *opt_temp = NULL;
|
||||
char buf_value[1024] = {0};
|
||||
int res = 0;
|
||||
|
||||
json_object_object_get_ex(mapping_obj, "uci", &uci_obj);
|
||||
|
|
@ -1383,16 +1436,21 @@ static int uci_set_value(json_object *mapping_obj, int json_version, char *refpa
|
|||
json_object_object_get_ex(option, "name", &option_name);
|
||||
json_object_object_get_ex(uci_obj, "list", &list);
|
||||
json_object_object_get_ex(list, "name", &list_name);
|
||||
json_object_object_get_ex(mapping_obj, "linker_obj", &linker_jobj);
|
||||
|
||||
char *opt_temp = NULL;
|
||||
if (list_name) {
|
||||
opt_temp = json_object_get_string(list_name);
|
||||
} else if (option_name) {
|
||||
opt_temp = json_object_get_string(option_name);
|
||||
}
|
||||
|
||||
if (value == NULL)
|
||||
return -1;
|
||||
|
||||
snprintf(buf_value, sizeof(buf_value), "%s", value);
|
||||
|
||||
if (opt_temp && strstr(refparam, ".Alias")) {
|
||||
return bbf_set_alias(ctx, ((struct dm_data *)data)->dmmap_section, opt_temp, instance, value);
|
||||
return bbf_set_alias(ctx, ((struct dm_data *)data)->dmmap_section, opt_temp, instance, buf_value);
|
||||
}
|
||||
|
||||
if (data && file && type && opt_temp) {
|
||||
|
|
@ -1406,7 +1464,7 @@ static int uci_set_value(json_object *mapping_obj, int json_version, char *refpa
|
|||
char sec_name[256] = {0};
|
||||
char buf[64] = {0};
|
||||
|
||||
if (dmuci_set_section_name(value, sec_name, sizeof(sec_name)))
|
||||
if (dmuci_set_section_name(buf_value, sec_name, sizeof(sec_name)))
|
||||
return -1;
|
||||
|
||||
snprintf(buf, sizeof(buf), "dmmap_%s", json_object_get_string(file));
|
||||
|
|
@ -1424,50 +1482,73 @@ static int uci_set_value(json_object *mapping_obj, int json_version, char *refpa
|
|||
}
|
||||
|
||||
if (option) {
|
||||
if ((res = dmuci_set_value_by_section(((struct dm_data *)data)->config_section, opt_temp, value)))
|
||||
res = dmuci_set_value(json_object_get_string(file), uci_type, opt_temp, value);
|
||||
if (linker_jobj) { // It is a reference value
|
||||
struct dm_reference reference = {0};
|
||||
|
||||
bbfdm_get_reference_linker(ctx, buf_value, &reference);
|
||||
|
||||
if ((res = dmuci_set_value_by_section(((struct dm_data *)data)->config_section, opt_temp, reference.value)))
|
||||
res = dmuci_set_value(json_object_get_string(file), uci_type, opt_temp, reference.value);
|
||||
} else {
|
||||
if (value != NULL) {
|
||||
char buf[1024] = {0};
|
||||
if ((res = dmuci_set_value_by_section(((struct dm_data *)data)->config_section, opt_temp, buf_value)))
|
||||
res = dmuci_set_value(json_object_get_string(file), uci_type, opt_temp, buf_value);
|
||||
}
|
||||
} else {
|
||||
char *pch = NULL, *pchr = NULL;
|
||||
|
||||
if (dmuci_delete_by_section(((struct dm_data *)data)->config_section, opt_temp, NULL))
|
||||
dmuci_delete(json_object_get_string(file), uci_type, opt_temp, NULL);
|
||||
|
||||
DM_STRNCPY(buf, value, sizeof(buf));
|
||||
for (pch = strtok_r(buf_value, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
|
||||
|
||||
char *p = strtok(buf, ",");
|
||||
while (p) {
|
||||
strip_lead_trail_whitespace(p);
|
||||
strip_lead_trail_whitespace(pch);
|
||||
|
||||
if ((res = dmuci_add_list_value_by_section(((struct dm_data *)data)->config_section, opt_temp, p)))
|
||||
res = dmuci_add_list_value(json_object_get_string(file), uci_type, opt_temp, p);
|
||||
if (linker_jobj) { // It is a reference value
|
||||
struct dm_reference reference = {0};
|
||||
|
||||
bbfdm_get_reference_linker(ctx, pch, &reference);
|
||||
|
||||
if ((res = dmuci_add_list_value_by_section(((struct dm_data *)data)->config_section, opt_temp, reference.value)))
|
||||
res = dmuci_add_list_value(json_object_get_string(file), uci_type, opt_temp, reference.value);
|
||||
} else {
|
||||
if ((res = dmuci_add_list_value_by_section(((struct dm_data *)data)->config_section, opt_temp, pch)))
|
||||
res = dmuci_add_list_value(json_object_get_string(file), uci_type, opt_temp, pch);
|
||||
}
|
||||
|
||||
if (res)
|
||||
return -1;
|
||||
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (file && section_name && opt_temp) {
|
||||
if (option) {
|
||||
res = dmuci_set_value(json_object_get_string(file), json_object_get_string(section_name), opt_temp, value);
|
||||
if (linker_jobj) { // It is a reference value
|
||||
struct dm_reference reference = {0};
|
||||
|
||||
bbfdm_get_reference_linker(ctx, buf_value, &reference);
|
||||
|
||||
res = dmuci_set_value(json_object_get_string(file), json_object_get_string(section_name), opt_temp, reference.value);
|
||||
} else {
|
||||
if (value != NULL) {
|
||||
char buf[1024] = {0};
|
||||
res = dmuci_set_value(json_object_get_string(file), json_object_get_string(section_name), opt_temp, buf_value);
|
||||
}
|
||||
} else {
|
||||
char *pch = NULL, *pchr = NULL;
|
||||
|
||||
dmuci_delete(json_object_get_string(file), json_object_get_string(section_name), opt_temp, NULL);
|
||||
|
||||
DM_STRNCPY(buf, value, sizeof(buf));
|
||||
for (pch = strtok_r(buf_value, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
|
||||
|
||||
char *p = strtok(buf, ",");
|
||||
while (p) {
|
||||
strip_lead_trail_whitespace(p);
|
||||
strip_lead_trail_whitespace(pch);
|
||||
|
||||
if (dmuci_add_list_value(json_object_get_string(file), json_object_get_string(section_name), opt_temp, p))
|
||||
if (linker_jobj) { // It is a reference value
|
||||
struct dm_reference reference = {0};
|
||||
|
||||
bbfdm_get_reference_linker(ctx, pch, &reference);
|
||||
|
||||
if (dmuci_add_list_value(json_object_get_string(file), json_object_get_string(section_name), opt_temp, reference.value))
|
||||
return -1;
|
||||
} else {
|
||||
if (dmuci_add_list_value(json_object_get_string(file), json_object_get_string(section_name), opt_temp, pch))
|
||||
return -1;
|
||||
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1516,33 +1597,44 @@ static int ubus_set_value(json_object *mapping_obj, int json_version, char *refp
|
|||
static int uci_v1_set_value(json_object *mapping_obj, int json_version, char *refparam, struct dmctx *ctx, void *data, char *instance, const char *value, bool is_dmmap)
|
||||
{
|
||||
struct json_object *data_s = NULL;
|
||||
struct json_object *key = NULL, *list = NULL;
|
||||
struct json_object *key = NULL, *list = NULL, *linker_jobj = NULL;
|
||||
char buf_value[1024] = {0};
|
||||
|
||||
json_object_object_get_ex(mapping_obj, "data", &data_s);
|
||||
json_object_object_get_ex(mapping_obj, "key", &key);
|
||||
json_object_object_get_ex(mapping_obj, "list", &list);
|
||||
json_object_object_get_ex(mapping_obj, "linker_obj", &linker_jobj);
|
||||
|
||||
if (data == NULL || data_s == NULL || strcmp(json_object_get_string(data_s), "@Parent") != 0)
|
||||
return -1;
|
||||
|
||||
if (value == NULL)
|
||||
return -1;
|
||||
|
||||
snprintf(buf_value, sizeof(buf_value), "%s", value);
|
||||
|
||||
char *key_value = key ? json_object_get_string(key) : NULL;
|
||||
char *list_value = list ? json_object_get_string(list) : NULL;
|
||||
|
||||
struct uci_section *req_sec = is_dmmap ? ((struct dm_data *)data)->dmmap_section : ((struct dm_data *)data)->config_section;
|
||||
|
||||
if (list_value) {
|
||||
if (value != NULL) {
|
||||
char buf[1024] = {0};
|
||||
char *pch = NULL, *pchr = NULL;
|
||||
|
||||
dmuci_delete_by_section(req_sec, list_value, NULL);
|
||||
|
||||
DM_STRNCPY(buf, value, sizeof(buf));
|
||||
for (pch = strtok_r(buf_value, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
|
||||
|
||||
char *p = strtok(buf, ",");
|
||||
while (p) {
|
||||
strip_lead_trail_whitespace(p);
|
||||
dmuci_add_list_value_by_section(req_sec, list_value, p);
|
||||
p = strtok(NULL, ",");
|
||||
strip_lead_trail_whitespace(pch);
|
||||
|
||||
if (linker_jobj) { // It is a reference value
|
||||
struct dm_reference reference = {0};
|
||||
|
||||
bbfdm_get_reference_linker(ctx, pch, &reference);
|
||||
|
||||
dmuci_add_list_value_by_section(req_sec, list_value, reference.value);
|
||||
} else {
|
||||
dmuci_add_list_value_by_section(req_sec, list_value, pch);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1553,16 +1645,24 @@ static int uci_v1_set_value(json_object *mapping_obj, int json_version, char *re
|
|||
if (strcmp(key_value, "@Name") == 0) {
|
||||
char sec_name[256] = {0};
|
||||
|
||||
if (dmuci_set_section_name(value, sec_name, sizeof(sec_name)))
|
||||
if (dmuci_set_section_name(buf_value, sec_name, sizeof(sec_name)))
|
||||
return -1;
|
||||
|
||||
dmuci_set_value_by_section(((struct dm_data *)data)->dmmap_section, "section_name", sec_name);
|
||||
dmuci_rename_section_by_section(((struct dm_data *)data)->config_section, sec_name);
|
||||
return 0;
|
||||
} else if (strstr(refparam, ".Alias")) {
|
||||
return bbf_set_alias(ctx, ((struct dm_data *)data)->dmmap_section, key_value, instance, value);
|
||||
return bbf_set_alias(ctx, ((struct dm_data *)data)->dmmap_section, key_value, instance, buf_value);
|
||||
} else {
|
||||
return dmuci_set_value_by_section(req_sec, key_value, value);
|
||||
if (linker_jobj) { // It is a reference value
|
||||
struct dm_reference reference = {0};
|
||||
|
||||
bbfdm_get_reference_linker(ctx, buf_value, &reference);
|
||||
|
||||
return dmuci_set_value_by_section(req_sec, key_value, reference.value);
|
||||
} else {
|
||||
return dmuci_set_value_by_section(req_sec, key_value, buf_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1626,7 +1726,6 @@ static int set_value_from_mapping(json_object *param_obj, int json_version, char
|
|||
|
||||
static int setvalue_param(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
{
|
||||
struct dm_reference reference = {0};
|
||||
struct dm_json_obj *pleaf = NULL;
|
||||
json_object *param_obj = NULL;
|
||||
char obj[MAX_DM_LENGTH] = {0};
|
||||
|
|
@ -1641,20 +1740,15 @@ static int setvalue_param(char *refparam, struct dmctx *ctx, void *data, char *i
|
|||
}
|
||||
}
|
||||
|
||||
if (DM_LSTRSTR(value, "=>")) {
|
||||
bbfdm_get_reference_linker(ctx, value, &reference);
|
||||
} else {
|
||||
reference.path = value;
|
||||
reference.value = dmstrdup("");
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case VALUECHECK:
|
||||
if (dm_validate_value(ctx, param_obj, reference.path))
|
||||
if (!DM_LSTRSTR(value, "=>")) { // It is not a reference value
|
||||
if (dm_validate_value(ctx, param_obj, value))
|
||||
return FAULT_9007;
|
||||
}
|
||||
break;
|
||||
case VALUESET:
|
||||
if (set_value_from_mapping(param_obj, json_version, refparam, ctx, data, instance, DM_STRLEN(reference.value) ? reference.value : reference.path))
|
||||
if (set_value_from_mapping(param_obj, json_version, refparam, ctx, data, instance, value))
|
||||
return FAULT_9007;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -647,13 +647,13 @@
|
|||
"flags": [
|
||||
"Reference"
|
||||
],
|
||||
"description": "Reference to the schedule instance",
|
||||
"description": "Comma separated list of references to the Schedules object",
|
||||
"mapping": [
|
||||
{
|
||||
"data": "@Parent",
|
||||
"type": "uci_sec",
|
||||
"key": "internet_access_schedule",
|
||||
"linker_obj": "Device.Schedules.Schedule.[Alias==@key]"
|
||||
"list": "internet_access_schedule",
|
||||
"linker_obj": "Device.Schedules.Schedule.[Alias==@list]"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue