1 /*
2 * Copyright (c) 2017 Linaro Limited
3 * Copyright (c) 2018-2019 Foundries.io
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /*
9 * Copyright (c) 2015, Yanzi Networks AB.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the copyright holder nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35 * OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 /*
39 * Original Authors:
40 * Joakim Eriksson <joakime@sics.se>
41 * Niclas Finne <nfi@sics.se>
42 */
43
44 #ifndef LWM2M_OBJECT_H_
45 #define LWM2M_OBJECT_H_
46
47 /* stdint conversions */
48 #include <zephyr/types.h>
49 #include <stddef.h>
50 #include <kernel.h>
51
52 #include <net/net_ip.h>
53 #include <sys/printk.h>
54 #include <sys/util.h>
55 #include <sys/types.h>
56
57 #include <net/coap.h>
58 #include <net/lwm2m.h>
59
60 #include "buf_util.h"
61
62 /* #####/###/#####/### + NULL */
63 #define MAX_RESOURCE_LEN 20
64
65 /* operations / permissions */
66 /* values from 0 to 7 can be used as permission checks */
67 #define LWM2M_OP_READ 0
68 #define LWM2M_OP_WRITE 1
69 #define LWM2M_OP_CREATE 2
70 #define LWM2M_OP_DELETE 3
71 #define LWM2M_OP_EXECUTE 4
72 #define LWM2M_FLAG_OPTIONAL 7
73 /* values >7 aren't used for permission checks */
74 #define LWM2M_OP_DISCOVER 8
75 #define LWM2M_OP_WRITE_ATTR 9
76
77 /* resource permissions */
78 #define LWM2M_PERM_R BIT(LWM2M_OP_READ)
79 #define LWM2M_PERM_R_OPT (BIT(LWM2M_OP_READ) | \
80 BIT(LWM2M_FLAG_OPTIONAL))
81 #define LWM2M_PERM_W (BIT(LWM2M_OP_WRITE) | \
82 BIT(LWM2M_OP_CREATE))
83 #define LWM2M_PERM_W_OPT (BIT(LWM2M_OP_WRITE) | \
84 BIT(LWM2M_OP_CREATE) | \
85 BIT(LWM2M_FLAG_OPTIONAL))
86 #define LWM2M_PERM_X BIT(LWM2M_OP_EXECUTE)
87 #define LWM2M_PERM_X_OPT (BIT(LWM2M_OP_EXECUTE) | \
88 BIT(LWM2M_FLAG_OPTIONAL))
89 #define LWM2M_PERM_RW (BIT(LWM2M_OP_READ) | \
90 BIT(LWM2M_OP_WRITE) | \
91 BIT(LWM2M_OP_CREATE))
92 #define LWM2M_PERM_RW_OPT (BIT(LWM2M_OP_READ) | \
93 BIT(LWM2M_OP_WRITE) | \
94 BIT(LWM2M_OP_CREATE) | \
95 BIT(LWM2M_FLAG_OPTIONAL))
96 #define LWM2M_PERM_RWX (BIT(LWM2M_OP_READ) | \
97 BIT(LWM2M_OP_WRITE) | \
98 BIT(LWM2M_OP_CREATE) | \
99 BIT(LWM2M_OP_EXECUTE))
100 #define LWM2M_PERM_RWX_OPT (BIT(LWM2M_OP_READ) | \
101 BIT(LWM2M_OP_WRITE) | \
102 BIT(LWM2M_OP_CREATE) | \
103 BIT(LWM2M_OP_EXECUTE) | \
104 BIT(LWM2M_FLAG_OPTIONAL))
105
106 #define LWM2M_HAS_PERM(of, p) (((of)->permissions & p) == p)
107
108 /* resource types */
109 #define LWM2M_RES_TYPE_NONE 0
110 #define LWM2M_RES_TYPE_OPAQUE 1
111 #define LWM2M_RES_TYPE_STRING 2
112 #define LWM2M_RES_TYPE_UINT 3
113 #define LWM2M_RES_TYPE_U32 3
114 #define LWM2M_RES_TYPE_U16 4
115 #define LWM2M_RES_TYPE_U8 5
116 #define LWM2M_RES_TYPE_INT64 6
117 #define LWM2M_RES_TYPE_S64 6
118 #define LWM2M_RES_TYPE_INT 7
119 #define LWM2M_RES_TYPE_S32 7
120 #define LWM2M_RES_TYPE_S16 8
121 #define LWM2M_RES_TYPE_S8 9
122 #define LWM2M_RES_TYPE_BOOL 10
123 #define LWM2M_RES_TYPE_TIME 11
124 #define LWM2M_RES_TYPE_FLOAT 12
125 #define LWM2M_RES_TYPE_OBJLNK 13
126
127 /* remember that we have already output a value - can be between two block's */
128 #define WRITER_OUTPUT_VALUE 1
129 #define WRITER_RESOURCE_INSTANCE 2
130
131 #define MAX_PACKET_SIZE (CONFIG_LWM2M_COAP_BLOCK_SIZE + \
132 CONFIG_LWM2M_ENGINE_MESSAGE_HEADER_SIZE)
133
134 /* buffer util macros */
135 #define CPKT_BUF_WRITE(cpkt) (cpkt)->data, &(cpkt)->offset, (cpkt)->max_len
136 #define CPKT_BUF_READ(cpkt) (cpkt)->data, (cpkt)->max_len
137
138 struct lwm2m_engine_obj;
139 struct lwm2m_message;
140
141 #define LWM2M_PATH_LEVEL_NONE 0
142 #define LWM2M_PATH_LEVEL_OBJECT 1
143 #define LWM2M_PATH_LEVEL_OBJECT_INST 2
144 #define LWM2M_PATH_LEVEL_RESOURCE 3
145 #define LWM2M_PATH_LEVEL_RESOURCE_INST 4
146
147 /* path representing object instances */
148 struct lwm2m_obj_path {
149 uint16_t obj_id;
150 uint16_t obj_inst_id;
151 uint16_t res_id;
152 uint16_t res_inst_id;
153 uint8_t level; /* 0/1/2/3/4 (4 = resource instance) */
154 };
155
156 #define OBJ_FIELD(_id, _perm, _type) \
157 { .res_id = _id, \
158 .permissions = LWM2M_PERM_ ## _perm, \
159 .data_type = LWM2M_RES_TYPE_ ## _type, }
160
161 /* Keep OBJ_FIELD_DATA around for historical reasons */
162 #define OBJ_FIELD_DATA(res_id, perm, type) \
163 OBJ_FIELD(res_id, perm, type)
164
165 #define OBJ_FIELD_EXECUTE(res_id) \
166 OBJ_FIELD(res_id, X, NONE)
167
168 #define OBJ_FIELD_EXECUTE_OPT(res_id) \
169 OBJ_FIELD(res_id, X_OPT, NONE)
170
171 struct lwm2m_engine_obj_field {
172 uint16_t res_id;
173 uint8_t permissions;
174 uint8_t data_type;
175 };
176
177 typedef struct lwm2m_engine_obj_inst *
178 (*lwm2m_engine_obj_create_cb_t)(uint16_t obj_inst_id);
179
180 struct lwm2m_engine_obj {
181 /* object list */
182 sys_snode_t node;
183
184 /* object field definitions */
185 struct lwm2m_engine_obj_field *fields;
186
187 /* object event callbacks */
188 lwm2m_engine_obj_create_cb_t create_cb;
189 lwm2m_engine_user_cb_t delete_cb;
190 lwm2m_engine_user_cb_t user_create_cb;
191 lwm2m_engine_user_cb_t user_delete_cb;
192
193 /* object member data */
194 uint16_t obj_id;
195 uint16_t field_count;
196 uint16_t instance_count;
197 uint16_t max_instance_count;
198
199 /* Object version information. */
200 uint8_t version_major;
201 uint8_t version_minor;
202
203 /* Object is a core object (defined in the official LwM2M spec.) */
204 bool is_core : 1;
205 };
206
207 /* Resource instances with this value are considered "not created" yet */
208 #define RES_INSTANCE_NOT_CREATED 65535
209
210 /* Resource macros */
211
212 #if CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE > 0
213 #define _INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_count, _multi_ri, \
214 _r_cb, _pre_w_cb, _val_cb, _post_w_cb, _ex_cb) \
215 _r_ptr[_r_idx].res_id = _id; \
216 _r_ptr[_r_idx].res_instances = _ri_ptr; \
217 _r_ptr[_r_idx].res_inst_count = _ri_count; \
218 _r_ptr[_r_idx].multi_res_inst = _multi_ri; \
219 _r_ptr[_r_idx].read_cb = _r_cb; \
220 _r_ptr[_r_idx].pre_write_cb = _pre_w_cb; \
221 _r_ptr[_r_idx].validate_cb = _val_cb; \
222 _r_ptr[_r_idx].post_write_cb = _post_w_cb; \
223 _r_ptr[_r_idx].execute_cb = _ex_cb
224 #else
225 #define _INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_count, _multi_ri, \
226 _r_cb, _pre_w_cb, _val_cb, _post_w_cb, _ex_cb) \
227 _r_ptr[_r_idx].res_id = _id; \
228 _r_ptr[_r_idx].res_instances = _ri_ptr; \
229 _r_ptr[_r_idx].res_inst_count = _ri_count; \
230 _r_ptr[_r_idx].multi_res_inst = _multi_ri; \
231 _r_ptr[_r_idx].read_cb = _r_cb; \
232 _r_ptr[_r_idx].pre_write_cb = _pre_w_cb; \
233 _r_ptr[_r_idx].post_write_cb = _post_w_cb; \
234 _r_ptr[_r_idx].execute_cb = _ex_cb
235 #endif /* CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE > 0 */
236
237 #define _INIT_OBJ_RES_INST(_ri_ptr, _ri_idx, _ri_count, _ri_create, \
238 _data_ptr, _data_len) \
239 do { \
240 if (_ri_ptr != NULL && _ri_count > 0) { \
241 for (int _i = 0; _i < _ri_count; _i++) { \
242 _ri_ptr[_ri_idx + _i].data_ptr = \
243 (_data_ptr + _i); \
244 _ri_ptr[_ri_idx + _i].max_data_len = \
245 _data_len; \
246 _ri_ptr[_ri_idx + _i].data_len = \
247 _data_len; \
248 if (_ri_create) { \
249 _ri_ptr[_ri_idx + _i].res_inst_id = \
250 _i; \
251 } else { \
252 _ri_ptr[_ri_idx + _i].res_inst_id = \
253 RES_INSTANCE_NOT_CREATED; \
254 } \
255 } \
256 } \
257 _ri_idx += _ri_count; \
258 } while (false)
259
260 #define _INIT_OBJ_RES_INST_OPT(_ri_ptr, _ri_idx, _ri_count, _ri_create) \
261 do { \
262 if (_ri_count > 0) { \
263 for (int _i = 0; _i < _ri_count; _i++) { \
264 _ri_ptr[_ri_idx + _i].data_ptr = NULL; \
265 _ri_ptr[_ri_idx + _i].max_data_len = 0; \
266 _ri_ptr[_ri_idx + _i].data_len = 0; \
267 if (_ri_create) { \
268 _ri_ptr[_ri_idx + _i].res_inst_id = \
269 _i; \
270 } else { \
271 _ri_ptr[_ri_idx + _i].res_inst_id = \
272 RES_INSTANCE_NOT_CREATED; \
273 } \
274 } \
275 } \
276 _ri_idx += _ri_count; \
277 } while (false)
278
279 #define INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
280 _ri_ptr, _ri_idx, _ri_count, _multi_ri, _ri_create, \
281 _data_ptr, _data_len, \
282 _r_cb, _pre_w_cb, _val_cb, _post_w_cb, _ex_cb) \
283 do { \
284 _INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
285 (_ri_ptr + _ri_idx), _ri_count, _multi_ri, \
286 _r_cb, _pre_w_cb, _val_cb, _post_w_cb, _ex_cb); \
287 _INIT_OBJ_RES_INST(_ri_ptr, _ri_idx, _ri_count, _ri_create, \
288 _data_ptr, _data_len); \
289 ++_r_idx; \
290 } while (false)
291
292
293 #define INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, \
294 _ri_ptr, _ri_idx, _ri_count, _multi_ri, _ri_create, \
295 _r_cb, _pre_w_cb, _val_cb, _post_w_cb, _ex_cb) \
296 do { \
297 _INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
298 (_ri_ptr + _ri_idx), _ri_count, _multi_ri, \
299 _r_cb, _pre_w_cb, _val_cb, _post_w_cb, _ex_cb); \
300 _INIT_OBJ_RES_INST_OPT(_ri_ptr, _ri_idx, _ri_count, _ri_create); \
301 ++_r_idx; \
302 } while (false)
303
304 #define INIT_OBJ_RES_MULTI_DATA(_id, _r_ptr, _r_idx, \
305 _ri_ptr, _ri_idx, _ri_count, _ri_create, \
306 _data_ptr, _data_len) \
307 INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
308 _ri_ptr, _ri_idx, _ri_count, true, _ri_create, \
309 _data_ptr, _data_len, NULL, NULL, NULL, NULL, NULL)
310
311 #define INIT_OBJ_RES_MULTI_OPTDATA(_id, _r_ptr, _r_idx, \
312 _ri_ptr, _ri_idx, _ri_count, _ri_create) \
313 INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, \
314 _ri_ptr, _ri_idx, _ri_count, true, _ri_create, \
315 NULL, NULL, NULL, NULL, NULL)
316
317 #define INIT_OBJ_RES_DATA(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, \
318 _data_ptr, _data_len) \
319 INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, false, true, \
320 _data_ptr, _data_len, NULL, NULL, NULL, NULL, NULL)
321
322 #define INIT_OBJ_RES_OPTDATA(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx) \
323 INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, false, \
324 true, NULL, NULL, NULL, NULL, NULL)
325
326 #define INIT_OBJ_RES_EXECUTE(_id, _r_ptr, _r_idx, _ex_cb) \
327 do { \
328 _INIT_OBJ_RES(_id, _r_ptr, _r_idx, NULL, 0, false, \
329 NULL, NULL, NULL, NULL, _ex_cb); \
330 ++_r_idx; \
331 } while (false)
332
333
334 #define LWM2M_ATTR_PMIN 0
335 #define LWM2M_ATTR_PMAX 1
336 #define LWM2M_ATTR_GT 2
337 #define LWM2M_ATTR_LT 3
338 #define LWM2M_ATTR_STEP 4
339 #define NR_LWM2M_ATTR 5
340
341 /* TODO: support multiple server (sec 5.4.2) */
342 struct lwm2m_attr {
343 void *ref;
344
345 /* values */
346 union {
347 float32_value_t float_val;
348 int32_t int_val;
349 };
350
351 uint8_t type;
352 };
353
354 struct lwm2m_engine_res_inst {
355 void *data_ptr;
356 uint16_t max_data_len;
357 uint16_t data_len;
358 uint16_t res_inst_id; /* 65535 == not "created" */
359 uint8_t data_flags;
360 };
361
362 struct lwm2m_engine_res {
363 lwm2m_engine_get_data_cb_t read_cb;
364 lwm2m_engine_get_data_cb_t pre_write_cb;
365 #if CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE > 0
366 lwm2m_engine_set_data_cb_t validate_cb;
367 #endif
368 lwm2m_engine_set_data_cb_t post_write_cb;
369 lwm2m_engine_execute_cb_t execute_cb;
370
371 struct lwm2m_engine_res_inst *res_instances;
372 uint16_t res_id;
373 uint8_t res_inst_count;
374 bool multi_res_inst;
375 };
376
377 struct lwm2m_engine_obj_inst {
378 /* instance list */
379 sys_snode_t node;
380
381 struct lwm2m_engine_obj *obj;
382 struct lwm2m_engine_res *resources;
383
384 /* object instance member data */
385 uint16_t obj_inst_id;
386 uint16_t resource_count;
387 };
388
389 /* Initialize resource instances prior to use */
init_res_instance(struct lwm2m_engine_res_inst * ri,size_t ri_len)390 static inline void init_res_instance(struct lwm2m_engine_res_inst *ri,
391 size_t ri_len)
392 {
393 size_t i;
394
395 memset(ri, 0, sizeof(*ri) * ri_len);
396 for (i = 0; i < ri_len; i++) {
397 ri[i].res_inst_id = RES_INSTANCE_NOT_CREATED;
398 }
399 }
400
401 struct lwm2m_opaque_context {
402 size_t len;
403 size_t remaining;
404 };
405
406 struct lwm2m_block_context {
407 struct coap_block_context ctx;
408 struct lwm2m_opaque_context opaque;
409 int64_t timestamp;
410 uint32_t expected;
411 uint8_t token[8];
412 uint8_t tkl;
413 bool last_block : 1;
414 uint16_t res_id;
415 };
416
417 struct lwm2m_output_context {
418 const struct lwm2m_writer *writer;
419 struct coap_packet *out_cpkt;
420
421 /* private output data */
422 void *user_data;
423 };
424
425 struct lwm2m_input_context {
426 const struct lwm2m_reader *reader;
427 struct coap_packet *in_cpkt;
428
429 /* current position in buffer */
430 uint16_t offset;
431
432 /* Corresponding block context. NULL if block transfer is not used. */
433 struct lwm2m_block_context *block_ctx;
434
435 /* private output data */
436 void *user_data;
437 };
438
439 /* Establish a message timeout callback */
440 typedef void (*lwm2m_message_timeout_cb_t)(struct lwm2m_message *msg);
441
442 /* Internal LwM2M message structure to track in-flight messages. */
443 struct lwm2m_message {
444 sys_snode_t node;
445
446 /** LwM2M context related to this message */
447 struct lwm2m_ctx *ctx;
448
449 /** Incoming / outgoing contexts */
450 struct lwm2m_input_context in;
451 struct lwm2m_output_context out;
452
453 /** Incoming path */
454 struct lwm2m_obj_path path;
455
456 /** CoAP packet data related to the outgoing message */
457 struct coap_packet cpkt;
458
459 /** Buffer data related outgoing message */
460 uint8_t msg_data[MAX_PACKET_SIZE];
461
462 /** Message transmission handling for TYPE_CON */
463 struct coap_pending *pending;
464 struct coap_reply *reply;
465
466 /** Message configuration */
467 uint8_t *token;
468 coap_reply_t reply_cb;
469 lwm2m_message_timeout_cb_t message_timeout_cb;
470 uint16_t mid;
471 uint8_t type;
472 uint8_t code;
473 uint8_t tkl;
474
475 /** Incoming message action */
476 uint8_t operation;
477
478 /* Information whether the message was acknowledged. */
479 bool acknowledged : 1;
480 };
481
482 /* LWM2M format writer for the various formats supported */
483 struct lwm2m_writer {
484 size_t (*put_begin)(struct lwm2m_output_context *out,
485 struct lwm2m_obj_path *path);
486 size_t (*put_end)(struct lwm2m_output_context *out,
487 struct lwm2m_obj_path *path);
488 size_t (*put_begin_oi)(struct lwm2m_output_context *out,
489 struct lwm2m_obj_path *path);
490 size_t (*put_end_oi)(struct lwm2m_output_context *out,
491 struct lwm2m_obj_path *path);
492 size_t (*put_begin_r)(struct lwm2m_output_context *out,
493 struct lwm2m_obj_path *path);
494 size_t (*put_end_r)(struct lwm2m_output_context *out,
495 struct lwm2m_obj_path *path);
496 size_t (*put_begin_ri)(struct lwm2m_output_context *out,
497 struct lwm2m_obj_path *path);
498 size_t (*put_end_ri)(struct lwm2m_output_context *out,
499 struct lwm2m_obj_path *path);
500 size_t (*put_s8)(struct lwm2m_output_context *out,
501 struct lwm2m_obj_path *path,
502 int8_t value);
503 size_t (*put_s16)(struct lwm2m_output_context *out,
504 struct lwm2m_obj_path *path,
505 int16_t value);
506 size_t (*put_s32)(struct lwm2m_output_context *out,
507 struct lwm2m_obj_path *path,
508 int32_t value);
509 size_t (*put_s64)(struct lwm2m_output_context *out,
510 struct lwm2m_obj_path *path,
511 int64_t value);
512 size_t (*put_string)(struct lwm2m_output_context *out,
513 struct lwm2m_obj_path *path,
514 char *buf, size_t buflen);
515 size_t (*put_float32fix)(struct lwm2m_output_context *out,
516 struct lwm2m_obj_path *path,
517 float32_value_t *value);
518 size_t (*put_bool)(struct lwm2m_output_context *out,
519 struct lwm2m_obj_path *path,
520 bool value);
521 size_t (*put_opaque)(struct lwm2m_output_context *out,
522 struct lwm2m_obj_path *path,
523 char *buf, size_t buflen);
524 size_t (*put_objlnk)(struct lwm2m_output_context *out,
525 struct lwm2m_obj_path *path,
526 struct lwm2m_objlnk *value);
527 ssize_t (*put_corelink)(struct lwm2m_output_context *out,
528 const struct lwm2m_obj_path *path);
529 };
530
531 struct lwm2m_reader {
532 size_t (*get_s32)(struct lwm2m_input_context *in,
533 int32_t *value);
534 size_t (*get_s64)(struct lwm2m_input_context *in,
535 int64_t *value);
536 size_t (*get_string)(struct lwm2m_input_context *in,
537 uint8_t *buf, size_t buflen);
538 size_t (*get_float32fix)(struct lwm2m_input_context *in,
539 float32_value_t *value);
540 size_t (*get_bool)(struct lwm2m_input_context *in,
541 bool *value);
542 size_t (*get_opaque)(struct lwm2m_input_context *in,
543 uint8_t *buf, size_t buflen,
544 struct lwm2m_opaque_context *opaque,
545 bool *last_block);
546 size_t (*get_objlnk)(struct lwm2m_input_context *in,
547 struct lwm2m_objlnk *value);
548 };
549
550 /* output user_data management functions */
551
engine_set_out_user_data(struct lwm2m_output_context * out,void * user_data)552 static inline void engine_set_out_user_data(struct lwm2m_output_context *out,
553 void *user_data)
554 {
555 out->user_data = user_data;
556 }
557
engine_get_out_user_data(struct lwm2m_output_context * out)558 static inline void *engine_get_out_user_data(struct lwm2m_output_context *out)
559 {
560 return out->user_data;
561 }
562
563 static inline void
engine_clear_out_user_data(struct lwm2m_output_context * out)564 engine_clear_out_user_data(struct lwm2m_output_context *out)
565 {
566 out->user_data = NULL;
567 }
568
engine_set_in_user_data(struct lwm2m_input_context * in,void * user_data)569 static inline void engine_set_in_user_data(struct lwm2m_input_context *in,
570 void *user_data)
571 {
572 in->user_data = user_data;
573 }
574
engine_get_in_user_data(struct lwm2m_input_context * in)575 static inline void *engine_get_in_user_data(struct lwm2m_input_context *in)
576 {
577 return in->user_data;
578 }
579
580 static inline void
engine_clear_in_user_data(struct lwm2m_input_context * in)581 engine_clear_in_user_data(struct lwm2m_input_context *in)
582 {
583 in->user_data = NULL;
584 }
585
586 /* inline multi-format write / read functions */
587
engine_put_begin(struct lwm2m_output_context * out,struct lwm2m_obj_path * path)588 static inline size_t engine_put_begin(struct lwm2m_output_context *out,
589 struct lwm2m_obj_path *path)
590 {
591 if (out->writer->put_begin) {
592 return out->writer->put_begin(out, path);
593 }
594
595 return 0;
596 }
597
engine_put_end(struct lwm2m_output_context * out,struct lwm2m_obj_path * path)598 static inline size_t engine_put_end(struct lwm2m_output_context *out,
599 struct lwm2m_obj_path *path)
600 {
601 if (out->writer->put_end) {
602 return out->writer->put_end(out, path);
603 }
604
605 return 0;
606 }
607
engine_put_begin_oi(struct lwm2m_output_context * out,struct lwm2m_obj_path * path)608 static inline size_t engine_put_begin_oi(struct lwm2m_output_context *out,
609 struct lwm2m_obj_path *path)
610 {
611 if (out->writer->put_begin_oi) {
612 return out->writer->put_begin_oi(out, path);
613 }
614
615 return 0;
616 }
617
engine_put_end_oi(struct lwm2m_output_context * out,struct lwm2m_obj_path * path)618 static inline size_t engine_put_end_oi(struct lwm2m_output_context *out,
619 struct lwm2m_obj_path *path)
620 {
621 if (out->writer->put_end_oi) {
622 return out->writer->put_end_oi(out, path);
623 }
624
625 return 0;
626 }
627
engine_put_begin_r(struct lwm2m_output_context * out,struct lwm2m_obj_path * path)628 static inline size_t engine_put_begin_r(struct lwm2m_output_context *out,
629 struct lwm2m_obj_path *path)
630 {
631 if (out->writer->put_begin_r) {
632 return out->writer->put_begin_r(out, path);
633 }
634
635 return 0;
636 }
637
engine_put_end_r(struct lwm2m_output_context * out,struct lwm2m_obj_path * path)638 static inline size_t engine_put_end_r(struct lwm2m_output_context *out,
639 struct lwm2m_obj_path *path)
640 {
641 if (out->writer->put_end_r) {
642 return out->writer->put_end_r(out, path);
643 }
644
645 return 0;
646 }
647
engine_put_begin_ri(struct lwm2m_output_context * out,struct lwm2m_obj_path * path)648 static inline size_t engine_put_begin_ri(struct lwm2m_output_context *out,
649 struct lwm2m_obj_path *path)
650 {
651 if (out->writer->put_begin_ri) {
652 return out->writer->put_begin_ri(out, path);
653 }
654
655 return 0;
656 }
657
engine_put_end_ri(struct lwm2m_output_context * out,struct lwm2m_obj_path * path)658 static inline size_t engine_put_end_ri(struct lwm2m_output_context *out,
659 struct lwm2m_obj_path *path)
660 {
661 if (out->writer->put_end_ri) {
662 return out->writer->put_end_ri(out, path);
663 }
664
665 return 0;
666 }
667
engine_put_s8(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,int8_t value)668 static inline size_t engine_put_s8(struct lwm2m_output_context *out,
669 struct lwm2m_obj_path *path,
670 int8_t value)
671 {
672 return out->writer->put_s8(out, path, value);
673 }
674
engine_put_s16(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,int16_t value)675 static inline size_t engine_put_s16(struct lwm2m_output_context *out,
676 struct lwm2m_obj_path *path,
677 int16_t value)
678 {
679 return out->writer->put_s16(out, path, value);
680 }
681
engine_put_s32(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,int32_t value)682 static inline size_t engine_put_s32(struct lwm2m_output_context *out,
683 struct lwm2m_obj_path *path,
684 int32_t value)
685 {
686 return out->writer->put_s32(out, path, value);
687 }
688
engine_put_s64(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,int64_t value)689 static inline size_t engine_put_s64(struct lwm2m_output_context *out,
690 struct lwm2m_obj_path *path,
691 int64_t value)
692 {
693 return out->writer->put_s64(out, path, value);
694 }
695
engine_put_string(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,char * buf,size_t buflen)696 static inline size_t engine_put_string(struct lwm2m_output_context *out,
697 struct lwm2m_obj_path *path,
698 char *buf, size_t buflen)
699 {
700 return out->writer->put_string(out, path, buf, buflen);
701 }
702
engine_put_float32fix(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,float32_value_t * value)703 static inline size_t engine_put_float32fix(struct lwm2m_output_context *out,
704 struct lwm2m_obj_path *path,
705 float32_value_t *value)
706 {
707 return out->writer->put_float32fix(out, path, value);
708 }
709
engine_put_bool(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,bool value)710 static inline size_t engine_put_bool(struct lwm2m_output_context *out,
711 struct lwm2m_obj_path *path,
712 bool value)
713 {
714 return out->writer->put_bool(out, path, value);
715 }
716
engine_put_opaque(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,char * buf,size_t buflen)717 static inline size_t engine_put_opaque(struct lwm2m_output_context *out,
718 struct lwm2m_obj_path *path,
719 char *buf, size_t buflen)
720 {
721 if (out->writer->put_opaque) {
722 return out->writer->put_opaque(out, path, buf, buflen);
723 }
724
725 return 0;
726 }
727
engine_put_objlnk(struct lwm2m_output_context * out,struct lwm2m_obj_path * path,struct lwm2m_objlnk * value)728 static inline size_t engine_put_objlnk(struct lwm2m_output_context *out,
729 struct lwm2m_obj_path *path,
730 struct lwm2m_objlnk *value)
731 {
732 return out->writer->put_objlnk(out, path, value);
733 }
734
engine_put_corelink(struct lwm2m_output_context * out,const struct lwm2m_obj_path * path)735 static inline ssize_t engine_put_corelink(struct lwm2m_output_context *out,
736 const struct lwm2m_obj_path *path)
737 {
738 if (out->writer->put_corelink) {
739 return out->writer->put_corelink(out, path);
740 }
741
742 return -ENOTSUP;
743 }
744
engine_get_s32(struct lwm2m_input_context * in,int32_t * value)745 static inline size_t engine_get_s32(struct lwm2m_input_context *in,
746 int32_t *value)
747 {
748 return in->reader->get_s32(in, value);
749 }
750
engine_get_s64(struct lwm2m_input_context * in,int64_t * value)751 static inline size_t engine_get_s64(struct lwm2m_input_context *in,
752 int64_t *value)
753 {
754 return in->reader->get_s64(in, value);
755 }
756
engine_get_string(struct lwm2m_input_context * in,uint8_t * buf,size_t buflen)757 static inline size_t engine_get_string(struct lwm2m_input_context *in,
758 uint8_t *buf, size_t buflen)
759 {
760 return in->reader->get_string(in, buf, buflen);
761 }
762
engine_get_float32fix(struct lwm2m_input_context * in,float32_value_t * value)763 static inline size_t engine_get_float32fix(struct lwm2m_input_context *in,
764 float32_value_t *value)
765 {
766 return in->reader->get_float32fix(in, value);
767 }
768
engine_get_bool(struct lwm2m_input_context * in,bool * value)769 static inline size_t engine_get_bool(struct lwm2m_input_context *in,
770 bool *value)
771 {
772 return in->reader->get_bool(in, value);
773 }
774
engine_get_opaque(struct lwm2m_input_context * in,uint8_t * buf,size_t buflen,struct lwm2m_opaque_context * opaque,bool * last_block)775 static inline size_t engine_get_opaque(struct lwm2m_input_context *in,
776 uint8_t *buf, size_t buflen,
777 struct lwm2m_opaque_context *opaque,
778 bool *last_block)
779 {
780 if (in->reader->get_opaque) {
781 return in->reader->get_opaque(in, buf, buflen,
782 opaque, last_block);
783 }
784
785 return 0;
786 }
787
engine_get_objlnk(struct lwm2m_input_context * in,struct lwm2m_objlnk * value)788 static inline size_t engine_get_objlnk(struct lwm2m_input_context *in,
789 struct lwm2m_objlnk *value)
790 {
791 return in->reader->get_objlnk(in, value);
792 }
793
794 #endif /* LWM2M_OBJECT_H_ */
795