diff --git a/doc/connectivity/networking/api/images/lwm2m_lifetime_both.png b/doc/connectivity/networking/api/images/lwm2m_lifetime_both.png new file mode 100644 index 00000000000..1cdf0bbb662 Binary files /dev/null and b/doc/connectivity/networking/api/images/lwm2m_lifetime_both.png differ diff --git a/doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png b/doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png new file mode 100644 index 00000000000..119005ce5c7 Binary files /dev/null and b/doc/connectivity/networking/api/images/lwm2m_lifetime_seconds_early.png differ diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index ce6cafd53a7..83ed71523e7 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -625,6 +625,53 @@ The events are prefixed with ``LWM2M_RD_CLIENT_EVENT_``. If the retry counter reaches its limits, this event will be triggered. - No actions needed, client will do a re-registrate automatically. + +Configuring lifetime and activity period +**************************************** + +In LwM2M engine, there are three Kconfig options and one runtime value that configures how often the +client will send LwM2M Update message. + +.. list-table:: Update period variables + :widths: auto + :header-rows: 1 + + * - Variable + - Effect + * - LwM2M registration lifetime + - The lifetime parameter in LwM2M specifies how long a device's registration with an LwM2M server remains valid. + Device is expected to send LwM2M Update message before the lifetime exprires. + * - :kconfig:option:`CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME` + - Default lifetime value, unless set by the bootstrap server. + Also defines lower limit that client accepts as a lifetime. + * - :kconfig:option:`CONFIG_LWM2M_UPDATE_PERIOD` + - How long the client can stay idle before sending a next update. + * - :kconfig:option:`CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY` + - Minimum time margin to send the update message before the registration lifetime expires. + +.. figure:: images/lwm2m_lifetime_seconds_early.png + :alt: LwM2M seconds to update early + + Default way of calculating when to update registration. + +By default, the client uses :kconfig:option:`CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY` to calculate how +many seconds before the expiration of lifetime it is going to send the registration update. +The problem with default mode is when the server changes the lifetime of the registration. +This is then affecting the period of updates the client is doing. +If this is used with the QUEUE mode, which is typical in IPv4 networks, it is also affecting the +period of when the device is reachable from the server. + +.. figure:: images/lwm2m_lifetime_both.png + :alt: LwM2M update time when both values are set + + Update time is controlled by UPDATE_PERIOD. + +When also the :kconfig:option:`CONFIG_LWM2M_UPDATE_PERIOD` is set, time to send the update message +is the earliest when any of these values expire. This allows setting long lifetime for the +registration and configure the period accurately, even if server changes the lifetime parameter. + +In runtime, the update frequency is limited to once in 15 seconds to avoid flooding. + .. _lwm2m_shell: LwM2M shell diff --git a/samples/net/lwm2m_client/overlay-queue.conf b/samples/net/lwm2m_client/overlay-queue.conf index 060767dcb89..1adc9eda5ec 100644 --- a/samples/net/lwm2m_client/overlay-queue.conf +++ b/samples/net/lwm2m_client/overlay-queue.conf @@ -1,2 +1,6 @@ CONFIG_LWM2M_QUEUE_MODE_ENABLED=y -CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=180 +CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 +# Default lifetime is 1 day +CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=86400 +# Send update once an hour +CONFIG_LWM2M_UPDATE_PERIOD=3600 diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index d826e5cd599..1f5b83f47d0 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -471,9 +471,19 @@ config LWM2M_ENGINE_DEFAULT_LIFETIME This is also a minimum lifetime that client accepts. If server sets lifetime less than this value, client automatically raises it. +config LWM2M_UPDATE_PERIOD + int "LwM2M engine update period" + default 0 + range 0 4294967295 + help + Time period after the previous update or registration when to send the next update message. + This allows modifying lifetime without affecting the update period. + Set to zero, to allow LWM2M_SECONDS_TO_UPDATE_EARLY and lifetime to control when to + send the update. When both values are set, smallest period will be used. + config LWM2M_SECONDS_TO_UPDATE_EARLY int "LWM2M Registration Update transmission time before timeout" - default 6 + default 10 range 1 4294967295 help Time in seconds before the registration timeout, when the LWM2M diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index db8a84ce0b8..ca539fcded6 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -64,13 +64,13 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_util.h" #define LWM2M_RD_CLIENT_URI "rd" -#define SECONDS_TO_UPDATE_EARLY CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY #define CLIENT_EP_LEN CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH #define CLIENT_BINDING_LEN sizeof("UQ") #define CLIENT_QUEUE_LEN sizeof("Q") #define DELAY_BEFORE_CLOSING (1 * MSEC_PER_SEC) #define DELAY_FOR_ACK 100U #define EXCHANGE_LIFETIME 247U +#define MINIMUM_PERIOD 15 static void sm_handle_registration_update_failure(void); static int sm_send_registration_msg(void); @@ -1104,11 +1104,21 @@ static int sm_do_registration(void) static int64_t next_update(void) { - /* - * check for lifetime seconds - SECONDS_TO_UPDATE_EARLY - * so that we can update early and avoid lifetime timeout - */ - return client.last_update + (client.lifetime - SECONDS_TO_UPDATE_EARLY) * MSEC_PER_SEC; + int64_t next; + int64_t period = CONFIG_LWM2M_UPDATE_PERIOD; + int64_t early = CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY; + + if (period == 0) { + period = client.lifetime; + } + if (early > client.lifetime) { + early = client.lifetime; + } + + next = MIN(period, client.lifetime - early); + next = MAX(next, MINIMUM_PERIOD); + + return client.last_update + next * MSEC_PER_SEC; } static int64_t next_rx_off(void) diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf index 5d255e0513e..66d6334264f 100644 --- a/tests/net/lib/lwm2m/interop/prj.conf +++ b/tests/net/lib/lwm2m/interop/prj.conf @@ -61,6 +61,8 @@ CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 # Use QUEUE mode by default CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 +CONFIG_LWM2M_UPDATE_PERIOD=30 +CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY=10 # LwM2M configuration as OMA-ETS-LightweightM2M_INT-V1_1-20190912-D Configuration 3 CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=30 diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt index 81e129c56c1..2a8e8959c25 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt @@ -32,3 +32,4 @@ add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_ENABLED=1) add_compile_definitions(CONFIG_LWM2M_TLS_SESSION_CACHING=1) add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE=1) add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP=1) +add_compile_definitions(CONFIG_LWM2M_UPDATE_PERIOD=0)