net: lwm2m: Added SenML JSON support for Read & Write
LwM2M SenML JSON contain format support for Read / Write operation. Added Kconfig configurable for enable SenML JSON format. LwM2m read validate read operation and report out of memory. Signed-off-by: Juha Heiskanen <juha.heiskanen@nordicsemi.no>
This commit is contained in:
parent
ea98d0587b
commit
a9c1b8d0f2
7 changed files with 1836 additions and 3 deletions
|
@ -48,6 +48,10 @@ zephyr_library_sources_ifdef(CONFIG_LWM2M_PORTFOLIO_OBJ_SUPPORT
|
||||||
zephyr_library_sources_ifdef(CONFIG_LWM2M_RW_JSON_SUPPORT
|
zephyr_library_sources_ifdef(CONFIG_LWM2M_RW_JSON_SUPPORT
|
||||||
lwm2m_rw_json.c
|
lwm2m_rw_json.c
|
||||||
)
|
)
|
||||||
|
# SENML JSON support
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT
|
||||||
|
lwm2m_rw_senml_json.c
|
||||||
|
)
|
||||||
|
|
||||||
# IPSO Objects
|
# IPSO Objects
|
||||||
zephyr_library_sources_ifdef(CONFIG_LWM2M_IPSO_TEMP_SENSOR
|
zephyr_library_sources_ifdef(CONFIG_LWM2M_IPSO_TEMP_SENSOR
|
||||||
|
|
|
@ -408,6 +408,13 @@ config LWM2M_RW_JSON_SUPPORT
|
||||||
help
|
help
|
||||||
Include support for writing JSON data
|
Include support for writing JSON data
|
||||||
|
|
||||||
|
|
||||||
|
config LWM2M_RW_SENML_JSON_SUPPORT
|
||||||
|
bool "SENML JSON data format"
|
||||||
|
depends on BASE64
|
||||||
|
help
|
||||||
|
Include support for write / parse SENML JSON data
|
||||||
|
|
||||||
config LWM2M_DEVICE_PWRSRC_MAX
|
config LWM2M_DEVICE_PWRSRC_MAX
|
||||||
int "Maximum # of device power source records"
|
int "Maximum # of device power source records"
|
||||||
default 5
|
default 5
|
||||||
|
|
|
@ -44,6 +44,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
#include "lwm2m_rw_plain_text.h"
|
#include "lwm2m_rw_plain_text.h"
|
||||||
#include "lwm2m_rw_oma_tlv.h"
|
#include "lwm2m_rw_oma_tlv.h"
|
||||||
#include "lwm2m_util.h"
|
#include "lwm2m_util.h"
|
||||||
|
#if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT)
|
||||||
|
#include "lwm2m_rw_senml_json.h"
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_LWM2M_RW_JSON_SUPPORT
|
#ifdef CONFIG_LWM2M_RW_JSON_SUPPORT
|
||||||
#include "lwm2m_rw_json.h"
|
#include "lwm2m_rw_json.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -260,6 +263,9 @@ static int init_block_ctx(const uint8_t *token, uint8_t tkl,
|
||||||
(*ctx)->timestamp = timestamp;
|
(*ctx)->timestamp = timestamp;
|
||||||
(*ctx)->expected = 0;
|
(*ctx)->expected = 0;
|
||||||
(*ctx)->last_block = false;
|
(*ctx)->last_block = false;
|
||||||
|
#if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT)
|
||||||
|
lwm2m_senml_json_context_init(&(*ctx)->senml_json_ctx);
|
||||||
|
#endif
|
||||||
memset(&(*ctx)->opaque, 0, sizeof((*ctx)->opaque));
|
memset(&(*ctx)->opaque, 0, sizeof((*ctx)->opaque));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1205,6 +1211,12 @@ static int select_writer(struct lwm2m_output_context *out, uint16_t accept)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT)
|
||||||
|
case LWM2M_FORMAT_APP_SEML_JSON:
|
||||||
|
out->writer = &senml_json_writer;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_WRN("Unknown content type %u", accept);
|
LOG_WRN("Unknown content type %u", accept);
|
||||||
return -ENOMSG;
|
return -ENOMSG;
|
||||||
|
@ -1236,6 +1248,12 @@ static int select_reader(struct lwm2m_input_context *in, uint16_t format)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT)
|
||||||
|
case LWM2M_FORMAT_APP_SEML_JSON:
|
||||||
|
in->reader = &senml_json_reader;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_WRN("Unknown content type %u", format);
|
LOG_WRN("Unknown content type %u", format);
|
||||||
return -ENOMSG;
|
return -ENOMSG;
|
||||||
|
@ -2475,10 +2493,12 @@ static int lwm2m_read_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0) {
|
/* Validate that we really read some data */
|
||||||
return ret;
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Read operation fail");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res->multi_res_inst) {
|
if (res->multi_res_inst) {
|
||||||
|
@ -3294,6 +3314,11 @@ static int do_read_op(struct lwm2m_message *msg, uint16_t content_format)
|
||||||
return do_read_op_json(msg, content_format);
|
return do_read_op_json(msg, content_format);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT)
|
||||||
|
case LWM2M_FORMAT_APP_SEML_JSON:
|
||||||
|
return do_read_op_senml_json(msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERR("Unsupported content-format: %u", content_format);
|
LOG_ERR("Unsupported content-format: %u", content_format);
|
||||||
return -ENOMSG;
|
return -ENOMSG;
|
||||||
|
@ -3795,6 +3820,11 @@ static int do_write_op(struct lwm2m_message *msg,
|
||||||
return do_write_op_json(msg);
|
return do_write_op_json(msg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT)
|
||||||
|
case LWM2M_FORMAT_APP_SEML_JSON:
|
||||||
|
return do_write_op_senml_json(msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERR("Unsupported format: %u", format);
|
LOG_ERR("Unsupported format: %u", format);
|
||||||
return -ENOMSG;
|
return -ENOMSG;
|
||||||
|
@ -5264,4 +5294,185 @@ static int lwm2m_engine_init(const struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct lwm2m_obj_path_list *lwm2m_engine_get_from_list(sys_slist_t *path_list)
|
||||||
|
{
|
||||||
|
sys_snode_t *path_node = sys_slist_get(path_list);
|
||||||
|
struct lwm2m_obj_path_list *entry;
|
||||||
|
|
||||||
|
if (!path_node) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = SYS_SLIST_CONTAINER(path_node, entry, node);
|
||||||
|
if (entry) {
|
||||||
|
memset(entry, 0, sizeof(struct lwm2m_obj_path_list));
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lwm2m_engine_free_list(sys_slist_t *path_list, sys_slist_t *free_list)
|
||||||
|
{
|
||||||
|
sys_snode_t *node;
|
||||||
|
|
||||||
|
while (NULL != (node = sys_slist_get(path_list))) {
|
||||||
|
/* Add to free list */
|
||||||
|
sys_slist_append(free_list, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool lwm2m_path_object_compare(struct lwm2m_obj_path *path,
|
||||||
|
struct lwm2m_obj_path *compare_path)
|
||||||
|
{
|
||||||
|
if (path->level != compare_path->level || path->obj_id != compare_path->obj_id ||
|
||||||
|
path->obj_inst_id != compare_path->obj_inst_id ||
|
||||||
|
path->res_id != compare_path->res_id ||
|
||||||
|
path->res_inst_id != compare_path->res_inst_id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lwm2m_engine_path_list_init(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list,
|
||||||
|
struct lwm2m_obj_path_list path_object_buf[],
|
||||||
|
uint8_t path_object_size)
|
||||||
|
{
|
||||||
|
/* Init list */
|
||||||
|
sys_slist_init(lwm2m_path_list);
|
||||||
|
sys_slist_init(lwm2m_free_list);
|
||||||
|
|
||||||
|
/* Put buffer elements to free list */
|
||||||
|
for (int i = 0; i < path_object_size; i++) {
|
||||||
|
sys_slist_append(lwm2m_free_list, &path_object_buf[i].node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int lwm2m_engine_add_path_to_list(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list,
|
||||||
|
struct lwm2m_obj_path *path)
|
||||||
|
{
|
||||||
|
struct lwm2m_obj_path_list *prev = NULL;
|
||||||
|
struct lwm2m_obj_path_list *entry;
|
||||||
|
struct lwm2m_obj_path_list *new_entry;
|
||||||
|
bool add_before_current = false;
|
||||||
|
|
||||||
|
if (path->level == LWM2M_PATH_LEVEL_NONE) {
|
||||||
|
/* Clear the list if we are adding the root path which includes all */
|
||||||
|
lwm2m_engine_free_list(lwm2m_path_list, lwm2m_free_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check is it at list already here */
|
||||||
|
new_entry = lwm2m_engine_get_from_list(lwm2m_free_list);
|
||||||
|
if (!new_entry) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_entry->path = *path;
|
||||||
|
if (!sys_slist_is_empty(lwm2m_path_list)) {
|
||||||
|
|
||||||
|
/* Keep list Ordered by Object ID/ Object instance/ resource ID */
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER(lwm2m_path_list, entry, node) {
|
||||||
|
if (entry->path.level == LWM2M_PATH_LEVEL_NONE ||
|
||||||
|
lwm2m_path_object_compare(&entry->path, &new_entry->path)) {
|
||||||
|
/* Already Root request at list or current path is at list */
|
||||||
|
sys_slist_append(lwm2m_free_list, &new_entry->node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->path.obj_id > path->obj_id) {
|
||||||
|
/* New entry have smaller Object ID */
|
||||||
|
add_before_current = true;
|
||||||
|
} else if (entry->path.obj_id == path->obj_id &&
|
||||||
|
entry->path.level > path->level) {
|
||||||
|
add_before_current = true;
|
||||||
|
} else if (entry->path.obj_id == path->obj_id &&
|
||||||
|
entry->path.level == path->level) {
|
||||||
|
if (path->level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||||
|
entry->path.obj_inst_id > path->obj_inst_id) {
|
||||||
|
/*
|
||||||
|
* New have same Object ID
|
||||||
|
* but smaller Object Instance ID
|
||||||
|
*/
|
||||||
|
add_before_current = true;
|
||||||
|
} else if (path->level >= LWM2M_PATH_LEVEL_RESOURCE &&
|
||||||
|
entry->path.obj_inst_id == path->obj_inst_id &&
|
||||||
|
entry->path.res_id > path->res_id) {
|
||||||
|
/*
|
||||||
|
* Object ID and Object Intance id same
|
||||||
|
* but Resource ID is smaller
|
||||||
|
*/
|
||||||
|
add_before_current = true;
|
||||||
|
} else if (path->level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
|
||||||
|
entry->path.obj_inst_id == path->obj_inst_id &&
|
||||||
|
entry->path.res_id == path->res_id &&
|
||||||
|
entry->path.res_inst_id > path->res_inst_id) {
|
||||||
|
/*
|
||||||
|
* Object ID, Object Intance id & Resource ID same
|
||||||
|
* but Resource instance ID is smaller
|
||||||
|
*/
|
||||||
|
add_before_current = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add_before_current) {
|
||||||
|
if (prev) {
|
||||||
|
sys_slist_insert(lwm2m_path_list, &prev->node,
|
||||||
|
&new_entry->node);
|
||||||
|
} else {
|
||||||
|
sys_slist_prepend(lwm2m_path_list, &new_entry->node);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
prev = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add First or new tail entry */
|
||||||
|
sys_slist_append(lwm2m_path_list, &new_entry->node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lwm2m_engine_clear_duplicate_path(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list)
|
||||||
|
{
|
||||||
|
struct lwm2m_obj_path_list *prev = NULL;
|
||||||
|
struct lwm2m_obj_path_list *entry, *tmp;
|
||||||
|
bool remove_entry;
|
||||||
|
|
||||||
|
if (sys_slist_is_empty(lwm2m_path_list)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep list Ordered but remove if shorter path is similar */
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(lwm2m_path_list, entry, tmp, node) {
|
||||||
|
|
||||||
|
if (prev && prev->path.level < entry->path.level) {
|
||||||
|
if (prev->path.level == LWM2M_PATH_LEVEL_OBJECT &&
|
||||||
|
entry->path.obj_id == prev->path.obj_id) {
|
||||||
|
remove_entry = true;
|
||||||
|
} else if (prev->path.level == LWM2M_PATH_LEVEL_OBJECT_INST &&
|
||||||
|
entry->path.obj_id == prev->path.obj_id &&
|
||||||
|
entry->path.obj_inst_id == prev->path.obj_inst_id) {
|
||||||
|
/* Remove current from the list */
|
||||||
|
remove_entry = true;
|
||||||
|
} else if (prev->path.level == LWM2M_PATH_LEVEL_RESOURCE &&
|
||||||
|
entry->path.obj_id == prev->path.obj_id &&
|
||||||
|
entry->path.obj_inst_id == prev->path.obj_inst_id &&
|
||||||
|
entry->path.res_id == prev->path.res_id) {
|
||||||
|
/* Remove current from the list */
|
||||||
|
remove_entry = true;
|
||||||
|
} else {
|
||||||
|
remove_entry = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove_entry) {
|
||||||
|
/* Remove Current entry */
|
||||||
|
sys_slist_remove(lwm2m_path_list, &prev->node, &entry->node);
|
||||||
|
sys_slist_append(lwm2m_free_list, &entry->node);
|
||||||
|
} else {
|
||||||
|
prev = entry;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prev = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SYS_INIT(lwm2m_engine_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
SYS_INIT(lwm2m_engine_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define LWM2M_FORMAT_APP_OCTET_STREAM 42
|
#define LWM2M_FORMAT_APP_OCTET_STREAM 42
|
||||||
#define LWM2M_FORMAT_APP_EXI 47
|
#define LWM2M_FORMAT_APP_EXI 47
|
||||||
#define LWM2M_FORMAT_APP_JSON 50
|
#define LWM2M_FORMAT_APP_JSON 50
|
||||||
|
#define LWM2M_FORMAT_APP_SEML_JSON 110
|
||||||
#define LWM2M_FORMAT_OMA_PLAIN_TEXT 1541
|
#define LWM2M_FORMAT_OMA_PLAIN_TEXT 1541
|
||||||
#define LWM2M_FORMAT_OMA_OLD_TLV 1542
|
#define LWM2M_FORMAT_OMA_OLD_TLV 1542
|
||||||
#define LWM2M_FORMAT_OMA_OLD_JSON 1543
|
#define LWM2M_FORMAT_OMA_OLD_JSON 1543
|
||||||
|
@ -54,6 +55,12 @@
|
||||||
#define COAP_REPLY_STATUS_NONE 0
|
#define COAP_REPLY_STATUS_NONE 0
|
||||||
#define COAP_REPLY_STATUS_ERROR 1
|
#define COAP_REPLY_STATUS_ERROR 1
|
||||||
|
|
||||||
|
/* path object list */
|
||||||
|
struct lwm2m_obj_path_list {
|
||||||
|
sys_snode_t node;
|
||||||
|
struct lwm2m_obj_path path;
|
||||||
|
};
|
||||||
|
|
||||||
/* Establish a request handler callback type */
|
/* Establish a request handler callback type */
|
||||||
typedef int (*udp_request_handler_cb_t)(struct coap_packet *request,
|
typedef int (*udp_request_handler_cb_t)(struct coap_packet *request,
|
||||||
struct lwm2m_message *msg);
|
struct lwm2m_message *msg);
|
||||||
|
@ -100,6 +107,16 @@ void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx);
|
||||||
uint8_t *lwm2m_get_message_buf(void);
|
uint8_t *lwm2m_get_message_buf(void);
|
||||||
int lwm2m_put_message_buf(uint8_t *buf);
|
int lwm2m_put_message_buf(uint8_t *buf);
|
||||||
|
|
||||||
|
/* Initialize path list */
|
||||||
|
void lwm2m_engine_path_list_init(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list,
|
||||||
|
struct lwm2m_obj_path_list path_object_buf[],
|
||||||
|
uint8_t path_object_size);
|
||||||
|
/* Add new Path to the list */
|
||||||
|
int lwm2m_engine_add_path_to_list(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list,
|
||||||
|
struct lwm2m_obj_path *path);
|
||||||
|
/* Remove paths when parent already exist in the list. */
|
||||||
|
void lwm2m_engine_clear_duplicate_path(sys_slist_t *lwm2m_path_list, sys_slist_t *lwm2m_free_list);
|
||||||
|
|
||||||
/* LwM2M message functions */
|
/* LwM2M message functions */
|
||||||
struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx);
|
struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx);
|
||||||
void lwm2m_reset_message(struct lwm2m_message *msg, bool release);
|
void lwm2m_reset_message(struct lwm2m_message *msg, bool release);
|
||||||
|
|
|
@ -137,6 +137,8 @@ BUILD_ASSERT(CONFIG_LWM2M_COAP_BLOCK_SIZE <= CONFIG_LWM2M_COAP_MAX_MSG_SIZE,
|
||||||
/* buffer util macros */
|
/* buffer util macros */
|
||||||
#define CPKT_BUF_WRITE(cpkt) (cpkt)->data, &(cpkt)->offset, (cpkt)->max_len
|
#define CPKT_BUF_WRITE(cpkt) (cpkt)->data, &(cpkt)->offset, (cpkt)->max_len
|
||||||
#define CPKT_BUF_READ(cpkt) (cpkt)->data, (cpkt)->max_len
|
#define CPKT_BUF_READ(cpkt) (cpkt)->data, (cpkt)->max_len
|
||||||
|
#define CPKT_BUF_W_PTR(cpkt) ((cpkt)->data + (cpkt)->offset)
|
||||||
|
#define CPKT_BUF_W_SIZE(cpkt) ((cpkt)->max_len - (cpkt)->offset)
|
||||||
|
|
||||||
struct lwm2m_engine_obj;
|
struct lwm2m_engine_obj;
|
||||||
struct lwm2m_message;
|
struct lwm2m_message;
|
||||||
|
@ -398,9 +400,22 @@ struct lwm2m_opaque_context {
|
||||||
size_t remaining;
|
size_t remaining;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct lwm2m_senml_json_context {
|
||||||
|
bool base_name_stored : 1;
|
||||||
|
bool full_name_true : 1;
|
||||||
|
uint8_t base64_buf_len : 2;
|
||||||
|
uint8_t base64_mod_buf[3];
|
||||||
|
uint8_t json_flags;
|
||||||
|
struct lwm2m_obj_path base_name_path;
|
||||||
|
uint8_t resource_path_level;
|
||||||
|
};
|
||||||
|
|
||||||
struct lwm2m_block_context {
|
struct lwm2m_block_context {
|
||||||
struct coap_block_context ctx;
|
struct coap_block_context ctx;
|
||||||
struct lwm2m_opaque_context opaque;
|
struct lwm2m_opaque_context opaque;
|
||||||
|
#if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT)
|
||||||
|
struct lwm2m_senml_json_context senml_json_ctx;
|
||||||
|
#endif
|
||||||
int64_t timestamp;
|
int64_t timestamp;
|
||||||
uint32_t expected;
|
uint32_t expected;
|
||||||
uint8_t token[8];
|
uint8_t token[8];
|
||||||
|
|
1557
subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c
Normal file
1557
subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c
Normal file
File diff suppressed because it is too large
Load diff
22
subsys/net/lib/lwm2m/lwm2m_rw_senml_json.h
Normal file
22
subsys/net/lib/lwm2m/lwm2m_rw_senml_json.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWM2M_RW_SENML_JSON_H_
|
||||||
|
#define LWM2M_RW_SENML_JSON_H_
|
||||||
|
|
||||||
|
#include "lwm2m_object.h"
|
||||||
|
|
||||||
|
extern const struct lwm2m_writer senml_json_writer;
|
||||||
|
extern const struct lwm2m_reader senml_json_reader;
|
||||||
|
|
||||||
|
/* Init Context format for coap blocking */
|
||||||
|
void lwm2m_senml_json_context_init(struct lwm2m_senml_json_context *ctx);
|
||||||
|
/* General Read single Path operation */
|
||||||
|
int do_read_op_senml_json(struct lwm2m_message *msg);
|
||||||
|
/* General Write single Path operation */
|
||||||
|
int do_write_op_senml_json(struct lwm2m_message *msg);
|
||||||
|
|
||||||
|
#endif /* LWM2M_RW_SENML_JSON_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue