net: lwm2m: add write-attribute WRITE support
Implement write-attribute on obj/obj_inst/res according to LwM2M spec 20170704-A, sec 5.1.2. Support pmin/pmax/st/gt/lt parameters on WRITE operation. The basic idea is to add sys_slist_t to obj/obj_inst/res structure. And attach struct lwm2m_attr to the list when attributes are written from server side (implement lwm2m_write_attr_handler accordingly) Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
This commit is contained in:
parent
ff22595c31
commit
09fcd83b98
3 changed files with 381 additions and 3 deletions
|
@ -179,6 +179,13 @@ config LWM2M_DEVICE_ERROR_CODE_MAX
|
||||||
This value sets the maximum number of error codes that the device
|
This value sets the maximum number of error codes that the device
|
||||||
object will store before ignoring new values.
|
object will store before ignoring new values.
|
||||||
|
|
||||||
|
config LWM2M_NUM_ATTR
|
||||||
|
int "Maximum # of LWM2M attributes"
|
||||||
|
default 20
|
||||||
|
help
|
||||||
|
This value sets up the maximum number of LwM2M attributes that
|
||||||
|
we can handle at the same time.
|
||||||
|
|
||||||
menu "IPSO Alliance Smart Object Support"
|
menu "IPSO Alliance Smart Object Support"
|
||||||
|
|
||||||
source "subsys/net/lib/lwm2m/Kconfig.ipso"
|
source "subsys/net/lib/lwm2m/Kconfig.ipso"
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -80,6 +81,12 @@
|
||||||
#define INSTANCE_INFO "Zephyr DTLS LwM2M-client"
|
#define INSTANCE_INFO "Zephyr DTLS LwM2M-client"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_COAP_EXTENDED_OPTIONS_LEN)
|
||||||
|
#define COAP_OPTION_BUF_LEN (CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE + 1)
|
||||||
|
#else
|
||||||
|
#define COAP_OPTION_BUF_LEN 13
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_TOKEN_LEN 8
|
#define MAX_TOKEN_LEN 8
|
||||||
|
|
||||||
struct observe_node {
|
struct observe_node {
|
||||||
|
@ -133,6 +140,13 @@ struct block_context {
|
||||||
|
|
||||||
static struct block_context block1_contexts[NUM_BLOCK1_CONTEXT];
|
static struct block_context block1_contexts[NUM_BLOCK1_CONTEXT];
|
||||||
|
|
||||||
|
/* write-attribute related definitons */
|
||||||
|
static const char * const LWM2M_ATTR_STR[] = { "pmin", "pmax",
|
||||||
|
"gt", "lt", "st" };
|
||||||
|
static const u8_t LWM2M_ATTR_LEN[] = { 4, 4, 2, 2, 2 };
|
||||||
|
|
||||||
|
static struct lwm2m_attr write_attr_pool[CONFIG_LWM2M_NUM_ATTR];
|
||||||
|
|
||||||
/* periodic / notify / observe handling stack */
|
/* periodic / notify / observe handling stack */
|
||||||
static K_THREAD_STACK_DEFINE(engine_thread_stack,
|
static K_THREAD_STACK_DEFINE(engine_thread_stack,
|
||||||
CONFIG_LWM2M_ENGINE_STACK_SIZE);
|
CONFIG_LWM2M_ENGINE_STACK_SIZE);
|
||||||
|
@ -288,6 +302,50 @@ static void free_block_ctx(struct block_context *ctx)
|
||||||
|
|
||||||
/* observer functions */
|
/* observer functions */
|
||||||
|
|
||||||
|
struct notification_attrs {
|
||||||
|
/* use to determine which value is set */
|
||||||
|
u8_t flags;
|
||||||
|
float32_value_t gt;
|
||||||
|
float32_value_t lt;
|
||||||
|
float32_value_t st;
|
||||||
|
s32_t pmin;
|
||||||
|
s32_t pmax;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int update_attrs(sys_slist_t *list, struct notification_attrs *out)
|
||||||
|
{
|
||||||
|
struct lwm2m_attr *attr;
|
||||||
|
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER(list, attr, node) {
|
||||||
|
switch (attr->type) {
|
||||||
|
case LWM2M_ATTR_PMIN:
|
||||||
|
out->pmin = attr->int_val;
|
||||||
|
break;
|
||||||
|
case LWM2M_ATTR_PMAX:
|
||||||
|
out->pmax = attr->int_val;
|
||||||
|
break;
|
||||||
|
case LWM2M_ATTR_LT:
|
||||||
|
out->lt = attr->float_val;
|
||||||
|
break;
|
||||||
|
case LWM2M_ATTR_GT:
|
||||||
|
out->gt = attr->float_val;
|
||||||
|
break;
|
||||||
|
case LWM2M_ATTR_STEP:
|
||||||
|
out->st = attr->float_val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SYS_LOG_ERR("Unrecognize attr: %d",
|
||||||
|
attr->type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mark as set */
|
||||||
|
out->flags |= BIT(attr->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int lwm2m_notify_observer(u16_t obj_id, u16_t obj_inst_id, u16_t res_id)
|
int lwm2m_notify_observer(u16_t obj_id, u16_t obj_inst_id, u16_t res_id)
|
||||||
{
|
{
|
||||||
struct observe_node *obs;
|
struct observe_node *obs;
|
||||||
|
@ -625,6 +683,8 @@ int lwm2m_delete_obj_inst(u16_t obj_id, u16_t obj_inst_id)
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
struct lwm2m_engine_obj *obj;
|
struct lwm2m_engine_obj *obj;
|
||||||
struct lwm2m_engine_obj_inst *obj_inst;
|
struct lwm2m_engine_obj_inst *obj_inst;
|
||||||
|
struct lwm2m_attr *attr, *tmp;
|
||||||
|
sys_snode_t *prev_node = NULL;
|
||||||
|
|
||||||
obj = get_engine_obj(obj_id);
|
obj = get_engine_obj(obj_id);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
|
@ -645,10 +705,25 @@ int lwm2m_delete_obj_inst(u16_t obj_id, u16_t obj_inst_id)
|
||||||
|
|
||||||
/* reset obj_inst and res_inst data structure */
|
/* reset obj_inst and res_inst data structure */
|
||||||
for (i = 0; i < obj_inst->resource_count; i++) {
|
for (i = 0; i < obj_inst->resource_count; i++) {
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(
|
||||||
|
&obj_inst->resources[i].attr_list, attr,
|
||||||
|
tmp, node) {
|
||||||
|
sys_slist_remove(&obj_inst->resources[i].attr_list,
|
||||||
|
prev_node, &attr->node);
|
||||||
|
memset(attr, 0, sizeof(*attr));
|
||||||
|
}
|
||||||
|
|
||||||
memset(obj_inst->resources + i, 0,
|
memset(obj_inst->resources + i, 0,
|
||||||
sizeof(struct lwm2m_engine_res_inst));
|
sizeof(struct lwm2m_engine_res_inst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(
|
||||||
|
&obj_inst->attr_list, attr, tmp, node) {
|
||||||
|
sys_slist_remove(&obj_inst->attr_list, prev_node,
|
||||||
|
&attr->node);
|
||||||
|
memset(attr, 0, sizeof(*attr));
|
||||||
|
}
|
||||||
|
|
||||||
memset(obj_inst, 0, sizeof(struct lwm2m_engine_obj_inst));
|
memset(obj_inst, 0, sizeof(struct lwm2m_engine_obj_inst));
|
||||||
#ifdef CONFIG_LWM2M_RD_CLIENT_SUPPORT
|
#ifdef CONFIG_LWM2M_RD_CLIENT_SUPPORT
|
||||||
engine_trigger_update();
|
engine_trigger_update();
|
||||||
|
@ -704,6 +779,50 @@ static u16_t atou16(u8_t *buf, u16_t buflen, u16_t *len)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int atof32(const char *input, float32_value_t *out)
|
||||||
|
{
|
||||||
|
char *pos, *end, buf[24];
|
||||||
|
long int val;
|
||||||
|
s32_t base = 1000000, sign = 1;
|
||||||
|
|
||||||
|
if (!input || !out) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(buf, input, sizeof(buf) - 1);
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
|
||||||
|
if (strchr(buf, '-')) {
|
||||||
|
sign = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = strchr(buf, '.');
|
||||||
|
if (pos) {
|
||||||
|
*pos = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
val = strtol(buf, &end, 10);
|
||||||
|
if (errno || *end || val > INT_MAX || val < INT_MIN) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->val1 = (s32_t) val;
|
||||||
|
out->val2 = 0;
|
||||||
|
|
||||||
|
if (!pos) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*(++pos) && base > 1 && isdigit(*pos)) {
|
||||||
|
out->val2 = out->val2 * 10 + (*pos - '0');
|
||||||
|
base /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->val2 *= sign * base;
|
||||||
|
return !*pos || base == 1 ? 0 : -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static int coap_options_to_path(struct coap_option *opt, int options_count,
|
static int coap_options_to_path(struct coap_option *opt, int options_count,
|
||||||
struct lwm2m_obj_path *path)
|
struct lwm2m_obj_path *path)
|
||||||
{
|
{
|
||||||
|
@ -2072,13 +2191,237 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
|
||||||
static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
static int lwm2m_write_attr_handler(struct lwm2m_engine_obj *obj,
|
||||||
struct lwm2m_engine_context *context)
|
struct lwm2m_engine_context *context)
|
||||||
{
|
{
|
||||||
|
char opt_buf[COAP_OPTION_BUF_LEN];
|
||||||
|
int nr_opt, ret = 0;
|
||||||
|
struct coap_option options[NR_LWM2M_ATTR];
|
||||||
|
struct lwm2m_engine_obj_inst *obj_inst = NULL;
|
||||||
|
struct lwm2m_engine_res_inst *res = NULL;
|
||||||
|
struct lwm2m_input_context *in;
|
||||||
|
struct lwm2m_obj_path *path;
|
||||||
|
struct lwm2m_attr *attr, *tmp;
|
||||||
|
struct notification_attrs nattrs = { 0 };
|
||||||
|
sys_slist_t *attr_list;
|
||||||
|
sys_snode_t *prev_node = NULL;
|
||||||
|
u8_t type = 0;
|
||||||
|
void *nattr_ptrs[NR_LWM2M_ATTR] = {
|
||||||
|
&nattrs.pmin, &nattrs.pmax, &nattrs.gt, &nattrs.lt, &nattrs.st
|
||||||
|
};
|
||||||
|
|
||||||
if (!obj || !context) {
|
if (!obj || !context) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: set parameters on resource for notification */
|
/* do not expose security obj */
|
||||||
|
if (obj->obj_id == LWM2M_OBJECT_SECURITY_ID) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
return -ENOTSUP;
|
in = context->in;
|
||||||
|
path = context->path;
|
||||||
|
|
||||||
|
nr_opt = coap_find_options(in->in_cpkt, COAP_OPTION_URI_QUERY,
|
||||||
|
options, NR_LWM2M_ATTR);
|
||||||
|
if (nr_opt <= 0) {
|
||||||
|
SYS_LOG_ERR("No attribute found!");
|
||||||
|
/* translate as bad request */
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get lwm2m_attr slist */
|
||||||
|
if (path->level == 3) {
|
||||||
|
ret = engine_get_resource(path, &res);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_list = &res->attr_list;
|
||||||
|
} else if (path->level == 1) {
|
||||||
|
attr_list = &obj->attr_list;
|
||||||
|
} else if (path->level == 2) {
|
||||||
|
obj_inst = get_engine_obj_inst(path->obj_id, path->obj_inst_id);
|
||||||
|
if (!obj_inst) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_list = &obj_inst->attr_list;
|
||||||
|
} else {
|
||||||
|
/* bad request */
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* retrieve existing attributes */
|
||||||
|
update_attrs(attr_list, &nattrs);
|
||||||
|
|
||||||
|
/* loop through options to parse attribute */
|
||||||
|
for (int i = 0; i < nr_opt; i++) {
|
||||||
|
int limit = min(options[i].len, 5), plen = 0, vlen;
|
||||||
|
float32_value_t val = { 0 };
|
||||||
|
type = 0;
|
||||||
|
|
||||||
|
/* search for '=' */
|
||||||
|
while (plen < limit && options[i].value[plen] != '=') {
|
||||||
|
plen += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* either length = 2(gt/lt/st) or = 4(pmin/pmax) */
|
||||||
|
if (plen != 2 && plen != 4) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* matching attribute name */
|
||||||
|
for (type = 0; type < NR_LWM2M_ATTR; type++) {
|
||||||
|
if (LWM2M_ATTR_LEN[type] == plen &&
|
||||||
|
!memcmp(options[i].value, LWM2M_ATTR_STR[type],
|
||||||
|
LWM2M_ATTR_LEN[type])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unrecognized attribute */
|
||||||
|
if (type == NR_LWM2M_ATTR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unset attribute when no value's given */
|
||||||
|
if (options[i].len == plen) {
|
||||||
|
nattrs.flags &= ~BIT(type);
|
||||||
|
|
||||||
|
memset(nattr_ptrs[type], 0,
|
||||||
|
type <= LWM2M_ATTR_PMAX ?
|
||||||
|
sizeof(s32_t) : sizeof(float32_value_t));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gt/lt/st cannot be assigned to obj/obj_inst unless unset */
|
||||||
|
if (plen == 2 && path->level <= 2) {
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlen = options[i].len - plen - 1;
|
||||||
|
memcpy(opt_buf, options[i].value + plen + 1, vlen);
|
||||||
|
opt_buf[vlen] = '\0';
|
||||||
|
|
||||||
|
/* convert value to integer or float */
|
||||||
|
if (plen == 4) {
|
||||||
|
char *end;
|
||||||
|
long int v;
|
||||||
|
|
||||||
|
/* pmin/pmax: integer (sec 5.1.2)
|
||||||
|
* however, negative is non-sense
|
||||||
|
*/
|
||||||
|
errno = 0;
|
||||||
|
v = strtol(opt_buf, &end, 10);
|
||||||
|
if (errno || *end || v > INT_MAX || v < 0) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
val.val1 = v;
|
||||||
|
} else {
|
||||||
|
/* gt/lt/st: type float */
|
||||||
|
ret = atof32(opt_buf, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
SYS_LOG_ERR("invalid attr[%s] value",
|
||||||
|
LWM2M_ATTR_STR[type]);
|
||||||
|
/* bad request */
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type <= LWM2M_ATTR_PMAX) {
|
||||||
|
*(s32_t *)nattr_ptrs[type] = val.val1;
|
||||||
|
} else {
|
||||||
|
memcpy(nattr_ptrs[type], &val, sizeof(float32_value_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
nattrs.flags |= BIT(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nattrs.flags & (BIT(LWM2M_ATTR_PMIN) | BIT(LWM2M_ATTR_PMAX))) &&
|
||||||
|
nattrs.pmin > nattrs.pmax) {
|
||||||
|
SYS_LOG_DBG("pmin (%d) > pmax (%d)", nattrs.pmin, nattrs.pmax);
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nattrs.flags & (BIT(LWM2M_ATTR_LT) | BIT(LWM2M_ATTR_GT))) {
|
||||||
|
if (!((nattrs.lt.val1 < nattrs.gt.val1) ||
|
||||||
|
(nattrs.lt.val2 < nattrs.gt.val2))) {
|
||||||
|
SYS_LOG_DBG("lt > gt");
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nattrs.flags & BIT(LWM2M_ATTR_STEP)) {
|
||||||
|
s32_t st1 = nattrs.st.val1 * 2 +
|
||||||
|
nattrs.st.val2 * 2 / 1000000;
|
||||||
|
s32_t st2 = nattrs.st.val2 * 2 % 1000000;
|
||||||
|
if (!(((nattrs.lt.val1 + st1) < nattrs.gt.val1) ||
|
||||||
|
((nattrs.lt.val2 + st2) < nattrs.gt.val2))) {
|
||||||
|
SYS_LOG_DBG("lt + 2*st > gt");
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(attr_list, attr, tmp, node) {
|
||||||
|
type = attr->type;
|
||||||
|
|
||||||
|
if (!(BIT(type) & nattrs.flags)) {
|
||||||
|
SYS_LOG_DBG("Unset attr %s", LWM2M_ATTR_STR[type]);
|
||||||
|
sys_slist_remove(attr_list, prev_node, &attr->node);
|
||||||
|
memset(attr, 0, sizeof(*attr));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_node = &attr->node;
|
||||||
|
nattrs.flags &= ~BIT(type);
|
||||||
|
|
||||||
|
if (type <= LWM2M_ATTR_PMAX) {
|
||||||
|
attr->int_val = *(s32_t *)nattr_ptrs[type];
|
||||||
|
} else {
|
||||||
|
memcpy(&attr->float_val, nattr_ptrs[type],
|
||||||
|
sizeof(float32_value_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_LOG_DBG("Update %s to %d.%06d", LWM2M_ATTR_STR[type],
|
||||||
|
attr->float_val.val1, attr->float_val.val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add attribute to obj/obj_inst/res */
|
||||||
|
for (type = 0; nattrs.flags && type < NR_LWM2M_ATTR; type++) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!(BIT(type) & nattrs.flags)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grab an entry for newly added attribute */
|
||||||
|
for (i = 0; i < CONFIG_LWM2M_NUM_ATTR; i++) {
|
||||||
|
if (!write_attr_pool[i].used) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == CONFIG_LWM2M_NUM_ATTR) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr = write_attr_pool + i;
|
||||||
|
attr->type = type;
|
||||||
|
attr->used = true;
|
||||||
|
if (type <= LWM2M_ATTR_PMAX) {
|
||||||
|
attr->int_val = *(s32_t *)nattr_ptrs[type];
|
||||||
|
} else {
|
||||||
|
memcpy(&attr->float_val, nattr_ptrs[type],
|
||||||
|
sizeof(float32_value_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_slist_append(attr_list, &attr->node);
|
||||||
|
nattrs.flags &= ~BIT(type);
|
||||||
|
SYS_LOG_DBG("Add %s to %d.%06d", LWM2M_ATTR_STR[type],
|
||||||
|
attr->float_val.val1, attr->float_val.val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lwm2m_exec_handler(struct lwm2m_engine_obj *obj,
|
static int lwm2m_exec_handler(struct lwm2m_engine_obj *obj,
|
||||||
|
|
|
@ -150,6 +150,9 @@ struct lwm2m_engine_obj {
|
||||||
u16_t max_instance_count;
|
u16_t max_instance_count;
|
||||||
lwm2m_engine_obj_create_cb_t create_cb;
|
lwm2m_engine_obj_create_cb_t create_cb;
|
||||||
lwm2m_engine_obj_delete_cb_t delete_cb;
|
lwm2m_engine_obj_delete_cb_t delete_cb;
|
||||||
|
|
||||||
|
/* runtime field attributes (lwm2m_attr) */
|
||||||
|
sys_slist_t attr_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_OBJ_RES(res_var, index_var, id_val, multi_var, \
|
#define INIT_OBJ_RES(res_var, index_var, id_val, multi_var, \
|
||||||
|
@ -179,13 +182,35 @@ struct lwm2m_engine_obj {
|
||||||
INIT_OBJ_RES(res_var, index_var, id_val, NULL, NULL, 0, \
|
INIT_OBJ_RES(res_var, index_var, id_val, NULL, NULL, 0, \
|
||||||
NULL, NULL, NULL, ex_cb)
|
NULL, NULL, NULL, ex_cb)
|
||||||
|
|
||||||
|
|
||||||
|
#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 {
|
||||||
|
union {
|
||||||
|
float32_value_t float_val;
|
||||||
|
s32_t int_val;
|
||||||
|
};
|
||||||
|
|
||||||
|
sys_snode_t node;
|
||||||
|
u8_t type;
|
||||||
|
bool used;
|
||||||
|
};
|
||||||
|
|
||||||
struct lwm2m_engine_res_inst {
|
struct lwm2m_engine_res_inst {
|
||||||
char path[MAX_RESOURCE_LEN]; /* 3/0/0 */
|
char path[MAX_RESOURCE_LEN]; /* 3/0/0 */
|
||||||
u16_t res_id;
|
u16_t res_id;
|
||||||
u8_t *multi_count_var;
|
u8_t *multi_count_var;
|
||||||
void *data_ptr;
|
void *data_ptr;
|
||||||
size_t data_len;
|
size_t data_len;
|
||||||
/* runtime field attributes (WRITE_ATTR) */
|
|
||||||
|
/* runtime field attributes (lwm2m_attr) */
|
||||||
|
sys_slist_t attr_list;
|
||||||
|
|
||||||
/* callbacks set by user code on obj instance */
|
/* callbacks set by user code on obj instance */
|
||||||
lwm2m_engine_get_data_cb_t read_cb;
|
lwm2m_engine_get_data_cb_t read_cb;
|
||||||
|
@ -201,6 +226,9 @@ struct lwm2m_engine_obj_inst {
|
||||||
u16_t obj_inst_id;
|
u16_t obj_inst_id;
|
||||||
struct lwm2m_engine_res_inst *resources;
|
struct lwm2m_engine_res_inst *resources;
|
||||||
u16_t resource_count;
|
u16_t resource_count;
|
||||||
|
|
||||||
|
/* runtime field attributes (lwm2m_attr) */
|
||||||
|
sys_slist_t attr_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lwm2m_output_context {
|
struct lwm2m_output_context {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue