From 358dcc1bde6a79abb3167e994fe7aec66968adaf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 29 Apr 2020 14:07:48 +0200 Subject: [PATCH] net: lwm2m: Handle socket errors So far socket errors reported by poll/recvfrom were ignored, which could lead to an unexpected behavior when socket was left in an undefined state. Fix this, by requesting a re-registration in the LWM2M state machine, which will close the faulty socket and open a new one. Note, that simply closing and re-opening a socket in the lwm2m engine would not work, since this would silently invalidate any open observations on the lwm2m server side (due to port number change). Triggering a fresh registration will notify the server to update its observations. Signed-off-by: Robert Lubos --- subsys/net/lib/lwm2m/lwm2m_engine.c | 14 +++++++++++--- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 12 ++++++++++++ subsys/net/lib/lwm2m/lwm2m_rd_client.h | 1 + 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index ed216f71ec8..306b714fdec 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -4114,9 +4114,14 @@ static void socket_receive_loop(void) } for (i = 0; i < sock_nfds; i++) { - if (sock_fds[i].revents & POLLERR) { - LOG_ERR("Error in poll.. waiting a moment."); - k_msleep(ENGINE_UPDATE_INTERVAL_MS); + if ((sock_fds[i].revents & POLLERR) || + (sock_fds[i].revents & POLLNVAL) || + (sock_fds[i].revents & POLLHUP)) { + LOG_ERR("Poll reported a socket error, %02x.", + sock_fds[i].revents); +#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT) + engine_trigger_restart(); +#endif continue; } @@ -4133,6 +4138,9 @@ static void socket_receive_loop(void) if (len < 0) { LOG_ERR("Error reading response: %d", errno); +#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT) + engine_trigger_restart(); +#endif continue; } diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index f0f6d1074dc..5e4b6691c9f 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -193,6 +193,18 @@ static void sm_handle_timeout_state(struct lwm2m_message *msg, } } +/* force state machine restart */ +void engine_trigger_restart(void) +{ + lwm2m_engine_context_close(client.ctx); + + /* Jump directly to the registration phase. In case there is no valid + * security object for the LWM2M server, it will fall back to the + * bootstrap procedure. + */ + set_sm_state(ENGINE_DO_REGISTRATION); +} + /* force re-update with remote peer */ void engine_trigger_update(void) { diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.h b/subsys/net/lib/lwm2m/lwm2m_rd_client.h index 96bb6f1c416..78cbb7287ab 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.h +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.h @@ -38,6 +38,7 @@ #ifndef LWM2M_RD_CLIENT_H #define LWM2M_RD_CLIENT_H +void engine_trigger_restart(void); void engine_trigger_update(void); #if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) void engine_bootstrap_finish(void);