1 /*
2  * Copyright (c) 2017 Linaro Limited
3  * Copyright (c) 2017-2019 Foundries.io
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /** @file lwm2m.h
9  *
10  * @defgroup lwm2m_api LwM2M high-level API
11  * @ingroup networking
12  * @{
13  * @brief LwM2M high-level API
14  *
15  * @details
16  * LwM2M high-level interface is defined in this header.
17  *
18  * @note The implementation assumes UDP module is enabled.
19  *
20  * @note LwM2M 1.0.x is currently the only supported version.
21  */
22 
23 #ifndef ZEPHYR_INCLUDE_NET_LWM2M_H_
24 #define ZEPHYR_INCLUDE_NET_LWM2M_H_
25 
26 #include <kernel.h>
27 #include <sys/mutex.h>
28 #include <net/coap.h>
29 #include <net/lwm2m_path.h>
30 
31 /**
32  * @brief LwM2M Objects managed by OMA for LwM2M tech specification.  Objects
33  * in this range have IDs from 0 to 1023.
34  * For more information refer to Technical Specification
35  * OMA-TS-LightweightM2M-V1_0_2-20180209-A
36  */
37 
38 #define LWM2M_OBJECT_SECURITY_ID			0
39 #define LWM2M_OBJECT_SERVER_ID				1
40 #define LWM2M_OBJECT_ACCESS_CONTROL_ID			2
41 #define LWM2M_OBJECT_DEVICE_ID				3
42 #define LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID		4
43 #define LWM2M_OBJECT_FIRMWARE_ID			5
44 #define LWM2M_OBJECT_LOCATION_ID			6
45 #define LWM2M_OBJECT_CONNECTIVITY_STATISTICS_ID		7
46 
47 /**
48  * @brief LwM2M Objects produced by 3rd party Standards Development
49  * Organizations.  Objects in this range have IDs from 2048 to 10240
50  * Refer to the OMA LightweightM2M (LwM2M) Object and Resource Registry:
51  * http://www.openmobilealliance.org/wp/OMNA/LwM2M/LwM2MRegistry.html
52  */
53 
54 /* clang-format off */
55 #define IPSO_OBJECT_GENERIC_SENSOR_ID       3300
56 #define IPSO_OBJECT_TEMP_SENSOR_ID          3303
57 #define IPSO_OBJECT_HUMIDITY_SENSOR_ID      3304
58 #define IPSO_OBJECT_LIGHT_CONTROL_ID        3311
59 #define IPSO_OBJECT_ACCELEROMETER_ID        3313
60 #define IPSO_OBJECT_PRESSURE_ID             3323
61 #define IPSO_OBJECT_BUZZER_ID               3338
62 #define IPSO_OBJECT_TIMER_ID                3340
63 #define IPSO_OBJECT_ONOFF_SWITCH_ID         3342
64 #define IPSO_OBJECT_PUSH_BUTTON_ID          3347
65 /* clang-format on */
66 
67 typedef void (*lwm2m_socket_fault_cb_t)(int error);
68 typedef void (*lwm2m_notify_timeout_cb_t)(void);
69 
70 /**
71  * @brief LwM2M context structure to maintain information for a single
72  * LwM2M connection.
73  */
74 struct lwm2m_ctx {
75 	/** Destination address storage */
76 	struct sockaddr remote_addr;
77 
78 	/** Private CoAP and networking structures */
79 	struct coap_pending pendings[CONFIG_LWM2M_ENGINE_MAX_PENDING];
80 	struct coap_reply replies[CONFIG_LWM2M_ENGINE_MAX_REPLIES];
81 	sys_slist_t pending_sends;
82 	sys_slist_t observer;
83 
84 	/** A pointer to currently processed request, for internal LwM2M engine
85 	 *  use. The underlying type is ``struct lwm2m_message``, but since it's
86 	 *  declared in a private header and not exposed to the application,
87 	 *  it's stored as a void pointer.
88 	 */
89 	void *processed_req;
90 
91 #if defined(CONFIG_LWM2M_DTLS_SUPPORT)
92 	/** TLS tag is set by client as a reference used when the
93 	 *  LwM2M engine calls tls_credential_(add|delete)
94 	 */
95 	int tls_tag;
96 
97 	/** Client can set load_credentials function as a way of overriding
98 	 *  the default behavior of load_tls_credential() in lwm2m_engine.c
99 	 */
100 	int (*load_credentials)(struct lwm2m_ctx *client_ctx);
101 #endif
102 	/** Flag to indicate if context should use DTLS.
103 	 *  Enabled via the use of coaps:// protocol prefix in connection
104 	 *  information.
105 	 *  NOTE: requires CONFIG_LWM2M_DTLS_SUPPORT=y
106 	 */
107 	bool use_dtls;
108 
109 	/** Current index of Security Object used for server credentials */
110 	int sec_obj_inst;
111 
112 	/** Current index of Server Object used in this context. */
113 	int srv_obj_inst;
114 
115 	/** Flag to enable BOOTSTRAP interface.  See Section 5.2
116 	 *  "Bootstrap Interface" of LwM2M Technical Specification 1.0.2
117 	 *  for more information.
118 	 */
119 	bool bootstrap_mode;
120 
121 	/** Socket File Descriptor */
122 	int sock_fd;
123 
124 	/** Socket fault callback. LwM2M processing thread will call this
125 	 *  callback in case of socket errors on receive.
126 	 */
127 	lwm2m_socket_fault_cb_t fault_cb;
128 
129 	/** Notify Timeout Callback. LwM2M processing thread will call this
130 	 *  callback in case of notify timeout.
131 	 */
132 	lwm2m_notify_timeout_cb_t notify_timeout_cb;
133 
134 	/** Validation buffer. Used as a temporary buffer to decode the resource
135 	 *  value before validation. On successful validation, its content is
136 	 *  copied into the actual resource buffer.
137 	 */
138 	uint8_t validate_buf[CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE];
139 };
140 
141 
142 /**
143  * @brief Asynchronous callback to get a resource buffer and length.
144  *
145  * Prior to accessing the data buffer of a resource, the engine can
146  * use this callback to get the buffer pointer and length instead
147  * of using the resource's data buffer.
148  *
149  * The client or LwM2M objects can register a function of this type via:
150  * lwm2m_engine_register_read_callback()
151  * lwm2m_engine_register_pre_write_callback()
152  *
153  * @param[in] obj_inst_id Object instance ID generating the callback.
154  * @param[in] res_id Resource ID generating the callback.
155  * @param[in] res_inst_id Resource instance ID generating the callback
156  *                        (typically 0 for non-multi instance resources).
157  * @param[out] data_len Length of the data buffer.
158  *
159  * @return Callback returns a pointer to the data buffer or NULL for failure.
160  */
161 typedef void *(*lwm2m_engine_get_data_cb_t)(uint16_t obj_inst_id,
162 					    uint16_t res_id,
163 					    uint16_t res_inst_id,
164 					    size_t *data_len);
165 
166 /**
167  * @brief Asynchronous callback when data has been set to a resource buffer.
168  *
169  * After changing the data of a resource buffer, the LwM2M engine can
170  * make use of this callback to pass the data back to the client or LwM2M
171  * objects.
172  *
173  * A function of this type can be registered via:
174  * lwm2m_engine_register_validate_callback()
175  * lwm2m_engine_register_post_write_callback()
176  *
177  * @param[in] obj_inst_id Object instance ID generating the callback.
178  * @param[in] res_id Resource ID generating the callback.
179  * @param[in] res_inst_id Resource instance ID generating the callback
180  *                        (typically 0 for non-multi instance resources).
181  * @param[in] data Pointer to data.
182  * @param[in] data_len Length of the data.
183  * @param[in] last_block Flag used during block transfer to indicate the last
184  *                       block of data. For non-block transfers this is always
185  *                       false.
186  * @param[in] total_size Expected total size of data for a block transfer.
187  *                       For non-block transfers this is 0.
188  *
189  * @return Callback returns a negative error code (errno.h) indicating
190  *         reason of failure or 0 for success.
191  */
192 typedef int (*lwm2m_engine_set_data_cb_t)(uint16_t obj_inst_id,
193 					  uint16_t res_id, uint16_t res_inst_id,
194 					  uint8_t *data, uint16_t data_len,
195 					  bool last_block, size_t total_size);
196 
197 /**
198  * @brief Asynchronous event notification callback.
199  *
200  * Various object instance and resource-based events in the LwM2M engine
201  * can trigger a callback of this function type: object instance create,
202  * and object instance delete.
203  *
204  * Register a function of this type via:
205  * lwm2m_engine_register_create_callback()
206  * lwm2m_engine_register_delete_callback()
207  *
208  * @param[in] obj_inst_id Object instance ID generating the callback.
209  *
210  * @return Callback returns a negative error code (errno.h) indicating
211  *         reason of failure or 0 for success.
212  */
213 typedef int (*lwm2m_engine_user_cb_t)(uint16_t obj_inst_id);
214 
215 /**
216  * @brief Asynchronous execute notification callback.
217  *
218  * Resource executes trigger a callback of this type.
219  *
220  * Register a function of this type via:
221  * lwm2m_engine_register_exec_callback()
222  *
223  * @param[in] obj_inst_id Object instance ID generating the callback.
224  * @param[in] args Pointer to execute arguments payload. (This can be
225  *            NULL if no arguments are provided)
226  * @param[in] args_len Length of argument payload in bytes.
227  *
228  * @return Callback returns a negative error code (errno.h) indicating
229  *         reason of failure or 0 for success.
230  */
231 typedef int (*lwm2m_engine_execute_cb_t)(uint16_t obj_inst_id,
232 					 uint8_t *args, uint16_t args_len);
233 
234 /**
235  * @brief Power source types used for the "Available Power Sources" resource of
236  * the LwM2M Device object.
237  */
238 #define LWM2M_DEVICE_PWR_SRC_TYPE_DC_POWER	0
239 #define LWM2M_DEVICE_PWR_SRC_TYPE_BAT_INT	1
240 #define LWM2M_DEVICE_PWR_SRC_TYPE_BAT_EXT	2
241 #define LWM2M_DEVICE_PWR_SRC_TYPE_UNUSED	3
242 #define LWM2M_DEVICE_PWR_SRC_TYPE_PWR_OVER_ETH	4
243 #define LWM2M_DEVICE_PWR_SRC_TYPE_USB		5
244 #define LWM2M_DEVICE_PWR_SRC_TYPE_AC_POWER	6
245 #define LWM2M_DEVICE_PWR_SRC_TYPE_SOLAR		7
246 #define LWM2M_DEVICE_PWR_SRC_TYPE_MAX		8
247 
248 /**
249  * @brief Error codes used for the "Error Code" resource of the LwM2M Device
250  * object.  An LwM2M client can register one of the following error codes via
251  * the lwm2m_device_add_err() function.
252  */
253 #define LWM2M_DEVICE_ERROR_NONE			0
254 #define LWM2M_DEVICE_ERROR_LOW_POWER		1
255 #define LWM2M_DEVICE_ERROR_EXT_POWER_SUPPLY_OFF	2
256 #define LWM2M_DEVICE_ERROR_GPS_FAILURE		3
257 #define LWM2M_DEVICE_ERROR_LOW_SIGNAL_STRENGTH	4
258 #define LWM2M_DEVICE_ERROR_OUT_OF_MEMORY	5
259 #define LWM2M_DEVICE_ERROR_SMS_FAILURE		6
260 #define LWM2M_DEVICE_ERROR_NETWORK_FAILURE	7
261 #define LWM2M_DEVICE_ERROR_PERIPHERAL_FAILURE	8
262 
263 /**
264  * @brief Battery status codes used for the "Battery Status" resource (3/0/20)
265  *        of the LwM2M Device object.  As the battery status changes, an LwM2M
266  *        client can set one of the following codes via:
267  *        lwm2m_engine_set_u8("3/0/20", [battery status])
268  */
269 #define LWM2M_DEVICE_BATTERY_STATUS_NORMAL	0
270 #define LWM2M_DEVICE_BATTERY_STATUS_CHARGING	1
271 #define LWM2M_DEVICE_BATTERY_STATUS_CHARGE_COMP	2
272 #define LWM2M_DEVICE_BATTERY_STATUS_DAMAGED	3
273 #define LWM2M_DEVICE_BATTERY_STATUS_LOW		4
274 #define LWM2M_DEVICE_BATTERY_STATUS_NOT_INST	5
275 #define LWM2M_DEVICE_BATTERY_STATUS_UNKNOWN	6
276 
277 /**
278  * @brief Register a new error code with LwM2M Device object.
279  *
280  * @param[in] error_code New error code.
281  *
282  * @return 0 for success or negative in case of error.
283  */
284 int lwm2m_device_add_err(uint8_t error_code);
285 
286 
287 /**
288  * @brief LWM2M Firmware Update object states
289  *
290  * An LwM2M client or the LwM2M Firmware Update object use the following codes
291  * to represent the LwM2M Firmware Update state (5/0/3).
292  */
293 #define STATE_IDLE		0
294 #define STATE_DOWNLOADING	1
295 #define STATE_DOWNLOADED	2
296 #define STATE_UPDATING		3
297 
298 /**
299  * @brief LWM2M Firmware Update object result codes
300  *
301  * After processing a firmware update, the client sets the result via one of
302  * the following codes via lwm2m_engine_set_u8("5/0/5", [result code])
303  */
304 #define RESULT_DEFAULT		0
305 #define RESULT_SUCCESS		1
306 #define RESULT_NO_STORAGE	2
307 #define RESULT_OUT_OF_MEM	3
308 #define RESULT_CONNECTION_LOST	4
309 #define RESULT_INTEGRITY_FAILED	5
310 #define RESULT_UNSUP_FW		6
311 #define RESULT_INVALID_URI	7
312 #define RESULT_UPDATE_FAILED	8
313 #define RESULT_UNSUP_PROTO	9
314 
315 #if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_OBJ_SUPPORT)
316 /**
317  * @brief Set data callback for firmware block transfer.
318  *
319  * LwM2M clients use this function to register a callback for receiving the
320  * block transfer data when performing a firmware update.
321  *
322  * @param[in] cb A callback function to receive the block transfer data
323  */
324 void lwm2m_firmware_set_write_cb(lwm2m_engine_set_data_cb_t cb);
325 
326 /**
327  * @brief Get the data callback for firmware block transfer writes.
328  *
329  * @return A registered callback function to receive the block transfer data
330  */
331 lwm2m_engine_set_data_cb_t lwm2m_firmware_get_write_cb(void);
332 
333 #if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_SUPPORT)
334 /**
335  * @brief Set data callback to handle firmware update execute events.
336  *
337  * LwM2M clients use this function to register a callback for receiving the
338  * update resource "execute" operation on the LwM2M Firmware Update object.
339  *
340  * @param[in] cb A callback function to receive the execute event.
341  */
342 void lwm2m_firmware_set_update_cb(lwm2m_engine_execute_cb_t cb);
343 
344 /**
345  * @brief Get the event callback for firmware update execute events.
346  *
347  * @return A registered callback function to receive the execute event.
348  */
349 lwm2m_engine_execute_cb_t lwm2m_firmware_get_update_cb(void);
350 
351 /**
352  * @brief Get the block context of the current firmware block.
353  *
354  * @param[out] ctx A buffer to store the block context.
355  */
356 struct coap_block_context *lwm2m_firmware_get_block_context();
357 #endif
358 #endif
359 
360 /**
361  * @brief Data structure used to represent the LwM2M float type:
362  * val1 is the whole number portion of the decimal
363  * val2 is the decimal portion *1000000 for 32bit, *1000000000 for 64bit
364  * Example: 123.456 == val1: 123, val2:456000
365  * Example: 123.000456 = val1: 123, val2:456
366  */
367 
368 /**
369  * @brief Maximum precision value for 32-bit LwM2M float val2
370  */
371 #define LWM2M_FLOAT32_DEC_MAX 1000000
372 
373 /**
374  * @brief 32-bit variant of the LwM2M float structure
375  */
376 typedef struct float32_value {
377 	int32_t val1;
378 	int32_t val2;
379 } float32_value_t;
380 
381 /**
382  * @brief Maximum value for ObjLnk resource fields
383  */
384 #define LWM2M_OBJLNK_MAX_ID USHRT_MAX
385 
386 /**
387  * @brief LWM2M ObjLnk resource type structure
388  */
389 struct lwm2m_objlnk {
390 	uint16_t obj_id;
391 	uint16_t obj_inst;
392 };
393 
394 /**
395  * @brief Change an observer's pmin value.
396  *
397  * LwM2M clients use this function to modify the pmin attribute
398  * for an observation being made.
399  * Example to update the pmin of a temperature sensor value being observed:
400  * lwm2m_engine_update_observer_min_period("3303/0/5700",5);
401  *
402  * @param[in] pathstr LwM2M path string "obj/obj-inst/res"
403  * @param[in] period_s Value of pmin to be given (in seconds).
404  *
405  * @return 0 for success or negative in case of error.
406  */
407 int lwm2m_engine_update_observer_min_period(char *pathstr, uint32_t period_s);
408 
409 /**
410  * @brief Change an observer's pmax value.
411  *
412  * LwM2M clients use this function to modify the pmax attribute
413  * for an observation being made.
414  * Example to update the pmax of a temperature sensor value being observed:
415  * lwm2m_engine_update_observer_max_period("3303/0/5700",5);
416  *
417  * @param[in] pathstr LwM2M path string "obj/obj-inst/res"
418  * @param[in] period_s Value of pmax to be given (in seconds).
419  *
420  * @return 0 for success or negative in case of error.
421  */
422 int lwm2m_engine_update_observer_max_period(char *pathstr, uint32_t period_s);
423 
424 /**
425  * @brief Create an LwM2M object instance.
426  *
427  * LwM2M clients use this function to create non-default LwM2M objects:
428  * Example to create first temperature sensor object:
429  * lwm2m_engine_create_obj_inst("3303/0");
430  *
431  * @param[in] pathstr LwM2M path string "obj/obj-inst"
432  *
433  * @return 0 for success or negative in case of error.
434  */
435 int lwm2m_engine_create_obj_inst(char *pathstr);
436 
437 /**
438  * @brief Delete an LwM2M object instance.
439  *
440  * LwM2M clients use this function to delete LwM2M objects.
441  *
442  * @param[in] pathstr LwM2M path string "obj/obj-inst"
443  *
444  * @return 0 for success or negative in case of error.
445  */
446 int lwm2m_engine_delete_obj_inst(char *pathstr);
447 
448 /**
449  * @brief Set resource (instance) value (opaque buffer)
450  *
451  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
452  * @param[in] data_ptr Data buffer
453  * @param[in] data_len Length of buffer
454  *
455  * @return 0 for success or negative in case of error.
456  */
457 int lwm2m_engine_set_opaque(char *pathstr, char *data_ptr, uint16_t data_len);
458 
459 /**
460  * @brief Set resource (instance) value (string)
461  *
462  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
463  * @param[in] data_ptr NULL terminated char buffer
464  *
465  * @return 0 for success or negative in case of error.
466  */
467 int lwm2m_engine_set_string(char *pathstr, char *data_ptr);
468 
469 /**
470  * @brief Set resource (instance) value (u8)
471  *
472  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
473  * @param[in] value u8 value
474  *
475  * @return 0 for success or negative in case of error.
476  */
477 int lwm2m_engine_set_u8(char *pathstr, uint8_t value);
478 
479 /**
480  * @brief Set resource (instance) value (u16)
481  *
482  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
483  * @param[in] value u16 value
484  *
485  * @return 0 for success or negative in case of error.
486  */
487 int lwm2m_engine_set_u16(char *pathstr, uint16_t value);
488 
489 /**
490  * @brief Set resource (instance) value (u32)
491  *
492  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
493  * @param[in] value u32 value
494  *
495  * @return 0 for success or negative in case of error.
496  */
497 int lwm2m_engine_set_u32(char *pathstr, uint32_t value);
498 
499 /**
500  * @brief Set resource (instance) value (u64)
501  *
502  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
503  * @param[in] value u64 value
504  *
505  * @return 0 for success or negative in case of error.
506  */
507 int lwm2m_engine_set_u64(char *pathstr, uint64_t value);
508 
509 /**
510  * @brief Set resource (instance) value (s8)
511  *
512  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
513  * @param[in] value s8 value
514  *
515  * @return 0 for success or negative in case of error.
516  */
517 int lwm2m_engine_set_s8(char *pathstr, int8_t value);
518 
519 /**
520  * @brief Set resource (instance) value (s16)
521  *
522  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
523  * @param[in] value s16 value
524  *
525  * @return 0 for success or negative in case of error.
526  */
527 int lwm2m_engine_set_s16(char *pathstr, int16_t value);
528 
529 /**
530  * @brief Set resource (instance) value (s32)
531  *
532  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
533  * @param[in] value s32 value
534  *
535  * @return 0 for success or negative in case of error.
536  */
537 int lwm2m_engine_set_s32(char *pathstr, int32_t value);
538 
539 /**
540  * @brief Set resource (instance) value (s64)
541  *
542  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
543  * @param[in] value s64 value
544  *
545  * @return 0 for success or negative in case of error.
546  */
547 int lwm2m_engine_set_s64(char *pathstr, int64_t value);
548 
549 /**
550  * @brief Set resource (instance) value (bool)
551  *
552  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
553  * @param[in] value bool value
554  *
555  * @return 0 for success or negative in case of error.
556  */
557 int lwm2m_engine_set_bool(char *pathstr, bool value);
558 
559 /**
560  * @brief Set resource (instance) value (32-bit float structure)
561  *
562  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
563  * @param[in] value 32-bit float value
564  *
565  * @return 0 for success or negative in case of error.
566  */
567 int lwm2m_engine_set_float32(char *pathstr, float32_value_t *value);
568 
569 /**
570  * @brief Set resource (instance) value (ObjLnk)
571  *
572  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
573  * @param[in] value pointer to the lwm2m_objlnk structure
574  *
575  * @return 0 for success or negative in case of error.
576  */
577 int lwm2m_engine_set_objlnk(char *pathstr, struct lwm2m_objlnk *value);
578 
579 /**
580  * @brief Get resource (instance) value (opaque buffer)
581  *
582  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
583  * @param[out] buf Data buffer to copy data into
584  * @param[in] buflen Length of buffer
585  *
586  * @return 0 for success or negative in case of error.
587  */
588 int lwm2m_engine_get_opaque(char *pathstr, void *buf, uint16_t buflen);
589 
590 /**
591  * @brief Get resource (instance) value (string)
592  *
593  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
594  * @param[out] str String buffer to copy data into
595  * @param[in] strlen Length of buffer
596  *
597  * @return 0 for success or negative in case of error.
598  */
599 int lwm2m_engine_get_string(char *pathstr, void *str, uint16_t strlen);
600 
601 /**
602  * @brief Get resource (instance) value (u8)
603  *
604  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
605  * @param[out] value u8 buffer to copy data into
606  *
607  * @return 0 for success or negative in case of error.
608  */
609 int lwm2m_engine_get_u8(char *pathstr, uint8_t *value);
610 
611 /**
612  * @brief Get resource (instance) value (u16)
613  *
614  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
615  * @param[out] value u16 buffer to copy data into
616  *
617  * @return 0 for success or negative in case of error.
618  */
619 int lwm2m_engine_get_u16(char *pathstr, uint16_t *value);
620 
621 /**
622  * @brief Get resource (instance) value (u32)
623  *
624  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
625  * @param[out] value u32 buffer to copy data into
626  *
627  * @return 0 for success or negative in case of error.
628  */
629 int lwm2m_engine_get_u32(char *pathstr, uint32_t *value);
630 
631 /**
632  * @brief Get resource (instance) value (u64)
633  *
634  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
635  * @param[out] value u64 buffer to copy data into
636  *
637  * @return 0 for success or negative in case of error.
638  */
639 int lwm2m_engine_get_u64(char *pathstr, uint64_t *value);
640 
641 /**
642  * @brief Get resource (instance) value (s8)
643  *
644  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
645  * @param[out] value s8 buffer to copy data into
646  *
647  * @return 0 for success or negative in case of error.
648  */
649 int lwm2m_engine_get_s8(char *pathstr, int8_t *value);
650 
651 /**
652  * @brief Get resource (instance) value (s16)
653  *
654  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
655  * @param[out] value s16 buffer to copy data into
656  *
657  * @return 0 for success or negative in case of error.
658  */
659 int lwm2m_engine_get_s16(char *pathstr, int16_t *value);
660 
661 /**
662  * @brief Get resource (instance) value (s32)
663  *
664  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
665  * @param[out] value s32 buffer to copy data into
666  *
667  * @return 0 for success or negative in case of error.
668  */
669 int lwm2m_engine_get_s32(char *pathstr, int32_t *value);
670 
671 /**
672  * @brief Get resource (instance) value (s64)
673  *
674  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
675  * @param[out] value s64 buffer to copy data into
676  *
677  * @return 0 for success or negative in case of error.
678  */
679 int lwm2m_engine_get_s64(char *pathstr, int64_t *value);
680 
681 /**
682  * @brief Get resource (instance) value (bool)
683  *
684  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
685  * @param[out] value bool buffer to copy data into
686  *
687  * @return 0 for success or negative in case of error.
688  */
689 int lwm2m_engine_get_bool(char *pathstr, bool *value);
690 
691 /**
692  * @brief Get resource (instance) value (32-bit float structure)
693  *
694  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
695  * @param[out] buf 32-bit float buffer to copy data into
696  *
697  * @return 0 for success or negative in case of error.
698  */
699 int lwm2m_engine_get_float32(char *pathstr, float32_value_t *buf);
700 
701 /**
702  * @brief Get resource (instance) value (ObjLnk)
703  *
704  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
705  * @param[out] buf lwm2m_objlnk buffer to copy data into
706  *
707  * @return 0 for success or negative in case of error.
708  */
709 int lwm2m_engine_get_objlnk(char *pathstr, struct lwm2m_objlnk *buf);
710 
711 
712 /**
713  * @brief Set resource (instance) read callback
714  *
715  * LwM2M clients can use this to set the callback function for resource reads.
716  *
717  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
718  * @param[in] cb Read resource callback
719  *
720  * @return 0 for success or negative in case of error.
721  */
722 int lwm2m_engine_register_read_callback(char *pathstr,
723 					lwm2m_engine_get_data_cb_t cb);
724 
725 /**
726  * @brief Set resource (instance) pre-write callback
727  *
728  * This callback is triggered before setting the value of a resource.  It
729  * can pass a special data buffer to the engine so that the actual resource
730  * value can be calculated later, etc.
731  *
732  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
733  * @param[in] cb Pre-write resource callback
734  *
735  * @return 0 for success or negative in case of error.
736  */
737 int lwm2m_engine_register_pre_write_callback(char *pathstr,
738 					     lwm2m_engine_get_data_cb_t cb);
739 
740 /**
741  * @brief Set resource (instance) validation callback
742  *
743  * This callback is triggered before setting the value of a resource to the
744  * resource data buffer.
745  *
746  * The callback allows an LwM2M client or object to validate the data before
747  * writing and notify an error if the data should be discarded for any reason
748  * (by returning a negative error code).
749  *
750  * @note All resources that have a validation callback registered are initially
751  *       decoded into a temporary validation buffer. Make sure that
752  *       ``CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE`` is large enough to
753  *       store each of the validated resources (individually).
754  *
755  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
756  * @param[in] cb Validate resource data callback
757  *
758  * @return 0 for success or negative in case of error.
759  */
760 int lwm2m_engine_register_validate_callback(char *pathstr,
761 					    lwm2m_engine_set_data_cb_t cb);
762 
763 /**
764  * @brief Set resource (instance) post-write callback
765  *
766  * This callback is triggered after setting the value of a resource to the
767  * resource data buffer.
768  *
769  * It allows an LwM2M client or object to post-process the value of a resource
770  * or trigger other related resource calculations.
771  *
772  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
773  * @param[in] cb Post-write resource callback
774  *
775  * @return 0 for success or negative in case of error.
776  */
777 int lwm2m_engine_register_post_write_callback(char *pathstr,
778 					      lwm2m_engine_set_data_cb_t cb);
779 
780 /**
781  * @brief Set resource execute event callback
782  *
783  * This event is triggered when the execute method of a resource is enabled.
784  *
785  * @param[in] pathstr LwM2M path string "obj/obj-inst/res"
786  * @param[in] cb Execute resource callback
787  *
788  * @return 0 for success or negative in case of error.
789  */
790 int lwm2m_engine_register_exec_callback(char *pathstr,
791 					lwm2m_engine_execute_cb_t cb);
792 
793 /**
794  * @brief Set object instance create event callback
795  *
796  * This event is triggered when an object instance is created.
797  *
798  * @param[in] obj_id LwM2M object id
799  * @param[in] cb Create object instance callback
800  *
801  * @return 0 for success or negative in case of error.
802  */
803 int lwm2m_engine_register_create_callback(uint16_t obj_id,
804 					  lwm2m_engine_user_cb_t cb);
805 
806 /**
807  * @brief Set object instance delete event callback
808  *
809  * This event is triggered when an object instance is deleted.
810  *
811  * @param[in] obj_id LwM2M object id
812  * @param[in] cb Delete object instance callback
813  *
814  * @return 0 for success or negative in case of error.
815  */
816 int lwm2m_engine_register_delete_callback(uint16_t obj_id,
817 					  lwm2m_engine_user_cb_t cb);
818 
819 /**
820  * @brief Resource read-only value bit
821  */
822 #define LWM2M_RES_DATA_READ_ONLY	0
823 
824 /**
825  * @brief Resource read-only flag
826  */
827 #define LWM2M_RES_DATA_FLAG_RO		BIT(LWM2M_RES_DATA_READ_ONLY)
828 
829 /**
830  * @brief Read resource flags helper macro
831  */
832 #define LWM2M_HAS_RES_FLAG(res, f)	((res->data_flags & f) == f)
833 
834 /**
835  * @brief Set data buffer for a resource
836  *
837  * Use this function to set the data buffer and flags for the specified LwM2M
838  * resource.
839  *
840  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
841  * @param[in] data_ptr Data buffer pointer
842  * @param[in] data_len Length of buffer
843  * @param[in] data_flags Data buffer flags (such as read-only, etc)
844  *
845  * @return 0 for success or negative in case of error.
846  */
847 int lwm2m_engine_set_res_data(char *pathstr, void *data_ptr, uint16_t data_len,
848 			      uint8_t data_flags);
849 
850 /**
851  * @brief Get data buffer for a resource
852  *
853  * Use this function to get the data buffer information for the specified LwM2M
854  * resource.
855  *
856  * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)"
857  * @param[out] data_ptr Data buffer pointer
858  * @param[out] data_len Length of buffer
859  * @param[out] data_flags Data buffer flags (such as read-only, etc)
860  *
861  * @return 0 for success or negative in case of error.
862  */
863 int lwm2m_engine_get_res_data(char *pathstr, void **data_ptr,
864 			      uint16_t *data_len, uint8_t *data_flags);
865 
866 /**
867  * @brief Create a resource instance
868  *
869  * LwM2M clients use this function to create multi-resource instances:
870  * Example to create 0 instance of device available power sources:
871  * lwm2m_engine_create_res_inst("3/0/6/0");
872  *
873  * @param[in] pathstr LwM2M path string "obj/obj-inst/res/res-inst"
874  *
875  * @return 0 for success or negative in case of error.
876  */
877 int lwm2m_engine_create_res_inst(char *pathstr);
878 
879 /**
880  * @brief Delete a resource instance
881  *
882  * Use this function to remove an existing resource instance
883  *
884  * @param[in] pathstr LwM2M path string "obj/obj-inst/res/res-inst"
885  *
886  * @return 0 for success or negative in case of error.
887  */
888 int lwm2m_engine_delete_res_inst(char *pathstr);
889 
890 /**
891  * @brief Update the period of a given service.
892  *
893  * Allow the period modification on an existing service created with
894  * lwm2m_engine_add_service().
895  * Example to frequency at which a periodic_service changes it's values :
896  * lwm2m_engine_update_service(device_periodic_service,5*MSEC_PER_SEC);
897  *
898  * @param[in] service Handler of the periodic_service
899  * @param[in] period_ms New period for the periodic_service (in milliseconds)
900  *
901  * @return 0 for success or negative in case of error.
902  */
903 int lwm2m_engine_update_service_period(k_work_handler_t service, uint32_t period_ms);
904 
905 /**
906  * @brief Start the LwM2M engine
907  *
908  * LwM2M clients normally do not need to call this function as it is called
909  * by lwm2m_rd_client_start().  However, if the client does not use the RD
910  * client implementation, it will need to be called manually.
911  *
912  * @param[in] client_ctx LwM2M context
913  *
914  * @return 0 for success or negative in case of error.
915  */
916 int lwm2m_engine_start(struct lwm2m_ctx *client_ctx);
917 
918 /**
919  * @brief Acknowledge the currently processed request with an empty ACK.
920  *
921  * LwM2M engine by default sends piggybacked responses for requests.
922  * This function allows to send an empty ACK for a request earlier (from the
923  * application callback). The LwM2M engine will then send the actual response
924  * as a separate CON message after all callbacks are executed.
925  *
926  * @param[in] client_ctx LwM2M context
927  *
928  */
929 void lwm2m_acknowledge(struct lwm2m_ctx *client_ctx);
930 
931 /**
932  * @brief LwM2M RD client events
933  *
934  * LwM2M client events are passed back to the event_cb function in
935  * lwm2m_rd_client_start()
936  */
937 enum lwm2m_rd_client_event {
938 	LWM2M_RD_CLIENT_EVENT_NONE,
939 	LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE,
940 	LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE,
941 	LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE,
942 	LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE,
943 	LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE,
944 	LWM2M_RD_CLIENT_EVENT_REG_UPDATE_FAILURE,
945 	LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE,
946 	LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE,
947 	LWM2M_RD_CLIENT_EVENT_DISCONNECT,
948 	LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF,
949 	LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR,
950 };
951 
952 /*
953  * LwM2M RD client flags, used to configure LwM2M session.
954  */
955 
956 /**
957  * @brief Run bootstrap procedure in current session.
958  */
959 #define LWM2M_RD_CLIENT_FLAG_BOOTSTRAP BIT(0)
960 
961 /**
962  * @brief Asynchronous RD client event callback
963  *
964  * @param[in] ctx LwM2M context generating the event
965  * @param[in] event LwM2M RD client event code
966  */
967 typedef void (*lwm2m_ctx_event_cb_t)(struct lwm2m_ctx *ctx,
968 				     enum lwm2m_rd_client_event event);
969 
970 /**
971  * @brief Start the LwM2M RD (Registration / Discovery) Client
972  *
973  * The RD client sits just above the LwM2M engine and performs the necessary
974  * actions to implement the "Registration interface".
975  * For more information see Section 5.3 "Client Registration Interface" of the
976  * LwM2M Technical Specification.
977  *
978  * NOTE: lwm2m_engine_start() is called automatically by this function.
979  *
980  * @param[in] client_ctx LwM2M context
981  * @param[in] ep_name Registered endpoint name
982  * @param[in] flags Flags used to configure current LwM2M session.
983  * @param[in] event_cb Client event callback function
984  */
985 void lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name,
986 			   uint32_t flags, lwm2m_ctx_event_cb_t event_cb);
987 
988 /**
989  * @brief Stop the LwM2M RD (De-register) Client
990  *
991  * The RD client sits just above the LwM2M engine and performs the necessary
992  * actions to implement the "Registration interface".
993  * For more information see Section 5.3 "Client Registration Interface" of the
994  * LwM2M Technical Specification.
995  *
996  * @param[in] client_ctx LwM2M context
997  * @param[in] event_cb Client event callback function
998  */
999 void lwm2m_rd_client_stop(struct lwm2m_ctx *client_ctx,
1000 			  lwm2m_ctx_event_cb_t event_cb);
1001 
1002 /**
1003  * @brief Trigger a Registration Update of the LwM2M RD Client
1004  */
1005 void lwm2m_rd_client_update(void);
1006 
1007 #endif	/* ZEPHYR_INCLUDE_NET_LWM2M_H_ */
1008 /**@}  */
1009