1.. _lwm2m_interface:
2
3Lightweight M2M (LWM2M)
4#######################
5
6.. contents::
7    :local:
8    :depth: 2
9
10Overview
11********
12
13Lightweight Machine to Machine (LwM2M) is an application layer protocol
14designed with device management, data reporting and device actuation in mind.
15Based on CoAP/UDP, `LwM2M`_ is a
16`standard <http://openmobilealliance.org/release/LightweightM2M/>`_ defined by
17the Open Mobile Alliance and suitable for constrained devices by its use of
18CoAP packet-size optimization and a simple, stateless flow that supports a
19REST API.
20
21One of the key differences between LwM2M and CoAP is that an LwM2M client
22initiates the connection to an LwM2M server.  The server can then use the
23REST API to manage various interfaces with the client.
24
25LwM2M uses a simple resource model with the core set of objects and resources
26defined in the specification.
27
28The LwM2M library can be enabled with :kconfig:option:`CONFIG_LWM2M` Kconfig option.
29
30Example LwM2M object and resources: Device
31******************************************
32
33*Object definition*
34
35.. list-table::
36   :header-rows: 1
37
38   * - Object ID
39     - Name
40     - Instance
41     - Mandatory
42
43   * - 3
44     - Device
45     - Single
46     - Mandatory
47
48*Resource definitions*
49
50``* R=Read, W=Write, E=Execute``
51
52.. list-table::
53   :header-rows: 1
54
55   * - ID
56     - Name
57     - OP\*
58     - Instance
59     - Mandatory
60     - Type
61
62   * - 0
63     - Manufacturer
64     - R
65     - Single
66     - Optional
67     - String
68
69   * - 1
70     - Model
71     - R
72     - Single
73     - Optional
74     - String
75
76   * - 2
77     - Serial number
78     - R
79     - Single
80     - Optional
81     - String
82
83   * - 3
84     - Firmware version
85     - R
86     - Single
87     - Optional
88     - String
89
90   * - 4
91     - Reboot
92     - E
93     - Single
94     - Mandatory
95     -
96
97   * - 5
98     - Factory Reset
99     - E
100     - Single
101     - Optional
102     -
103
104   * - 6
105     - Available Power Sources
106     - R
107     - Multiple
108     - Optional
109     - Integer 0-7
110
111   * - 7
112     - Power Source Voltage (mV)
113     - R
114     - Multiple
115     - Optional
116     - Integer
117
118   * - 8
119     - Power Source Current (mA)
120     - R
121     - Multiple
122     - Optional
123     - Integer
124
125   * - 9
126     - Battery Level %
127     - R
128     - Single
129     - Optional
130     - Integer
131
132   * - 10
133     - Memory Free (Kb)
134     - R
135     - Single
136     - Optional
137     - Integer
138
139   * - 11
140     - Error Code
141     - R
142     - Multiple
143     - Optional
144     - Integer 0-8
145
146   * - 12
147     - Reset Error
148     - E
149     - Single
150     - Optional
151     -
152
153   * - 13
154     - Current Time
155     - RW
156     - Single
157     - Optional
158     - Time
159
160   * - 14
161     - UTC Offset
162     - RW
163     - Single
164     - Optional
165     - String
166
167   * - 15
168     - Timezone
169     - RW
170     - Single
171     - Optional
172     - String
173
174   * - 16
175     - Supported Binding
176     - R
177     - Single
178     - Mandatory
179     - String
180
181   * - 17
182     - Device Type
183     - R
184     - Single
185     - Optional
186     - String
187
188   * - 18
189     - Hardware Version
190     - R
191     - Single
192     - Optional
193     - String
194
195   * - 19
196     - Software Version
197     - R
198     - Single
199     - Optional
200     - String
201
202   * - 20
203     - Battery Status
204     - R
205     - Single
206     - Optional
207     - Integer 0-6
208
209   * - 21
210     - Memory Total (Kb)
211     - R
212     - Single
213     - Optional
214     - Integer
215
216   * - 22
217     - ExtDevInfo
218     - R
219     - Multiple
220     - Optional
221     - ObjLnk
222
223The server could query the ``Manufacturer`` resource for ``Device`` object
224instance 0 (the default and only instance) by sending a ``READ 3/0/0``
225operation to the client.
226
227The full list of registered objects and resource IDs can be found in the
228`LwM2M registry`_.
229
230Zephyr's LwM2M library lives in the :zephyr_file:`subsys/net/lib/lwm2m`, with a
231client sample in :zephyr_file:`samples/net/lwm2m_client`.  For more information
232about the provided sample see: :zephyr:code-sample:`lwm2m-client`. The sample can be
233configured to use normal unsecure network sockets or sockets secured via DTLS.
234
235The Zephyr LwM2M library implements the following items:
236
237* engine to process networking events and core functions
238* RD client which performs BOOTSTRAP and REGISTRATION functions
239* SenML CBOR, SenML JSON, CBOR, TLV, JSON, and plain text formatting functions
240* LwM2M Technical Specification Enabler objects such as Security, Server,
241  Device, Firmware Update, etc.
242* Extended IPSO objects such as Light Control, Temperature Sensor, and Timer
243
244By default, the library implements `LwM2M specification 1.0.2`_ and can be set to
245`LwM2M specification 1.1.1`_ with a Kconfig option.
246
247For more information about LwM2M visit `OMA Specworks LwM2M`_.
248
249Sample usage
250************
251
252To use the LwM2M library, start by creating an LwM2M client context
253:c:struct:`lwm2m_ctx` structure:
254
255.. code-block:: c
256
257	/* LwM2M client context */
258	static struct lwm2m_ctx client;
259
260Create callback functions for LwM2M resource executions:
261
262.. code-block:: c
263
264	static int device_reboot_cb(uint16_t obj_inst_id, uint8_t *args,
265				    uint16_t args_len)
266	{
267		LOG_INF("Device rebooting.");
268		LOG_PANIC();
269		sys_reboot(0);
270		return 0; /* won't reach this */
271	}
272
273The LwM2M RD client can send events back to the sample.  To receive those
274events, setup a callback function:
275
276.. code-block:: c
277
278	static void rd_client_event(struct lwm2m_ctx *client,
279				    enum lwm2m_rd_client_event client_event)
280	{
281		switch (client_event) {
282
283		case LWM2M_RD_CLIENT_EVENT_NONE:
284			/* do nothing */
285			break;
286
287		case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE:
288			LOG_DBG("Bootstrap registration failure!");
289			break;
290
291		case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE:
292			LOG_DBG("Bootstrap registration complete");
293			break;
294
295		case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE:
296			LOG_DBG("Bootstrap transfer complete");
297			break;
298
299		case LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE:
300			LOG_DBG("Registration failure!");
301			break;
302
303		case LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE:
304			LOG_DBG("Registration complete");
305			break;
306
307		case LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT:
308			LOG_DBG("Registration timeout!");
309			break;
310
311		case LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE:
312			LOG_DBG("Registration update complete");
313			break;
314
315		case LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE:
316			LOG_DBG("Deregister failure!");
317			break;
318
319		case LWM2M_RD_CLIENT_EVENT_DISCONNECT:
320			LOG_DBG("Disconnected");
321			break;
322
323		case LWM2M_RD_CLIENT_EVENT_REG_UPDATE:
324			LOG_DBG("Registration update");
325			break;
326
327		case LWM2M_RD_CLIENT_EVENT_DEREGISTER:
328			LOG_DBG("Deregistration client");
329			break;
330
331		case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED:
332			LOG_DBG("LwM2M server disabled");
333		  break;
334		}
335	}
336
337Next we assign ``Security`` resource values to let the client know where and how
338to connect as well as set the ``Manufacturer`` and ``Reboot`` resources in the
339``Device`` object with some data and the callback we defined above:
340
341.. code-block:: c
342
343	/*
344	 * Server URL of default Security object = 0/0/0
345	 * Use leshan.eclipse.org server IP (5.39.83.206) for connection
346	 */
347	lwm2m_set_string(&LWM2M_OBJ(0, 0, 0), "coap://5.39.83.206");
348
349	/*
350	 * Security Mode of default Security object = 0/0/2
351	 * 3 = NoSec mode (no security beware!)
352	 */
353	lwm2m_set_u8(&LWM2M_OBJ(0, 0, 2), 3);
354
355	#define CLIENT_MANUFACTURER "Zephyr Manufacturer"
356
357	/*
358	 * Manufacturer resource of Device object = 3/0/0
359	 * We use lwm2m_set_res_data() function to set a pointer to the
360	 * CLIENT_MANUFACTURER string.
361	 * Note the LWM2M_RES_DATA_FLAG_RO flag which stops the engine from
362	 * trying to assign a new value to the buffer.
363	 */
364	lwm2m_set_res_data(&LWM2M_OBJ(3, 0, 0), CLIENT_MANUFACTURER,
365			   sizeof(CLIENT_MANUFACTURER),
366			   LWM2M_RES_DATA_FLAG_RO);
367
368	/* Reboot resource of Device object = 3/0/4 */
369	lwm2m_register_exec_callback(&LWM2M_OBJ(3, 0, 4), device_reboot_cb);
370
371Lastly, we start the LwM2M RD client (which in turn starts the LwM2M engine).
372The second parameter of :c:func:`lwm2m_rd_client_start` is the client
373endpoint name.  This is important as it needs to be unique per LwM2M server:
374
375.. code-block:: c
376
377	(void)memset(&client, 0x0, sizeof(client));
378	lwm2m_rd_client_start(&client, "unique-endpoint-name", 0, rd_client_event);
379
380.. _lwm2m_security:
381
382LwM2M security modes
383********************
384
385The Zephyr LwM2M library can be used either without security or use DTLS to secure the communication channel.
386When using DTLS with the LwM2M engine, PSK (Pre-Shared Key) and X.509 certificates are the security modes that can be used to secure the communication.
387The engine uses LwM2M Security object (Id 0) to read the stored credentials and feed keys from the security object into
388the TLS credential subsystem, see :ref:`secure sockets documentation <secure_sockets_interface>`.
389Enable the :kconfig:option:`CONFIG_LWM2M_DTLS_SUPPORT` Kconfig option to use the security.
390
391Depending on the selected mode, the security object must contain following data:
392
393PSK
394  Security Mode (Resource ID 2) set to zero (Pre-Shared Key mode).
395  Identity (Resource ID 3) contains PSK ID in binary form.
396  Secret key (Resource ID 5) contains the PSK key in binary form.
397  If the key or identity is provided as a hex string, it must be converted to binary before storing into the security object.
398
399X509
400  When X509 certificates are used, set Security Mode (ID 2) to ``2`` (Certificate mode).
401  Identity (ID 3) is used to store the client certificate and Secret key (ID 5) must have a private key associated with the certificate.
402  Server Public Key resource (ID 4) must contain a server certificate or CA certificate used to sign the certificate chain.
403  If the :kconfig:option:`CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT` Kconfig option is enabled, certificates and private key can be entered in PEM format.
404  Otherwise, they must be in binary DER format.
405
406NoSec
407  When no security is used, set Security Mode (Resource ID 2) to ``3`` (NoSec).
408
409In all modes, Server URI resource (ID 0) must contain the full URI for the target server.
410When DNS names are used, the DNS resolver must be enabled.
411
412When DTLS is used, following options are recommended to reduce DTLS handshake traffic when connection is re-established:
413
414* :kconfig:option:`CONFIG_LWM2M_DTLS_CID` enables DTLS Connection Identifier support. When server supports it, this completely removes the handshake when device resumes operation after long idle period. Greatly helps when NAT mappings have timed out.
415* :kconfig:option:`CONFIG_LWM2M_TLS_SESSION_CACHING` uses session cache when before falling back to full DTLS handshake. Reduces few packets from handshake, when session is still cached on server side. Most significant effect is to avoid full registration.
416
417LwM2M stack provides callbacks in the :c:struct:`lwm2m_ctx` structure.
418They are used to feed keys from the LwM2M security object into the TLS credential subsystem.
419By default, these callbacks can be left as NULL pointers, in which case default callbacks are used.
420When an external TLS stack, or non-default socket options are required, you can overwrite the :c:func:`lwm2m_ctx.load_credentials` or :c:func:`lwm2m_ctx.set_socketoptions` callbacks.
421
422An example of setting up the security object for PSK mode:
423
424.. code-block:: c
425
426	/* "000102030405060708090a0b0c0d0e0f" */
427	static unsigned char client_psk[] = {
428		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
429		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
430	};
431
432	static const char client_identity[] = "Client_identity";
433
434	lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 0), "coaps://lwm2m.example.com");
435	lwm2m_set_u8(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 2), LWM2M_SECURITY_PSK);
436	/* Set the client identity as a string, but this could be binary as well */
437	lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 3), client_identity);
438	/* Set the client pre-shared key (PSK) */
439	lwm2m_set_opaque(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 5), client_psk, sizeof(client_psk));
440
441An example of setting up the security object for X509 certificate mode:
442
443.. code-block:: c
444
445	static const char certificate[] = "-----BEGIN CERTIFICATE-----\nMIIB6jCCAY+gAw...";
446	static const char key[] = "-----BEGIN EC PRIVATE KEY-----\nMHcCAQ...";
447	static const char root_ca[] = "-----BEGIN CERTIFICATE-----\nMIIBaz...";
448
449	lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 0), "coaps://lwm2m.example.com");
450	lwm2m_set_u8(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 2), LWM2M_SECURITY_CERT);
451	lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 3), certificate);
452	lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 5), key);
453	lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 4), root_ca);
454
455Before calling :c:func:`lwm2m_rd_client_start` assign the tls_tag # where the
456LwM2M library should store the DTLS information prior to connection (normally a
457value of 1 is ok here).
458
459.. code-block:: c
460
461	(void)memset(&client, 0x0, sizeof(client));
462	client.tls_tag = 1; /* <---- */
463	lwm2m_rd_client_start(&client, "endpoint-name", 0, rd_client_event);
464
465For a more detailed LwM2M client sample see: :zephyr:code-sample:`lwm2m-client`.
466
467Multi-thread usage
468******************
469Writing a value to a resource can be done using functions like lwm2m_set_u8. When writing
470to multiple resources, the function lwm2m_registry_lock will ensure that the
471client halts until all writing operations are finished:
472
473.. code-block:: c
474
475  lwm2m_registry_lock();
476  lwm2m_set_u32(&LWM2M_OBJ(1, 0, 1), 60);
477  lwm2m_set_u8(&LWM2M_OBJ(5, 0, 3), 0);
478  lwm2m_set_f64(&LWM2M_OBJ(3303, 0, 5700), value);
479  lwm2m_registry_unlock();
480
481This is especially useful if the server is composite-observing the resources being
482written to. Locking will then ensure that the client only updates and sends notifications
483to the server after all operations are done, resulting in fewer messages in general.
484
485Support for time series data
486****************************
487
488LwM2M version 1.1 adds support for SenML CBOR and SenML JSON data formats. These data formats add
489support for time series data. Time series formats can be used for READ, NOTIFY and SEND operations.
490When data cache is enabled for a resource, each write will create a timestamped entry in a cache,
491and its content is then returned as a content in READ, NOTIFY or SEND operation for a given
492resource.
493
494Data cache is only supported for resources with a fixed data size.
495
496Supported resource types:
497
498* Signed and unsigned 8-64-bit integers
499* Float
500* Boolean
501
502Enabling and configuring
503========================
504
505Enable data cache by selecting :kconfig:option:`CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT`.
506Application needs to allocate an array of :c:struct:`lwm2m_time_series_elem` structures and then
507enable the cache by calling :c:func:`lwm2m_enable_cache` for a given resource. Each resource
508must be enabled separately and each resource needs their own storage.
509
510.. code-block:: c
511
512  /* Allocate data cache storage */
513  static struct lwm2m_time_series_elem temperature_cache[10];
514  /* Enable data cache */
515  lwm2m_enable_cache(LWM2M_OBJ(IPSO_OBJECT_TEMP_SENSOR_ID, 0, SENSOR_VALUE_RID),
516          temperature_cache, ARRAY_SIZE(temperature_cache));
517
518LwM2M engine have room for four resources that have cache enabled. Limit can be increased by
519changing :kconfig:option:`CONFIG_LWM2M_MAX_CACHED_RESOURCES`. This affects a static memory usage of
520engine.
521
522Data caches depends on one of the SenML data formats
523:kconfig:option:`CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT` or
524:kconfig:option:`CONFIG_LWM2M_RW_SENML_JSON_SUPPORT` and needs :kconfig:option:`CONFIG_POSIX_TIMERS`
525so it can request a timestamp from the system and :kconfig:option:`CONFIG_RING_BUFFER` for ring
526buffer.
527
528Read and Write operations
529=========================
530
531Full content of data cache is written into a payload when any READ, SEND or NOTIFY operation
532internally reads the content of a given resource. This has a side effect that any read callbacks
533registered for a that resource are ignored when cache is enabled.
534Data is written into a cache when any of the ``lwm2m_set_*`` functions are called. To filter
535the data entering the cache, application may register a validation callback using
536:c:func:`lwm2m_register_validate_callback`.
537
538Limitations
539===========
540
541Cache size should be manually set so small that the content can fit normal packets sizes.
542When cache is full, new values are dropped.
543
544LwM2M engine and application events
545***********************************
546
547The Zephyr LwM2M engine defines events that can be sent back to the application through callback
548functions.
549The engine state machine shows when the events are spawned.
550Events depicted in the diagram are listed in the table.
551The events are prefixed with ``LWM2M_RD_CLIENT_EVENT_``.
552
553.. figure:: images/lwm2m_engine_state_machine.svg
554    :alt: LwM2M engine state machine
555
556    State machine for the LwM2M engine
557
558.. list-table:: LwM2M RD Client events
559   :widths: auto
560   :header-rows: 1
561
562   * - Event ID
563     - Event Name
564     - Description
565   * - 0
566     - NONE
567     - No event
568   * - 1
569     - BOOTSTRAP_REG_FAILURE
570     - Bootstrap registration failed.
571       Occurs if there is a timeout or failure in bootstrap registration.
572   * - 2
573     - BOOTSTRAP_REG_COMPLETE
574     - Bootstrap registration complete.
575       Occurs after successful bootstrap registration.
576   * - 3
577     - BOOTSTRAP_TRANSFER_COMPLETE
578     - Bootstrap finish command received from the server.
579   * - 4
580     - REGISTRATION_FAILURE
581     - Registration to LwM2M server failed.
582       Occurs if server rejects the registration attempt.
583   * - 5
584     - REGISTRATION_COMPLETE
585     - Registration to LwM2M server successful.
586       Occurs after a successful registration reply from the LwM2M server
587       or when session resumption is used.
588   * - 6
589     - REG_TIMEOUT
590     - Registration status lost.
591       Occurs if there is socket errors or message timeouts. Client have lost connection to the server.
592   * - 7
593     - REG_UPDATE_COMPLETE
594     - Registration update completed.
595       Occurs after successful registration update reply from the LwM2M server.
596   * - 8
597     - DEREGISTER_FAILURE
598     - Deregistration to LwM2M server failed.
599       Occurs if there is a timeout or failure in the deregistration.
600   * - 9
601     - DISCONNECT
602     - LwM2M client have de-registered from server and is now stopped.
603       Triggered only if the application have requested the client to stop.
604   * - 10
605     - QUEUE_MODE_RX_OFF
606     - Used only in queue mode, not actively listening for incoming packets.
607       In queue mode the client is not required to actively listen for the incoming packets
608       after a configured time period.
609   * - 11
610     - ENGINE_SUSPENDED
611     - Indicate that client has now paused as a result of calling :c:func:`lwm2m_engine_pause`.
612       State machine is no longer running and the handler thread is suspended.
613       All timers are stopped so notifications are not triggered.
614   * - 12
615     - SERVER_DISABLED
616     - Server have executed the disable command.
617       Client will deregister and stay idle for the disable period.
618   * - 13
619     - NETWORK_ERROR
620     - Sending messages to the network failed too many times.
621       Client cannot reach any servers or fallback to bootstrap.
622       LwM2M engine cannot recover and have stopped.
623
624The LwM2M client engine handles most of the state transitions automatically. The application
625needs to handle only the events that indicate that the client have stopped or is in a state
626where it cannot recover.
627
628.. list-table:: How application should react to events
629   :widths: auto
630   :header-rows: 1
631
632   * - Event Name
633     - How application should react
634   * - NONE
635     - Ignore the event.
636   * - BOOTSTRAP_REG_FAILURE
637     - Try to recover network connection. Then restart the client by calling :c:func:`lwm2m_rd_client_start`.
638       This might also indicate configuration issue.
639   * - BOOTSTRAP_REG_COMPLETE
640     - No actions needed
641   * - BOOTSTRAP_TRANSFER_COMPLETE
642     - No actions needed
643   * - REGISTRATION_FAILURE
644     - No actions needed.
645       Client proceeds re-registration automatically. Might need a bootstrap or configuration fix. Cannot send or receive data.
646   * - REGISTRATION_COMPLETE
647     - No actions needed.
648       Application can send or receive data.
649   * - REG_TIMEOUT
650     - No actions needed.
651       Client proceeds to re-registration automatically. Cannot send or receive data.
652   * - REG_UPDATE_COMPLETE
653     - No actions needed
654       Application can send or receive data.
655   * - DEREGISTER_FAILURE
656     - No actions needed, client proceeds to idle state automatically. Cannot send or receive data.
657   * - DISCONNECT
658     - Engine have stopped as a result of calling :c:func:`lwm2m_rd_client_stop`.
659       If connection is required, the application should restart the client by calling :c:func:`lwm2m_rd_client_start`.
660   * - QUEUE_MODE_RX_OFF
661     - No actions needed.
662       Application can send but cannot receive data.
663       Any data transmission will trigger a registration update.
664   * - ENGINE_SUSPENDED
665     - Engine can be resumed by calling :c:func:`lwm2m_engine_resume`.
666       Cannot send or receive data.
667   * - SERVER_DISABLED
668     - No actions needed, client will re-register once the disable period is over.
669       Cannot send or receive data.
670   * - NETWORK_ERROR
671     - Try to recover network connection. Then restart the client by calling :c:func:`lwm2m_rd_client_start`.
672       This might also indicate configuration issue.
673
674Sending of data in the table above refers to calling :c:func:`lwm2m_send_cb` or by writing into one of the observed resources where observation would trigger a notify message.
675Receiving of data refers to receiving read, write or execute operations from the server. Application can register callbacks for these operations.
676
677Configuring lifetime and activity period
678****************************************
679
680In LwM2M engine, there are three Kconfig options and one runtime value that configures how often the
681client will send LwM2M Update message.
682
683.. list-table:: Update period variables
684   :widths: auto
685   :header-rows: 1
686
687   * - Variable
688     - Effect
689   * - LwM2M registration lifetime
690     - The lifetime parameter in LwM2M specifies how long a device's registration with an LwM2M server remains valid.
691       Device is expected to send LwM2M Update message before the lifetime exprires.
692   * - :kconfig:option:`CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME`
693     - Default lifetime value, unless set by the bootstrap server.
694       Also defines lower limit that client accepts as a lifetime.
695   * - :kconfig:option:`CONFIG_LWM2M_UPDATE_PERIOD`
696     - How long the client can stay idle before sending a next update.
697   * - :kconfig:option:`CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY`
698     - Minimum time margin to send the update message before the registration lifetime expires.
699
700.. figure:: images/lwm2m_lifetime_seconds_early.png
701    :alt: LwM2M seconds to update early
702
703    Default way of calculating when to update registration.
704
705By default, the client uses :kconfig:option:`CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY` to calculate how
706many seconds before the expiration of lifetime it is going to send the registration update.
707The problem with default mode is when the server changes the lifetime of the registration.
708This is then affecting the period of updates the client is doing.
709If this is used with the QUEUE mode, which is typical in IPv4 networks, it is also affecting the
710period of when the device is reachable from the server.
711
712.. figure:: images/lwm2m_lifetime_both.png
713    :alt: LwM2M update time when both values are set
714
715    Update time is controlled by UPDATE_PERIOD.
716
717When also the :kconfig:option:`CONFIG_LWM2M_UPDATE_PERIOD` is set, time to send the update message
718is the earliest when any of these values expire. This allows setting long lifetime for the
719registration and configure the period accurately, even if server changes the lifetime parameter.
720
721In runtime, the update frequency is limited to once in 15 seconds to avoid flooding.
722
723.. _lwm2m_shell:
724
725LwM2M shell
726***********
727For testing the client it is possible to enable Zephyr's shell and LwM2M specific commands which
728support changing the state of the client. Operations supported are read, write and execute
729resources. Client start, stop, pause and resume are also available. The feature is enabled by
730selecting :kconfig:option:`CONFIG_LWM2M_SHELL`. The shell is meant for testing so productions
731systems should not enable it.
732
733One imaginable scenario, where to use the shell, would be executing client side actions over UART
734when a server side tests would require those. It is assumed that not all tests are able to trigger
735required actions from the server side.
736
737.. code-block:: console
738
739  uart:~$ lwm2m
740  lwm2m - LwM2M commands
741  Subcommands:
742    send    :send PATHS
743            LwM2M SEND operation
744
745    exec    :exec PATH [PARAM]
746            Execute a resource
747
748    read    :read PATH [OPTIONS]
749            Read value from LwM2M resource
750            -x   Read value as hex stream (default)
751            -s   Read value as string
752            -b   Read value as bool (1/0)
753            -uX  Read value as uintX_t
754            -sX  Read value as intX_t
755            -f   Read value as float
756            -t   Read value as time_t
757
758    write   :write PATH [OPTIONS] VALUE
759            Write into LwM2M resource
760            -s   Write value as string (default)
761            -b   Write value as bool
762            -uX  Write value as uintX_t
763            -sX  Write value as intX_t
764            -f   Write value as float
765            -t   Write value as time_t
766
767    create  :create PATH
768            Create object or resource instance
769
770    delete  :delete PATH
771            Delete object or resource instance
772
773    cache   :cache PATH NUM
774            Enable data cache for resource
775            PATH is LwM2M path
776            NUM how many elements to cache
777
778    start   :start EP_NAME [BOOTSTRAP FLAG]
779            Start the LwM2M RD (Registration / Discovery) Client
780            -b   Set the bootstrap flag (default 0)
781
782    stop    :stop [OPTIONS]
783            Stop the LwM2M RD (De-register) Client
784            -f   Force close the connection
785
786    update  :Trigger Registration Update of the LwM2M RD Client
787
788    pause   :LwM2M engine thread pause
789    resume  :LwM2M engine thread resume
790    lock    :Lock the LwM2M registry
791    unlock  :Unlock the LwM2M registry
792    obs     : List observations
793    ls      : ls [PATH]
794            List objects, instances, resources
795
796
797
798
799.. _lwm2m_api_reference:
800
801API Reference
802*************
803
804.. doxygengroup:: lwm2m_api
805
806.. _LwM2M:
807   https://www.omaspecworks.org/what-is-oma-specworks/iot/lightweight-m2m-lwm2m/
808
809.. _LwM2M registry:
810   http://www.openmobilealliance.org/wp/OMNA/LwM2M/LwM2MRegistry.html
811
812.. _OMA Specworks LwM2M:
813   https://www.omaspecworks.org/what-is-oma-specworks/iot/lightweight-m2m-lwm2m/
814
815.. _LwM2M specification 1.0.2:
816   http://openmobilealliance.org/release/LightweightM2M/V1_0_2-20180209-A/OMA-TS-LightweightM2M-V1_0_2-20180209-A.pdf
817
818.. _LwM2M specification 1.1.1:
819   http://openmobilealliance.org/release/LightweightM2M/V1_1_1-20190617-A/
820