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

View file

@ -289,22 +289,38 @@ static uint8_t get_sm_state(void)
return state;
}
/** Handle state transition when we have lost the connection. */
static void sm_handle_timeout_state(enum sm_engine_state sm_state)
{
k_mutex_lock(&client.mutex, K_FOREVER);
enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE;
switch (client.engine_state) {
case ENGINE_DO_BOOTSTRAP_REG:
case ENGINE_BOOTSTRAP_REG_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.
*/
if (client.engine_state == ENGINE_REGISTRATION_SENT) {
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;
} else if (client.engine_state == ENGINE_UPDATE_SENT) {
event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT;
} else if (client.engine_state == ENGINE_DEREGISTER_SENT) {
break;
case ENGINE_DEREGISTER:
case ENGINE_DEREGISTER_SENT:
event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE;
} else {
/* TODO: unknown timeout state */
break;
default:
/* No default events for socket errors */
break;
}
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);
}
/** Handle state transition where server have rejected the connection. */
static void sm_handle_failure_state(enum sm_engine_state sm_state)
{
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);
} else if (client.engine_state != ENGINE_SUSPENDED &&
!client.server_disabled) {
sm_handle_failure_state(ENGINE_IDLE);
sm_handle_timeout_state(ENGINE_IDLE);
}
}