2017-07-25 11:04:16 -07:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2017 Linaro Limited
|
2019-01-24 14:40:23 -08:00
|
|
|
* Copyright (c) 2018-2019 Foundries.io
|
2017-07-25 11:04:16 -07:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2015, Yanzi Networks AB.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. Neither the name of the copyright holder nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
|
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Original Authors:
|
|
|
|
* Joakim Eriksson <joakime@sics.se>
|
|
|
|
* Niclas Finne <nfi@sics.se>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef LWM2M_OBJECT_H_
|
|
|
|
#define LWM2M_OBJECT_H_
|
|
|
|
|
|
|
|
/* stdint conversions */
|
|
|
|
#include <zephyr/types.h>
|
|
|
|
#include <stddef.h>
|
2019-01-24 14:40:23 -08:00
|
|
|
#include <kernel.h>
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
#include <net/net_ip.h>
|
2019-06-26 10:33:49 -04:00
|
|
|
#include <sys/printk.h>
|
2019-06-26 10:33:55 -04:00
|
|
|
#include <sys/util.h>
|
2019-01-24 14:40:23 -08:00
|
|
|
|
2019-02-01 14:44:42 +02:00
|
|
|
#include <net/coap.h>
|
2019-01-24 14:40:23 -08:00
|
|
|
#include <net/lwm2m.h>
|
2017-07-07 11:04:03 -07:00
|
|
|
|
2019-01-25 14:13:07 -08:00
|
|
|
#include "buf_util.h"
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
/* #####/###/#####/### + NULL */
|
|
|
|
#define MAX_RESOURCE_LEN 20
|
|
|
|
|
2018-04-30 15:42:55 -07:00
|
|
|
/* operations / permissions */
|
|
|
|
/* values from 0 to 7 can be used as permission checks */
|
|
|
|
#define LWM2M_OP_READ 0
|
|
|
|
#define LWM2M_OP_WRITE 1
|
|
|
|
#define LWM2M_OP_CREATE 2
|
|
|
|
#define LWM2M_OP_DELETE 3
|
|
|
|
#define LWM2M_OP_EXECUTE 4
|
2018-04-30 16:43:25 -07:00
|
|
|
#define LWM2M_FLAG_OPTIONAL 7
|
2018-04-30 15:42:55 -07:00
|
|
|
/* values >7 aren't used for permission checks */
|
|
|
|
#define LWM2M_OP_DISCOVER 8
|
|
|
|
#define LWM2M_OP_WRITE_ATTR 9
|
2017-07-07 11:04:03 -07:00
|
|
|
|
|
|
|
/* resource permissions */
|
2018-04-30 15:35:43 -07:00
|
|
|
#define LWM2M_PERM_R BIT(LWM2M_OP_READ)
|
2018-04-30 16:43:25 -07:00
|
|
|
#define LWM2M_PERM_R_OPT (BIT(LWM2M_OP_READ) | \
|
|
|
|
BIT(LWM2M_FLAG_OPTIONAL))
|
2018-04-30 15:35:43 -07:00
|
|
|
#define LWM2M_PERM_W (BIT(LWM2M_OP_WRITE) | \
|
|
|
|
BIT(LWM2M_OP_CREATE))
|
2018-04-30 16:43:25 -07:00
|
|
|
#define LWM2M_PERM_W_OPT (BIT(LWM2M_OP_WRITE) | \
|
|
|
|
BIT(LWM2M_OP_CREATE) | \
|
|
|
|
BIT(LWM2M_FLAG_OPTIONAL))
|
2018-04-30 15:35:43 -07:00
|
|
|
#define LWM2M_PERM_X BIT(LWM2M_OP_EXECUTE)
|
2018-04-30 16:43:25 -07:00
|
|
|
#define LWM2M_PERM_X_OPT (BIT(LWM2M_OP_EXECUTE) | \
|
|
|
|
BIT(LWM2M_FLAG_OPTIONAL))
|
2018-04-30 15:35:43 -07:00
|
|
|
#define LWM2M_PERM_RW (BIT(LWM2M_OP_READ) | \
|
|
|
|
BIT(LWM2M_OP_WRITE) | \
|
|
|
|
BIT(LWM2M_OP_CREATE))
|
2018-04-30 16:43:25 -07:00
|
|
|
#define LWM2M_PERM_RW_OPT (BIT(LWM2M_OP_READ) | \
|
|
|
|
BIT(LWM2M_OP_WRITE) | \
|
|
|
|
BIT(LWM2M_OP_CREATE) | \
|
|
|
|
BIT(LWM2M_FLAG_OPTIONAL))
|
2018-04-30 15:35:43 -07:00
|
|
|
#define LWM2M_PERM_RWX (BIT(LWM2M_OP_READ) | \
|
|
|
|
BIT(LWM2M_OP_WRITE) | \
|
|
|
|
BIT(LWM2M_OP_CREATE) | \
|
|
|
|
BIT(LWM2M_OP_EXECUTE))
|
2018-04-30 16:43:25 -07:00
|
|
|
#define LWM2M_PERM_RWX_OPT (BIT(LWM2M_OP_READ) | \
|
|
|
|
BIT(LWM2M_OP_WRITE) | \
|
|
|
|
BIT(LWM2M_OP_CREATE) | \
|
|
|
|
BIT(LWM2M_OP_EXECUTE) | \
|
|
|
|
BIT(LWM2M_FLAG_OPTIONAL))
|
2017-07-07 11:04:03 -07:00
|
|
|
|
2019-02-21 00:46:27 -08:00
|
|
|
#define LWM2M_HAS_PERM(of, p) (((of)->permissions & p) == p)
|
2018-04-30 15:30:12 -07:00
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
/* resource types */
|
|
|
|
#define LWM2M_RES_TYPE_NONE 0
|
|
|
|
#define LWM2M_RES_TYPE_OPAQUE 1
|
|
|
|
#define LWM2M_RES_TYPE_STRING 2
|
|
|
|
#define LWM2M_RES_TYPE_UINT64 3
|
|
|
|
#define LWM2M_RES_TYPE_U64 3
|
|
|
|
#define LWM2M_RES_TYPE_UINT 4
|
|
|
|
#define LWM2M_RES_TYPE_U32 4
|
|
|
|
#define LWM2M_RES_TYPE_U16 5
|
|
|
|
#define LWM2M_RES_TYPE_U8 6
|
|
|
|
#define LWM2M_RES_TYPE_INT64 7
|
|
|
|
#define LWM2M_RES_TYPE_S64 7
|
|
|
|
#define LWM2M_RES_TYPE_INT 8
|
|
|
|
#define LWM2M_RES_TYPE_S32 8
|
|
|
|
#define LWM2M_RES_TYPE_S16 9
|
|
|
|
#define LWM2M_RES_TYPE_S8 10
|
|
|
|
#define LWM2M_RES_TYPE_BOOL 11
|
|
|
|
#define LWM2M_RES_TYPE_TIME 12
|
|
|
|
#define LWM2M_RES_TYPE_FLOAT32 13
|
|
|
|
#define LWM2M_RES_TYPE_FLOAT64 14
|
2020-05-19 12:37:02 +02:00
|
|
|
#define LWM2M_RES_TYPE_OBJLNK 15
|
2017-07-07 11:04:03 -07:00
|
|
|
|
|
|
|
/* remember that we have already output a value - can be between two block's */
|
|
|
|
#define WRITER_OUTPUT_VALUE 1
|
|
|
|
#define WRITER_RESOURCE_INSTANCE 2
|
|
|
|
|
2019-01-25 14:13:07 -08:00
|
|
|
#define MAX_PACKET_SIZE (CONFIG_LWM2M_COAP_BLOCK_SIZE + \
|
|
|
|
CONFIG_LWM2M_ENGINE_MESSAGE_HEADER_SIZE)
|
|
|
|
|
|
|
|
/* buffer util macros */
|
|
|
|
#define CPKT_BUF_WRITE(cpkt) (cpkt)->data, &(cpkt)->offset, (cpkt)->max_len
|
|
|
|
#define CPKT_BUF_READ(cpkt) (cpkt)->data, (cpkt)->max_len
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
struct lwm2m_engine_obj;
|
2019-01-24 14:40:23 -08:00
|
|
|
struct lwm2m_message;
|
2017-07-07 11:04:03 -07:00
|
|
|
|
|
|
|
/* path representing object instances */
|
|
|
|
struct lwm2m_obj_path {
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t obj_id;
|
|
|
|
uint16_t obj_inst_id;
|
|
|
|
uint16_t res_id;
|
|
|
|
uint16_t res_inst_id;
|
|
|
|
uint8_t level; /* 0/1/2/3/4 (4 = resource instance) */
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
2019-07-29 10:06:00 -07:00
|
|
|
#define OBJ_FIELD(_id, _perm, _type) \
|
|
|
|
{ .res_id = _id, \
|
|
|
|
.permissions = LWM2M_PERM_ ## _perm, \
|
|
|
|
.data_type = LWM2M_RES_TYPE_ ## _type, }
|
2017-07-07 11:04:03 -07:00
|
|
|
|
2019-07-29 10:06:00 -07:00
|
|
|
/* Keep OBJ_FIELD_DATA around for historical reasons */
|
2017-07-07 11:04:03 -07:00
|
|
|
#define OBJ_FIELD_DATA(res_id, perm, type) \
|
2019-07-29 10:06:00 -07:00
|
|
|
OBJ_FIELD(res_id, perm, type)
|
2017-07-07 11:04:03 -07:00
|
|
|
|
|
|
|
#define OBJ_FIELD_EXECUTE(res_id) \
|
2019-07-29 10:06:00 -07:00
|
|
|
OBJ_FIELD(res_id, X, NONE)
|
2017-07-07 11:04:03 -07:00
|
|
|
|
2018-04-30 16:43:25 -07:00
|
|
|
#define OBJ_FIELD_EXECUTE_OPT(res_id) \
|
2019-07-29 10:06:00 -07:00
|
|
|
OBJ_FIELD(res_id, X_OPT, NONE)
|
2018-04-30 16:43:25 -07:00
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
struct lwm2m_engine_obj_field {
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t res_id;
|
|
|
|
uint8_t permissions;
|
|
|
|
uint8_t data_type;
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct lwm2m_engine_obj_inst *
|
2020-05-27 11:26:57 -05:00
|
|
|
(*lwm2m_engine_obj_create_cb_t)(uint16_t obj_inst_id);
|
2017-07-07 11:04:03 -07:00
|
|
|
|
|
|
|
struct lwm2m_engine_obj {
|
2018-05-07 13:33:48 -07:00
|
|
|
/* object list */
|
2017-07-07 11:04:03 -07:00
|
|
|
sys_snode_t node;
|
2018-05-07 13:33:48 -07:00
|
|
|
|
|
|
|
/* object field definitions */
|
2017-07-07 11:04:03 -07:00
|
|
|
struct lwm2m_engine_obj_field *fields;
|
2018-05-07 13:33:48 -07:00
|
|
|
|
|
|
|
/* object event callbacks */
|
2017-07-07 11:04:03 -07:00
|
|
|
lwm2m_engine_obj_create_cb_t create_cb;
|
2019-07-29 10:07:00 -07:00
|
|
|
lwm2m_engine_user_cb_t delete_cb;
|
2018-07-12 10:00:01 -07:00
|
|
|
lwm2m_engine_user_cb_t user_create_cb;
|
|
|
|
lwm2m_engine_user_cb_t user_delete_cb;
|
2017-11-24 18:47:00 +08:00
|
|
|
|
2018-05-07 13:33:48 -07:00
|
|
|
/* object member data */
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t obj_id;
|
|
|
|
uint16_t field_count;
|
|
|
|
uint16_t instance_count;
|
|
|
|
uint16_t max_instance_count;
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
2019-07-29 10:09:00 -07:00
|
|
|
/* Resource instances with this value are considered "not created" yet */
|
|
|
|
#define RES_INSTANCE_NOT_CREATED 65535
|
|
|
|
|
|
|
|
/* Resource macros */
|
|
|
|
#define _INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_count, \
|
|
|
|
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
|
|
|
|
_r_ptr[_r_idx].res_id = _id; \
|
|
|
|
_r_ptr[_r_idx].res_instances = _ri_ptr; \
|
|
|
|
_r_ptr[_r_idx].res_inst_count = _ri_count; \
|
|
|
|
_r_ptr[_r_idx].read_cb = _r_cb; \
|
|
|
|
_r_ptr[_r_idx].pre_write_cb = _pre_w_cb; \
|
|
|
|
_r_ptr[_r_idx].post_write_cb = _post_w_cb; \
|
|
|
|
_r_ptr[_r_idx].execute_cb = _ex_cb
|
|
|
|
|
|
|
|
#define _INIT_OBJ_RES_INST(_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
|
|
|
_data_ptr, _data_len) \
|
|
|
|
do { \
|
|
|
|
if (_ri_ptr != NULL && _ri_count > 0) { \
|
|
|
|
for (int _i = 0; _i < _ri_count; _i++) { \
|
|
|
|
_ri_ptr[_ri_idx + _i].data_ptr = \
|
|
|
|
(_data_ptr + _i); \
|
2020-09-24 15:28:10 +02:00
|
|
|
_ri_ptr[_ri_idx + _i].max_data_len = \
|
|
|
|
_data_len; \
|
2019-07-29 10:09:00 -07:00
|
|
|
_ri_ptr[_ri_idx + _i].data_len = \
|
|
|
|
_data_len; \
|
|
|
|
if (_ri_create) { \
|
|
|
|
_ri_ptr[_ri_idx + _i].res_inst_id = \
|
|
|
|
_i; \
|
|
|
|
} else { \
|
|
|
|
_ri_ptr[_ri_idx + _i].res_inst_id = \
|
|
|
|
RES_INSTANCE_NOT_CREATED; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
_ri_idx += _ri_count; \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
#define _INIT_OBJ_RES_INST_OPT(_ri_ptr, _ri_idx, _ri_count, _ri_create) \
|
|
|
|
do { \
|
|
|
|
if (_ri_count > 0) { \
|
|
|
|
for (int _i = 0; _i < _ri_count; _i++) { \
|
|
|
|
_ri_ptr[_ri_idx + _i].data_ptr = NULL; \
|
2020-09-24 15:28:10 +02:00
|
|
|
_ri_ptr[_ri_idx + _i].max_data_len = 0; \
|
2019-07-29 10:09:00 -07:00
|
|
|
_ri_ptr[_ri_idx + _i].data_len = 0; \
|
|
|
|
if (_ri_create) { \
|
|
|
|
_ri_ptr[_ri_idx + _i].res_inst_id = \
|
|
|
|
_i; \
|
|
|
|
} else { \
|
|
|
|
_ri_ptr[_ri_idx + _i].res_inst_id = \
|
|
|
|
RES_INSTANCE_NOT_CREATED; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
_ri_idx += _ri_count; \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
#define INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
|
|
|
|
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
|
|
|
_data_ptr, _data_len, \
|
|
|
|
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
|
|
|
|
do { \
|
|
|
|
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
|
|
|
|
(_ri_ptr + _ri_idx), _ri_count, \
|
|
|
|
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb); \
|
|
|
|
_INIT_OBJ_RES_INST(_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
|
|
|
_data_ptr, _data_len); \
|
|
|
|
++_r_idx; \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
|
|
|
|
#define INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, \
|
|
|
|
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
|
|
|
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
|
|
|
|
do { \
|
|
|
|
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
|
|
|
|
(_ri_ptr + _ri_idx), _ri_count, \
|
|
|
|
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb); \
|
|
|
|
_INIT_OBJ_RES_INST_OPT(_ri_ptr, _ri_idx, _ri_count, _ri_create); \
|
|
|
|
++_r_idx; \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
#define INIT_OBJ_RES_MULTI_DATA(_id, _r_ptr, _r_idx, \
|
|
|
|
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
|
|
|
_data_ptr, _data_len) \
|
|
|
|
INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
|
|
|
|
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
|
|
|
_data_ptr, _data_len, NULL, NULL, NULL, NULL)
|
|
|
|
|
|
|
|
#define INIT_OBJ_RES_MULTI_OPTDATA(_id, _r_ptr, _r_idx, \
|
|
|
|
_ri_ptr, _ri_idx, _ri_count, _ri_create) \
|
|
|
|
INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, \
|
|
|
|
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
|
|
|
|
NULL, NULL, NULL, NULL)
|
|
|
|
|
|
|
|
#define INIT_OBJ_RES_DATA(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, \
|
|
|
|
_data_ptr, _data_len) \
|
|
|
|
INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, true, \
|
|
|
|
_data_ptr, _data_len, NULL, NULL, NULL, NULL)
|
|
|
|
|
|
|
|
#define INIT_OBJ_RES_OPTDATA(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx) \
|
|
|
|
INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, true, \
|
|
|
|
NULL, NULL, NULL, NULL)
|
|
|
|
|
|
|
|
#define INIT_OBJ_RES_EXECUTE(_id, _r_ptr, _r_idx, _ex_cb) \
|
|
|
|
do { \
|
|
|
|
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, NULL, 0, \
|
|
|
|
NULL, NULL, NULL, _ex_cb); \
|
|
|
|
++_r_idx; \
|
|
|
|
} while (false)
|
2017-07-07 11:04:03 -07:00
|
|
|
|
2017-11-24 18:47:00 +08:00
|
|
|
|
|
|
|
#define LWM2M_ATTR_PMIN 0
|
|
|
|
#define LWM2M_ATTR_PMAX 1
|
|
|
|
#define LWM2M_ATTR_GT 2
|
|
|
|
#define LWM2M_ATTR_LT 3
|
|
|
|
#define LWM2M_ATTR_STEP 4
|
|
|
|
#define NR_LWM2M_ATTR 5
|
|
|
|
|
|
|
|
/* TODO: support multiple server (sec 5.4.2) */
|
|
|
|
struct lwm2m_attr {
|
2018-05-07 15:05:04 -07:00
|
|
|
void *ref;
|
|
|
|
|
|
|
|
/* values */
|
2017-11-24 18:47:00 +08:00
|
|
|
union {
|
|
|
|
float32_value_t float_val;
|
2020-05-27 11:26:57 -05:00
|
|
|
int32_t int_val;
|
2017-11-24 18:47:00 +08:00
|
|
|
};
|
|
|
|
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t type;
|
2017-11-24 18:47:00 +08:00
|
|
|
};
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
struct lwm2m_engine_res_inst {
|
2018-05-07 13:33:48 -07:00
|
|
|
void *data_ptr;
|
2020-09-24 15:28:10 +02:00
|
|
|
uint16_t max_data_len;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t data_len;
|
|
|
|
uint16_t res_inst_id; /* 65535 == not "created" */
|
|
|
|
uint8_t data_flags;
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
2019-07-29 10:09:00 -07:00
|
|
|
struct lwm2m_engine_res {
|
|
|
|
lwm2m_engine_get_data_cb_t read_cb;
|
|
|
|
lwm2m_engine_get_data_cb_t pre_write_cb;
|
|
|
|
lwm2m_engine_set_data_cb_t post_write_cb;
|
|
|
|
lwm2m_engine_user_cb_t execute_cb;
|
|
|
|
|
|
|
|
struct lwm2m_engine_res_inst *res_instances;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t res_id;
|
|
|
|
uint8_t res_inst_count;
|
2019-07-29 10:09:00 -07:00
|
|
|
};
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
struct lwm2m_engine_obj_inst {
|
2018-05-07 13:33:48 -07:00
|
|
|
/* instance list */
|
2017-07-07 11:04:03 -07:00
|
|
|
sys_snode_t node;
|
2018-05-07 13:33:48 -07:00
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
struct lwm2m_engine_obj *obj;
|
2019-07-29 10:09:00 -07:00
|
|
|
struct lwm2m_engine_res *resources;
|
2017-11-24 18:47:00 +08:00
|
|
|
|
2018-05-07 13:33:48 -07:00
|
|
|
/* object instance member data */
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t obj_inst_id;
|
|
|
|
uint16_t resource_count;
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
2019-07-29 10:09:00 -07:00
|
|
|
/* Initialize resource instances prior to use */
|
|
|
|
static inline void init_res_instance(struct lwm2m_engine_res_inst *ri,
|
|
|
|
size_t ri_len)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
memset(ri, 0, sizeof(*ri) * ri_len);
|
|
|
|
for (i = 0; i < ri_len; i++) {
|
|
|
|
ri[i].res_inst_id = RES_INSTANCE_NOT_CREATED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-16 15:09:30 +02:00
|
|
|
struct lwm2m_opaque_context {
|
|
|
|
size_t len;
|
|
|
|
size_t remaining;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct lwm2m_block_context {
|
|
|
|
struct coap_block_context ctx;
|
|
|
|
struct lwm2m_opaque_context opaque;
|
|
|
|
int64_t timestamp;
|
|
|
|
uint32_t expected;
|
|
|
|
uint8_t token[8];
|
|
|
|
uint8_t tkl;
|
|
|
|
bool last_block : 1;
|
|
|
|
};
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
struct lwm2m_output_context {
|
|
|
|
const struct lwm2m_writer *writer;
|
2017-10-19 16:27:32 -07:00
|
|
|
struct coap_packet *out_cpkt;
|
|
|
|
|
2018-08-29 13:51:17 -07:00
|
|
|
/* private output data */
|
|
|
|
void *user_data;
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct lwm2m_input_context {
|
|
|
|
const struct lwm2m_reader *reader;
|
2017-10-19 16:27:32 -07:00
|
|
|
struct coap_packet *in_cpkt;
|
|
|
|
|
2019-01-25 14:13:07 -08:00
|
|
|
/* current position in buffer */
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t offset;
|
2017-10-19 16:27:32 -07:00
|
|
|
|
2020-09-16 15:09:30 +02:00
|
|
|
/* Corresponding block context. NULL if block transfer is not used. */
|
|
|
|
struct lwm2m_block_context *block_ctx;
|
2019-01-25 15:45:14 -08:00
|
|
|
|
|
|
|
/* private output data */
|
|
|
|
void *user_data;
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
2019-01-24 14:40:23 -08:00
|
|
|
/* Establish a message timeout callback */
|
|
|
|
typedef void (*lwm2m_message_timeout_cb_t)(struct lwm2m_message *msg);
|
|
|
|
|
|
|
|
/* Internal LwM2M message structure to track in-flight messages. */
|
|
|
|
struct lwm2m_message {
|
|
|
|
/** LwM2M context related to this message */
|
|
|
|
struct lwm2m_ctx *ctx;
|
|
|
|
|
|
|
|
/** Incoming / outgoing contexts */
|
|
|
|
struct lwm2m_input_context in;
|
|
|
|
struct lwm2m_output_context out;
|
|
|
|
|
|
|
|
/** Incoming path */
|
|
|
|
struct lwm2m_obj_path path;
|
|
|
|
|
|
|
|
/** CoAP packet data related to the outgoing message */
|
|
|
|
struct coap_packet cpkt;
|
|
|
|
|
2019-01-25 14:13:07 -08:00
|
|
|
/** Buffer data related outgoing message */
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t msg_data[MAX_PACKET_SIZE];
|
2019-01-25 14:13:07 -08:00
|
|
|
|
2019-01-24 14:40:23 -08:00
|
|
|
/** Message transmission handling for TYPE_CON */
|
|
|
|
struct coap_pending *pending;
|
|
|
|
struct coap_reply *reply;
|
|
|
|
|
|
|
|
/** Message configuration */
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *token;
|
2019-01-24 14:40:23 -08:00
|
|
|
coap_reply_t reply_cb;
|
|
|
|
lwm2m_message_timeout_cb_t message_timeout_cb;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t mid;
|
|
|
|
uint8_t type;
|
|
|
|
uint8_t code;
|
|
|
|
uint8_t tkl;
|
2019-01-24 14:40:23 -08:00
|
|
|
|
|
|
|
/** Incoming message action */
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t operation;
|
2019-01-24 14:40:23 -08:00
|
|
|
|
|
|
|
/** Counter for message re-send / abort handling */
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t send_attempts;
|
2020-10-13 14:10:55 +02:00
|
|
|
|
|
|
|
/* Information whether the message was acknowledged. */
|
|
|
|
bool acknowledged : 1;
|
2019-01-24 14:40:23 -08:00
|
|
|
};
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
/* LWM2M format writer for the various formats supported */
|
|
|
|
struct lwm2m_writer {
|
|
|
|
size_t (*put_begin)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path);
|
|
|
|
size_t (*put_end)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path);
|
2018-08-29 14:26:24 -07:00
|
|
|
size_t (*put_begin_oi)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path);
|
|
|
|
size_t (*put_end_oi)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path);
|
|
|
|
size_t (*put_begin_r)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path);
|
|
|
|
size_t (*put_end_r)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*put_begin_ri)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path);
|
|
|
|
size_t (*put_end_ri)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path);
|
|
|
|
size_t (*put_s8)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2020-05-27 11:26:57 -05:00
|
|
|
int8_t value);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*put_s16)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2020-05-27 11:26:57 -05:00
|
|
|
int16_t value);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*put_s32)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2020-05-27 11:26:57 -05:00
|
|
|
int32_t value);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*put_s64)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2020-05-27 11:26:57 -05:00
|
|
|
int64_t value);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*put_string)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2017-10-11 12:48:06 -07:00
|
|
|
char *buf, size_t buflen);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*put_float32fix)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
float32_value_t *value);
|
|
|
|
size_t (*put_float64fix)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
float64_value_t *value);
|
|
|
|
size_t (*put_bool)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
bool value);
|
2017-10-26 23:32:47 -07:00
|
|
|
size_t (*put_opaque)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
char *buf, size_t buflen);
|
2020-05-19 12:37:02 +02:00
|
|
|
size_t (*put_objlnk)(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
struct lwm2m_objlnk *value);
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct lwm2m_reader {
|
|
|
|
size_t (*get_s32)(struct lwm2m_input_context *in,
|
2020-05-27 11:26:57 -05:00
|
|
|
int32_t *value);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*get_s64)(struct lwm2m_input_context *in,
|
2020-05-27 11:26:57 -05:00
|
|
|
int64_t *value);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*get_string)(struct lwm2m_input_context *in,
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *buf, size_t buflen);
|
2017-07-07 11:04:03 -07:00
|
|
|
size_t (*get_float32fix)(struct lwm2m_input_context *in,
|
|
|
|
float32_value_t *value);
|
|
|
|
size_t (*get_float64fix)(struct lwm2m_input_context *in,
|
|
|
|
float64_value_t *value);
|
|
|
|
size_t (*get_bool)(struct lwm2m_input_context *in,
|
|
|
|
bool *value);
|
2017-10-26 23:32:47 -07:00
|
|
|
size_t (*get_opaque)(struct lwm2m_input_context *in,
|
2020-09-16 15:09:30 +02:00
|
|
|
uint8_t *buf, size_t buflen,
|
|
|
|
struct lwm2m_opaque_context *opaque,
|
|
|
|
bool *last_block);
|
2020-05-19 12:37:02 +02:00
|
|
|
size_t (*get_objlnk)(struct lwm2m_input_context *in,
|
|
|
|
struct lwm2m_objlnk *value);
|
2017-07-07 11:04:03 -07:00
|
|
|
};
|
|
|
|
|
2018-08-29 13:51:17 -07:00
|
|
|
/* output user_data management functions */
|
|
|
|
|
|
|
|
static inline void engine_set_out_user_data(struct lwm2m_output_context *out,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
out->user_data = user_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void *engine_get_out_user_data(struct lwm2m_output_context *out)
|
|
|
|
{
|
|
|
|
return out->user_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
engine_clear_out_user_data(struct lwm2m_output_context *out)
|
|
|
|
{
|
|
|
|
out->user_data = NULL;
|
|
|
|
}
|
|
|
|
|
2019-01-25 15:45:14 -08:00
|
|
|
static inline void engine_set_in_user_data(struct lwm2m_input_context *in,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
in->user_data = user_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void *engine_get_in_user_data(struct lwm2m_input_context *in)
|
|
|
|
{
|
|
|
|
return in->user_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
engine_clear_in_user_data(struct lwm2m_input_context *in)
|
|
|
|
{
|
|
|
|
in->user_data = NULL;
|
|
|
|
}
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
/* inline multi-format write / read functions */
|
|
|
|
|
|
|
|
static inline size_t engine_put_begin(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path)
|
|
|
|
{
|
|
|
|
if (out->writer->put_begin) {
|
|
|
|
return out->writer->put_begin(out, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_end(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path)
|
|
|
|
{
|
|
|
|
if (out->writer->put_end) {
|
|
|
|
return out->writer->put_end(out, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-08-29 14:26:24 -07:00
|
|
|
static inline size_t engine_put_begin_oi(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path)
|
|
|
|
{
|
|
|
|
if (out->writer->put_begin_oi) {
|
|
|
|
return out->writer->put_begin_oi(out, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_end_oi(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path)
|
|
|
|
{
|
|
|
|
if (out->writer->put_end_oi) {
|
|
|
|
return out->writer->put_end_oi(out, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_begin_r(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path)
|
|
|
|
{
|
|
|
|
if (out->writer->put_begin_r) {
|
|
|
|
return out->writer->put_begin_r(out, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_end_r(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path)
|
|
|
|
{
|
|
|
|
if (out->writer->put_end_r) {
|
|
|
|
return out->writer->put_end_r(out, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
static inline size_t engine_put_begin_ri(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path)
|
|
|
|
{
|
|
|
|
if (out->writer->put_begin_ri) {
|
|
|
|
return out->writer->put_begin_ri(out, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_end_ri(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path)
|
|
|
|
{
|
|
|
|
if (out->writer->put_end_ri) {
|
|
|
|
return out->writer->put_end_ri(out, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_s8(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2020-05-27 11:26:57 -05:00
|
|
|
int8_t value)
|
2017-07-07 11:04:03 -07:00
|
|
|
{
|
|
|
|
return out->writer->put_s8(out, path, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_s16(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2020-05-27 11:26:57 -05:00
|
|
|
int16_t value)
|
2017-07-07 11:04:03 -07:00
|
|
|
{
|
|
|
|
return out->writer->put_s16(out, path, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_s32(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2020-05-27 11:26:57 -05:00
|
|
|
int32_t value)
|
2017-07-07 11:04:03 -07:00
|
|
|
{
|
|
|
|
return out->writer->put_s32(out, path, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_s64(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2020-05-27 11:26:57 -05:00
|
|
|
int64_t value)
|
2017-07-07 11:04:03 -07:00
|
|
|
{
|
|
|
|
return out->writer->put_s64(out, path, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_string(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
2017-10-11 12:48:06 -07:00
|
|
|
char *buf, size_t buflen)
|
2017-07-07 11:04:03 -07:00
|
|
|
{
|
2017-10-11 12:48:06 -07:00
|
|
|
return out->writer->put_string(out, path, buf, buflen);
|
2017-07-07 11:04:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_float32fix(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
float32_value_t *value)
|
|
|
|
{
|
|
|
|
return out->writer->put_float32fix(out, path, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_float64fix(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
float64_value_t *value)
|
|
|
|
{
|
|
|
|
return out->writer->put_float64fix(out, path, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_put_bool(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
bool value)
|
|
|
|
{
|
|
|
|
return out->writer->put_bool(out, path, value);
|
|
|
|
}
|
|
|
|
|
2017-10-26 23:32:47 -07:00
|
|
|
static inline size_t engine_put_opaque(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
char *buf, size_t buflen)
|
|
|
|
{
|
|
|
|
if (out->writer->put_opaque) {
|
|
|
|
return out->writer->put_opaque(out, path, buf, buflen);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-19 12:37:02 +02:00
|
|
|
static inline size_t engine_put_objlnk(struct lwm2m_output_context *out,
|
|
|
|
struct lwm2m_obj_path *path,
|
|
|
|
struct lwm2m_objlnk *value)
|
|
|
|
{
|
|
|
|
return out->writer->put_objlnk(out, path, value);
|
|
|
|
}
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
static inline size_t engine_get_s32(struct lwm2m_input_context *in,
|
2020-05-27 11:26:57 -05:00
|
|
|
int32_t *value)
|
2017-07-07 11:04:03 -07:00
|
|
|
{
|
|
|
|
return in->reader->get_s32(in, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_get_s64(struct lwm2m_input_context *in,
|
2020-05-27 11:26:57 -05:00
|
|
|
int64_t *value)
|
2017-07-07 11:04:03 -07:00
|
|
|
{
|
|
|
|
return in->reader->get_s64(in, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_get_string(struct lwm2m_input_context *in,
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *buf, size_t buflen)
|
2017-07-07 11:04:03 -07:00
|
|
|
{
|
2017-10-11 12:48:06 -07:00
|
|
|
return in->reader->get_string(in, buf, buflen);
|
2017-07-07 11:04:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_get_float32fix(struct lwm2m_input_context *in,
|
|
|
|
float32_value_t *value)
|
|
|
|
{
|
|
|
|
return in->reader->get_float32fix(in, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_get_float64fix(struct lwm2m_input_context *in,
|
|
|
|
float64_value_t *value)
|
|
|
|
{
|
|
|
|
return in->reader->get_float64fix(in, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline size_t engine_get_bool(struct lwm2m_input_context *in,
|
|
|
|
bool *value)
|
|
|
|
{
|
|
|
|
return in->reader->get_bool(in, value);
|
|
|
|
}
|
|
|
|
|
2017-10-26 23:32:47 -07:00
|
|
|
static inline size_t engine_get_opaque(struct lwm2m_input_context *in,
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *buf, size_t buflen,
|
2020-09-16 15:09:30 +02:00
|
|
|
struct lwm2m_opaque_context *opaque,
|
2017-10-26 23:32:47 -07:00
|
|
|
bool *last_block)
|
|
|
|
{
|
|
|
|
if (in->reader->get_opaque) {
|
2020-09-16 15:09:30 +02:00
|
|
|
return in->reader->get_opaque(in, buf, buflen,
|
|
|
|
opaque, last_block);
|
2017-10-26 23:32:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-19 12:37:02 +02:00
|
|
|
static inline size_t engine_get_objlnk(struct lwm2m_input_context *in,
|
|
|
|
struct lwm2m_objlnk *value)
|
|
|
|
{
|
|
|
|
return in->reader->get_objlnk(in, value);
|
|
|
|
}
|
|
|
|
|
2017-07-07 11:04:03 -07:00
|
|
|
#endif /* LWM2M_OBJECT_H_ */
|