diff --git a/include/net/lwm2m.h b/include/net/lwm2m.h index d4846439115..10bce646a53 100644 --- a/include/net/lwm2m.h +++ b/include/net/lwm2m.h @@ -24,6 +24,7 @@ #define ZEPHYR_INCLUDE_NET_LWM2M_H_ #include +#include #include /** @@ -69,6 +70,7 @@ struct lwm2m_ctx { struct coap_pending pendings[CONFIG_LWM2M_ENGINE_MAX_PENDING]; struct coap_reply replies[CONFIG_LWM2M_ENGINE_MAX_REPLIES]; struct k_delayed_work retransmit_work; + struct sys_mutex send_lock; #if defined(CONFIG_LWM2M_DTLS_SUPPORT) /** TLS tag is set by client as a reference used when the diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 0126604d5aa..4c2357d25d4 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -26,6 +26,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include #include #include #include @@ -994,6 +995,8 @@ cleanup: int lwm2m_send_message(struct lwm2m_message *msg) { + int rc; + if (!msg || !msg->ctx) { LOG_ERR("LwM2M message is invalid."); return -EINVAL; @@ -1005,11 +1008,16 @@ int lwm2m_send_message(struct lwm2m_message *msg) msg->send_attempts++; - if (send(msg->ctx->sock_fd, msg->cpkt.data, msg->cpkt.offset, 0) < 0) { + sys_mutex_lock(&msg->ctx->send_lock, K_FOREVER); + rc = send(msg->ctx->sock_fd, msg->cpkt.data, msg->cpkt.offset, 0); + sys_mutex_unlock(&msg->ctx->send_lock); + if (rc < 0) { if (msg->type == COAP_TYPE_CON) { coap_pending_clear(msg->pending); } + LOG_ERR("Failed to send packet, err %d", errno); + return -errno; } @@ -3769,11 +3777,22 @@ static void retransmit_request(struct k_work *work) LOG_INF("Resending message: %p", msg); msg->send_attempts++; + + sys_mutex_lock(&client_ctx->send_lock, K_FOREVER); + + if (msg->ctx == NULL) { + LOG_INF("Response for %p already handled", msg); + goto next_locked; + } + if (send(msg->ctx->sock_fd, msg->cpkt.data, msg->cpkt.offset, 0) < 0) { LOG_ERR("Error sending lwm2m message: %d", -errno); /* don't error here, retry until timeout */ } +next_locked: + sys_mutex_unlock(&client_ctx->send_lock); + next: pending = coap_pending_next_to_expire(client_ctx->pendings, CONFIG_LWM2M_ENGINE_MAX_PENDING); @@ -4055,6 +4074,7 @@ int lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx) void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx) { k_delayed_work_init(&client_ctx->retransmit_work, retransmit_request); + sys_mutex_init(&client_ctx->send_lock); } /* LwM2M Socket Integration */