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 <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2023-10-03 15:35:24 +02:00 committed by Carles Cufí
commit 1b21109c2c
5 changed files with 25 additions and 13 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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));

View file

@ -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. */

View file

@ -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);