net: lwm2m: send REGISTRATION_TIMEOUT event on error

When socket errors call sm_handle_timeout_state() we might be
in a state where application assumes we are in registered state
but we are dropping it.
Therefore we must ensure that all registration states emit either
REGISTRATION_TIMEOUT event for application to indicate that
we have lost the connection to server.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
This commit is contained in:
Seppo Takalo 2024-08-01 14:09:38 +03:00 committed by Anas Nashif
commit e7b06e1c86
3 changed files with 33 additions and 15 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Before After
Before After

View file

@ -579,7 +579,7 @@ The events are prefixed with ``LWM2M_RD_CLIENT_EVENT_``.
* - 4 * - 4
- REGISTRATION_FAILURE - REGISTRATION_FAILURE
- Registration to LwM2M server failed. - Registration to LwM2M server failed.
Occurs if there is a failure in the registration. Occurs if server rejects the registration attempt.
* - 5 * - 5
- REGISTRATION_COMPLETE - REGISTRATION_COMPLETE
- Registration to LwM2M server successful. - Registration to LwM2M server successful.
@ -587,8 +587,8 @@ The events are prefixed with ``LWM2M_RD_CLIENT_EVENT_``.
or when session resumption is used. or when session resumption is used.
* - 6 * - 6
- REG_TIMEOUT - REG_TIMEOUT
- Registration or registration update timeout. - Registration status lost.
Occurs if there is a timeout during registration. Client have lost connection to the server. Occurs if there is socket errors or message timeouts. Client have lost connection to the server.
* - 7 * - 7
- REG_UPDATE_COMPLETE - REG_UPDATE_COMPLETE
- Registration update completed. - Registration update completed.
@ -641,7 +641,8 @@ where it cannot recover.
* - BOOTSTRAP_TRANSFER_COMPLETE * - BOOTSTRAP_TRANSFER_COMPLETE
- No actions needed - No actions needed
* - REGISTRATION_FAILURE * - REGISTRATION_FAILURE
- No actions needed - No actions needed.
Client proceeds re-registration automatically. Might need a bootstrap or configuration fix. Cannot send or receive data.
* - REGISTRATION_COMPLETE * - REGISTRATION_COMPLETE
- No actions needed. - No actions needed.
Application can send or receive data. Application can send or receive data.

View file

@ -289,22 +289,38 @@ static uint8_t get_sm_state(void)
return state; return state;
} }
/** Handle state transition when we have lost the connection. */
static void sm_handle_timeout_state(enum sm_engine_state sm_state) static void sm_handle_timeout_state(enum sm_engine_state sm_state)
{ {
k_mutex_lock(&client.mutex, K_FOREVER); k_mutex_lock(&client.mutex, K_FOREVER);
enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE; enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE;
/* Don't send BOOTSTRAP_REG_FAILURE event, that is only emitted from switch (client.engine_state) {
* do_network_error() once we are out of retries. case ENGINE_DO_BOOTSTRAP_REG:
*/ case ENGINE_BOOTSTRAP_REG_SENT:
if (client.engine_state == ENGINE_REGISTRATION_SENT) { case ENGINE_BOOTSTRAP_REG_DONE:
case ENGINE_BOOTSTRAP_TRANS_DONE:
/* Don't send BOOTSTRAP_REG_FAILURE event, that is only emitted from
* do_network_error() once we are out of retries.
*/
break;
case ENGINE_SEND_REGISTRATION:
case ENGINE_REGISTRATION_SENT:
case ENGINE_REGISTRATION_DONE:
case ENGINE_REGISTRATION_DONE_RX_OFF:
case ENGINE_UPDATE_REGISTRATION:
case ENGINE_UPDATE_SENT:
event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT;
} else if (client.engine_state == ENGINE_UPDATE_SENT) { break;
event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT;
} else if (client.engine_state == ENGINE_DEREGISTER_SENT) { case ENGINE_DEREGISTER:
case ENGINE_DEREGISTER_SENT:
event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE; event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE;
} else { break;
/* TODO: unknown timeout state */ default:
/* No default events for socket errors */
break;
} }
set_sm_state(sm_state); set_sm_state(sm_state);
@ -315,6 +331,7 @@ static void sm_handle_timeout_state(enum sm_engine_state sm_state)
k_mutex_unlock(&client.mutex); k_mutex_unlock(&client.mutex);
} }
/** Handle state transition where server have rejected the connection. */
static void sm_handle_failure_state(enum sm_engine_state sm_state) static void sm_handle_failure_state(enum sm_engine_state sm_state)
{ {
k_mutex_lock(&client.mutex, K_FOREVER); k_mutex_lock(&client.mutex, K_FOREVER);
@ -374,7 +391,7 @@ static void socket_fault_cb(int error)
sm_handle_timeout_state(ENGINE_NETWORK_ERROR); sm_handle_timeout_state(ENGINE_NETWORK_ERROR);
} else if (client.engine_state != ENGINE_SUSPENDED && } else if (client.engine_state != ENGINE_SUSPENDED &&
!client.server_disabled) { !client.server_disabled) {
sm_handle_failure_state(ENGINE_IDLE); sm_handle_timeout_state(ENGINE_IDLE);
} }
} }