From 1b21109c2cc618bd4dcc3ea2c5658337f9b92db5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 3 Oct 2023 15:35:24 +0200 Subject: [PATCH] net: lwm2m: Reset ongoing notification in case token changes In case observation token changes (the LwM2M server re-sends observation request to the client), the LwM2M engine should cancel any ongoing notifications based on the old token. Otherwise, it will be impossible to match the pending notification reply (ACK) with the observer context anymore, causing new notifications for this observation to stall. Signed-off-by: Robert Lubos --- subsys/net/lib/lwm2m/lwm2m_engine.c | 2 +- subsys/net/lib/lwm2m/lwm2m_message_handling.c | 6 +++--- subsys/net/lib/lwm2m/lwm2m_observation.c | 14 +++++++++++++- subsys/net/lib/lwm2m/lwm2m_observation.h | 14 +++++++------- tests/net/lib/lwm2m/lwm2m_engine/src/main.c | 2 +- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 651baa30ff6..d4ebf2d62a2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -592,7 +592,7 @@ static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) continue; } /* Check That There is not pending process*/ - if (obs->active_tx_operation) { + if (obs->active_notify != NULL) { continue; } diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 678f358d1ee..2733f6ed4a8 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -2823,7 +2823,7 @@ static void notify_message_timeout_cb(struct lwm2m_message *msg) msg->token, msg->tkl); if (obs) { - obs->active_tx_operation = false; + obs->active_notify = NULL; if (client_ctx->observe_cb) { client_ctx->observe_cb(LWM2M_OBSERVE_EVENT_NOTIFY_TIMEOUT, &msg->path, msg->reply->user_data); @@ -2895,7 +2895,7 @@ static int notify_message_reply_cb(const struct coap_packet *response, struct co reply->token, reply->tkl); if (obs) { - obs->active_tx_operation = false; + obs->active_notify = NULL; if (msg->ctx->observe_cb) { msg->ctx->observe_cb(LWM2M_OBSERVE_EVENT_NOTIFY_ACK, lwm2m_read_first_path_ptr(&obs->path_list), @@ -3068,7 +3068,7 @@ msg_init: goto cleanup; } - obs->active_tx_operation = true; + obs->active_notify = msg; obs->resource_update = false; lwm2m_information_interface_send(msg); #if defined(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT) diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.c b/subsys/net/lib/lwm2m/lwm2m_observation.c index 91ab9c1709a..7933ebd8fd3 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.c +++ b/subsys/net/lib/lwm2m/lwm2m_observation.c @@ -438,7 +438,7 @@ static void engine_observe_node_init(struct observe_node *obs, const uint8_t *to obs->event_timestamp = 0; } obs->resource_update = false; - obs->active_tx_operation = false; + obs->active_notify = NULL; obs->format = format; obs->counter = OBSERVE_COUNTER_START; sys_slist_append(&ctx->observer, &obs->node); @@ -596,6 +596,12 @@ static int engine_add_observer(struct lwm2m_message *msg, const uint8_t *token, memcpy(obs->token, token, tkl); obs->tkl = tkl; + /* Cancel ongoing notification */ + if (obs->active_notify != NULL) { + lwm2m_reset_message(obs->active_notify, true); + obs->active_notify = NULL; + } + LOG_DBG("OBSERVER DUPLICATE %u/%u/%u(%u) [%s]", msg->path.obj_id, msg->path.obj_inst_id, msg->path.res_id, msg->path.level, lwm2m_sprint_ip_addr(&msg->ctx->remote_addr)); @@ -679,6 +685,12 @@ static int engine_add_composite_observer(struct lwm2m_message *msg, const uint8_ memcpy(obs->token, token, tkl); obs->tkl = tkl; + /* Cancel ongoing notification */ + if (obs->active_notify != NULL) { + lwm2m_reset_message(obs->active_notify, true); + obs->active_notify = NULL; + } + LOG_DBG("OBSERVER Composite DUPLICATE [%s]", lwm2m_sprint_ip_addr(&msg->ctx->remote_addr)); diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.h b/subsys/net/lib/lwm2m/lwm2m_observation.h index 95e60ab0a19..d74df74aab4 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.h +++ b/subsys/net/lib/lwm2m/lwm2m_observation.h @@ -14,16 +14,16 @@ int lwm2m_notify_observer_path(const struct lwm2m_obj_path *path); struct observe_node { sys_snode_t node; - sys_slist_t path_list; /* List of Observation path */ - uint8_t token[MAX_TOKEN_LEN]; /* Observation Token */ - int64_t event_timestamp; /* Timestamp for trig next Notify */ - int64_t last_timestamp; /* Timestamp from last Notify */ + sys_slist_t path_list; /* List of Observation path */ + uint8_t token[MAX_TOKEN_LEN]; /* Observation Token */ + int64_t event_timestamp; /* Timestamp for trig next Notify */ + int64_t last_timestamp; /* Timestamp from last Notify */ + struct lwm2m_message *active_notify; /* Currently active notification */ uint32_t counter; uint16_t format; uint8_t tkl; - bool resource_update : 1; /* Resource is updated */ - bool composite : 1; /* Composite Observation */ - bool active_tx_operation : 1; /* Active Notification process ongoing */ + bool resource_update : 1; /* Resource is updated */ + bool composite : 1; /* Composite Observation */ }; /* Attribute handling. */ diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c index bd1d21983dd..ed26380eccd 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c @@ -238,7 +238,7 @@ ZTEST(lwm2m_engine, test_check_notifications) obs.last_timestamp = k_uptime_get(); obs.event_timestamp = k_uptime_get() + 1000U; obs.resource_update = false; - obs.active_tx_operation = false; + obs.active_notify = NULL; sys_slist_append(&ctx.observer, &obs.node);