net: lwm2m: Senml Json Base name dynamical update
SenML Json support dynamical basename for composite operation. Changes simplify base name generation and compres message better. Signed-off-by: Juha Heiskanen <juha.heiskanen@nordicsemi.no>
This commit is contained in:
parent
a2e3774e54
commit
6d624e5e18
1 changed files with 61 additions and 181 deletions
|
@ -42,7 +42,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
#define SENML_JSON_STRING_BLOCK_DATA 9
|
||||
#define SENML_JSON_UNKNOWN_ATTRIBUTE 255
|
||||
|
||||
#define SEPARATOR(f) ((f & WRITER_OUTPUT_VALUE) ? "," : "")
|
||||
#define OBJECT_SEPARATOR(f) ((f & WRITER_OUTPUT_VALUE) ? "," : "")
|
||||
|
||||
#define TOKEN_BUF_LEN 64
|
||||
|
||||
|
@ -53,7 +53,6 @@ struct json_out_formatter_data {
|
|||
/* base name */
|
||||
struct lwm2m_obj_path base_name;
|
||||
/* Add Base name */
|
||||
bool base_name_used;
|
||||
bool add_base_name_to_start;
|
||||
};
|
||||
|
||||
|
@ -290,11 +289,8 @@ static int put_begin(struct lwm2m_output_context *out, struct lwm2m_obj_path *pa
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable base name add if it is enabled
|
||||
* Base name is only added one time at first resource data
|
||||
*/
|
||||
fd->add_base_name_to_start = fd->base_name_used;
|
||||
/* Init base level state for skip first object instance compare */
|
||||
fd->base_name.level = LWM2M_PATH_LEVEL_NONE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -308,9 +304,6 @@ static int put_end(struct lwm2m_output_context *out, struct lwm2m_obj_path *path
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Clear flag. */
|
||||
fd->add_base_name_to_start = false;
|
||||
|
||||
res = buf_append(CPKT_BUF_WRITE(out->out_cpkt), "]", 1);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
|
@ -319,6 +312,35 @@ static int put_end(struct lwm2m_output_context *out, struct lwm2m_obj_path *path
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int put_begin_oi(struct lwm2m_output_context *out, struct lwm2m_obj_path *path)
|
||||
{
|
||||
struct json_out_formatter_data *fd;
|
||||
bool update_base_name = false;
|
||||
|
||||
fd = engine_get_out_user_data(out);
|
||||
if (!fd) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fd->base_name.level == LWM2M_PATH_LEVEL_NONE) {
|
||||
update_base_name = true;
|
||||
|
||||
} else if (fd->base_name.obj_id != path->obj_id ||
|
||||
fd->base_name.obj_inst_id != path->obj_inst_id) {
|
||||
update_base_name = true;
|
||||
}
|
||||
|
||||
if (update_base_name) {
|
||||
fd->base_name.level = LWM2M_PATH_LEVEL_OBJECT_INST;
|
||||
fd->base_name.obj_inst_id = path->obj_id;
|
||||
fd->base_name.obj_inst_id = path->obj_inst_id;
|
||||
}
|
||||
|
||||
fd->add_base_name_to_start = update_base_name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int put_begin_ri(struct lwm2m_output_context *out, struct lwm2m_obj_path *path)
|
||||
{
|
||||
struct json_out_formatter_data *fd;
|
||||
|
@ -362,93 +384,47 @@ static int put_json_prefix(struct lwm2m_output_context *out, struct lwm2m_obj_pa
|
|||
{
|
||||
struct json_out_formatter_data *fd;
|
||||
char *sep;
|
||||
int len = 0;
|
||||
int base_name_length = 0;
|
||||
int len = 0, t_length;
|
||||
|
||||
fd = engine_get_out_user_data(out);
|
||||
|
||||
/* Add separator after first added resource */
|
||||
sep = SEPARATOR(fd->writer_flags);
|
||||
if (!fd->base_name_used) {
|
||||
if (fd->writer_flags & WRITER_RESOURCE_INSTANCE) {
|
||||
len = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"%s{\"n\":\"/%u/%u/%u/%u\",%s:", sep, path->obj_id,
|
||||
path->obj_inst_id, path->res_id, path->res_inst_id, format);
|
||||
} else {
|
||||
len = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"%s{\"n\":\"/%u/%u/%u\",%s:", sep, path->obj_id,
|
||||
path->obj_inst_id, path->res_id, format);
|
||||
}
|
||||
sep = OBJECT_SEPARATOR(fd->writer_flags);
|
||||
|
||||
if (fd->add_base_name_to_start) {
|
||||
t_length = snprintk(json_buffer, sizeof(json_buffer), "%s{\"bn\":\"/%u/%u/\",", sep,
|
||||
path->obj_id, path->obj_inst_id);
|
||||
} else {
|
||||
if (fd->add_base_name_to_start) {
|
||||
/* Generate base name */
|
||||
if (fd->base_name.level == LWM2M_PATH_LEVEL_NONE) {
|
||||
base_name_length = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"%s{\"bn\":\"/\",", sep);
|
||||
} else if (fd->base_name.level == LWM2M_PATH_LEVEL_OBJECT) {
|
||||
base_name_length =
|
||||
snprintk(json_buffer, sizeof(json_buffer),
|
||||
"%s{\"bn\":\"/%u/\",", sep, path->obj_id);
|
||||
} else {
|
||||
base_name_length = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"%s{\"bn\":\"/%u/%u/\",", sep,
|
||||
path->obj_id, path->obj_inst_id);
|
||||
}
|
||||
fd->add_base_name_to_start = false;
|
||||
} else {
|
||||
base_name_length = snprintk(json_buffer, sizeof(json_buffer), "%s{", sep);
|
||||
}
|
||||
|
||||
if (base_name_length < 0) {
|
||||
return base_name_length;
|
||||
}
|
||||
|
||||
if (buf_append(CPKT_BUF_WRITE(out->out_cpkt), json_buffer, base_name_length) < 0) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (fd->base_name.level == LWM2M_PATH_LEVEL_NONE) {
|
||||
if (fd->writer_flags & WRITER_RESOURCE_INSTANCE) {
|
||||
len = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"\"n\":\"%u/%u/%u/%u\",%s:", path->obj_id,
|
||||
path->obj_inst_id, path->res_id, path->res_inst_id,
|
||||
format);
|
||||
} else {
|
||||
len = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"\"n\":\"%u/%u/%u\",%s:", path->obj_id,
|
||||
path->obj_inst_id, path->res_id, format);
|
||||
}
|
||||
} else if (fd->base_name.level == LWM2M_PATH_LEVEL_OBJECT) {
|
||||
if (fd->writer_flags & WRITER_RESOURCE_INSTANCE) {
|
||||
len = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"\"n\":\"%u/%u/%u\",%s:", path->obj_inst_id,
|
||||
path->res_id, path->res_inst_id, format);
|
||||
} else {
|
||||
len = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"\"n\":\"%u/%u\",%s:", path->obj_inst_id,
|
||||
path->res_id, format);
|
||||
}
|
||||
} else {
|
||||
if (fd->writer_flags & WRITER_RESOURCE_INSTANCE) {
|
||||
len = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"\"n\":\"%u/%u\",%s:", path->res_id,
|
||||
path->res_inst_id, format);
|
||||
} else {
|
||||
len = snprintk(json_buffer, sizeof(json_buffer),
|
||||
"\"n\":\"%u\",%s:", path->res_id, format);
|
||||
}
|
||||
}
|
||||
t_length = snprintk(json_buffer, sizeof(json_buffer), "%s{", sep);
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
return len;
|
||||
if (t_length < 0) {
|
||||
return t_length;
|
||||
}
|
||||
|
||||
len = t_length;
|
||||
|
||||
/* Add Name and value format */
|
||||
if (fd->writer_flags & WRITER_RESOURCE_INSTANCE) {
|
||||
t_length = snprintk(json_buffer + len, sizeof(json_buffer) - len,
|
||||
"\"n\":\"%u/%u\",%s:", path->res_id, path->res_inst_id, format);
|
||||
} else {
|
||||
t_length = snprintk(json_buffer + len, sizeof(json_buffer) - len,
|
||||
"\"n\":\"%u\",%s:", path->res_id, format);
|
||||
}
|
||||
|
||||
if (t_length < 0) {
|
||||
return t_length;
|
||||
}
|
||||
len += t_length;
|
||||
|
||||
/* Write Json Prefix to message */
|
||||
if (buf_append(CPKT_BUF_WRITE(out->out_cpkt), json_buffer, len)) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
fd->add_base_name_to_start = false;
|
||||
|
||||
return len + base_name_length;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int put_json_postfix(struct lwm2m_output_context *out)
|
||||
|
@ -1071,6 +1047,7 @@ static int get_objlnk(struct lwm2m_input_context *in, struct lwm2m_objlnk *value
|
|||
const struct lwm2m_writer senml_json_writer = {
|
||||
.put_begin = put_begin,
|
||||
.put_end = put_end,
|
||||
.put_begin_oi = put_begin_oi,
|
||||
.put_begin_ri = put_begin_ri,
|
||||
.put_end_ri = put_end_ri,
|
||||
.put_s8 = put_s8,
|
||||
|
@ -1094,94 +1071,6 @@ const struct lwm2m_reader senml_json_reader = {
|
|||
.get_objlnk = get_objlnk,
|
||||
};
|
||||
|
||||
static uint8_t lwm2m_use_base_name(sys_slist_t *lwm_path_list)
|
||||
{
|
||||
uint8_t recursive_path = 0;
|
||||
struct lwm2m_obj_path_list *entry;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(lwm_path_list, entry, node) {
|
||||
if (entry->path.level < 3) {
|
||||
recursive_path++;
|
||||
}
|
||||
}
|
||||
return recursive_path;
|
||||
}
|
||||
|
||||
static void lwm2m_define_longest_match_url_for_base_name(struct json_out_formatter_data *fd,
|
||||
sys_slist_t *lwm_path_list)
|
||||
{
|
||||
struct lwm2m_obj_path_list *entry;
|
||||
|
||||
/* Set base name use to false */
|
||||
fd->base_name_used = false;
|
||||
|
||||
if (!lwm2m_use_base_name(lwm_path_list)) {
|
||||
/* do not use base at all */
|
||||
return;
|
||||
}
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(lwm_path_list, entry, node) {
|
||||
if (fd->base_name_used == false) {
|
||||
/* First at list is define compare for rest */
|
||||
fd->base_name.level = entry->path.level;
|
||||
fd->base_name.obj_id = entry->path.obj_id;
|
||||
fd->base_name.obj_inst_id = entry->path.obj_inst_id;
|
||||
fd->base_name.res_id = entry->path.res_id;
|
||||
fd->base_name.res_inst_id = entry->path.res_inst_id;
|
||||
|
||||
fd->base_name_used = true;
|
||||
|
||||
if (fd->base_name.level == LWM2M_PATH_LEVEL_NONE) {
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry->path.level == LWM2M_PATH_LEVEL_NONE ||
|
||||
fd->base_name.obj_id != entry->path.obj_id) {
|
||||
/*
|
||||
* Stop if Object ID is not match or compare url level is 0
|
||||
* Define just "/" base name
|
||||
*/
|
||||
fd->base_name.level = LWM2M_PATH_LEVEL_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fd->base_name.level == LWM2M_PATH_LEVEL_OBJECT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd->base_name.level >= entry->path.level &&
|
||||
fd->base_name.obj_inst_id != entry->path.obj_inst_id) {
|
||||
/* Define just "/obj_id/" base name */
|
||||
fd->base_name.level = LWM2M_PATH_LEVEL_OBJECT;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd->base_name.level == LWM2M_PATH_LEVEL_OBJECT_INST) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd->base_name.level >= entry->path.level &&
|
||||
fd->base_name.res_id != entry->path.res_id) {
|
||||
/* Do not continue deeper possible bn "/obj_id/obj_inst_id/" */
|
||||
fd->base_name.level = LWM2M_PATH_LEVEL_OBJECT_INST;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd->base_name.level == LWM2M_PATH_LEVEL_RESOURCE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd->base_name.level >= entry->path.level &&
|
||||
fd->base_name.res_inst_id != entry->path.res_inst_id) {
|
||||
/* Do not continue deeper possible bn "/obj_id/obj_inst_id/res_id/" */
|
||||
fd->base_name.level = LWM2M_PATH_LEVEL_RESOURCE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lwm2m_senml_json_context_init(struct lwm2m_senml_json_context *ctx)
|
||||
{
|
||||
ctx->base_name_stored = false;
|
||||
|
@ -1206,9 +1095,6 @@ int do_read_op_senml_json(struct lwm2m_message *msg)
|
|||
/* Add one entry to list */
|
||||
sys_slist_append(&lwm_path_list, &temp.node);
|
||||
|
||||
/* Detect longest match base name to url */
|
||||
lwm2m_define_longest_match_url_for_base_name(&fd, &lwm_path_list);
|
||||
|
||||
ret = lwm2m_perform_read_op(msg, LWM2M_FORMAT_APP_SEML_JSON);
|
||||
engine_clear_out_user_data(&msg->out);
|
||||
|
||||
|
@ -1664,9 +1550,6 @@ int do_composite_read_op_senml_json(struct lwm2m_message *msg)
|
|||
(void)memset(&fd, 0, sizeof(fd));
|
||||
engine_set_out_user_data(&msg->out, &fd);
|
||||
|
||||
/* Detect longest match base name to url */
|
||||
lwm2m_define_longest_match_url_for_base_name(&fd, &lwm_path_list);
|
||||
|
||||
ret = lwm2m_perform_composite_read_op(msg, LWM2M_FORMAT_APP_SEML_JSON, &lwm_path_list);
|
||||
engine_clear_out_user_data(&msg->out);
|
||||
|
||||
|
@ -1681,9 +1564,6 @@ int do_send_op_senml_json(struct lwm2m_message *msg, sys_slist_t *lwm_path_list)
|
|||
(void)memset(&fd, 0, sizeof(fd));
|
||||
engine_set_out_user_data(&msg->out, &fd);
|
||||
|
||||
/* Detect longest match base name to url */
|
||||
lwm2m_define_longest_match_url_for_base_name(&fd, lwm_path_list);
|
||||
|
||||
ret = lwm2m_perform_composite_read_op(msg, LWM2M_FORMAT_APP_SEML_JSON, lwm_path_list);
|
||||
engine_clear_out_user_data(&msg->out);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue