Skip to content

Commit

Permalink
net: lwm2m: Refactor RD client to be tickless
Browse files Browse the repository at this point in the history
Call RD client service only when there is state transitioning.
Remove periodic 500 ms timer.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
  • Loading branch information
SeppoTakalo authored and carlescufi committed Aug 1, 2023
1 parent 2da8844 commit 518bbc1
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 47 deletions.
72 changes: 55 additions & 17 deletions subsys/net/lib/lwm2m/lwm2m_rd_client.c
Expand Up @@ -64,18 +64,16 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_util.h"

#define LWM2M_RD_CLIENT_URI "rd"

#define SECONDS_TO_UPDATE_EARLY CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY
#define STATE_MACHINE_UPDATE_INTERVAL_MS 500

#define CLIENT_EP_LEN CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH

#define CLIENT_BINDING_LEN sizeof("UQ")
#define CLIENT_QUEUE_LEN sizeof("Q")

static void sm_handle_registration_update_failure(void);
static int sm_send_registration_msg(void);
static bool sm_is_suspended(void);
static void lwm2m_rd_client_service(struct k_work *work);
static int64_t calc_next_event(void);

/* The states for the RD client state machine */
/*
Expand Down Expand Up @@ -117,6 +115,7 @@ struct lwm2m_rd_client_info {

int64_t last_update;
int64_t last_tx;
int64_t next_event;

char ep_name[CLIENT_EP_LEN];
char server_ep[CLIENT_EP_LEN];
Expand Down Expand Up @@ -167,6 +166,11 @@ void engine_update_tx_time(void)
client.last_tx = k_uptime_get();
}

static void next_event_at(int64_t timestamp)
{
(void)lwm2m_engine_call_at(lwm2m_rd_client_service, timestamp);
}

static void set_sm_state(uint8_t sm_state)
{
k_mutex_lock(&client.mutex, K_FOREVER);
Expand Down Expand Up @@ -228,6 +232,7 @@ static void set_sm_state(uint8_t sm_state)
lwm2m_close_socket(client.ctx);
}
}
next_event_at(0);
k_mutex_unlock(&client.mutex);
}

Expand Down Expand Up @@ -453,6 +458,7 @@ int engine_trigger_bootstrap(void)
client.use_bootstrap = true;
client.trigger_update = false;
client.engine_state = ENGINE_INIT;
next_event_at(0);
k_mutex_unlock(&client.mutex);
return 0;
#else
Expand Down Expand Up @@ -1000,6 +1006,7 @@ static void sm_handle_registration_update_failure(void)
client.engine_state = ENGINE_SEND_REGISTRATION;
lwm2m_engine_context_close(client.ctx);
k_mutex_unlock(&client.mutex);
next_event_at(0);
}

static int sm_send_registration_msg(void)
Expand Down Expand Up @@ -1079,28 +1086,49 @@ static int sm_do_registration(void)
return ret;
}

static int sm_registration_done(void)
static int64_t next_update(void)
{
k_mutex_lock(&client.mutex, K_FOREVER);
int ret = 0;

/*
* check for lifetime seconds - SECONDS_TO_UPDATE_EARLY
* so that we can update early and avoid lifetime timeout
*/
return client.last_update + (client.lifetime - SECONDS_TO_UPDATE_EARLY) * 1000;
}

static int64_t next_rx_off(void)
{
if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED)) {
return client.last_tx + CONFIG_LWM2M_QUEUE_MODE_UPTIME * 1000;
} else {
return next_update();
}
}

/** Return timestamp to next even whether it is RX_OFF or update event */
static int64_t calc_next_event(void)
{
return Z_MIN(next_update(), next_rx_off());
}

static void sm_registration_done(void)
{
k_mutex_lock(&client.mutex, K_FOREVER);

int64_t now = k_uptime_get();

if (sm_is_registered() &&
(client.trigger_update ||
((client.lifetime - SECONDS_TO_UPDATE_EARLY) <=
(k_uptime_get() - client.last_update) / 1000))) {
now >= next_update())) {
set_sm_state(ENGINE_UPDATE_REGISTRATION);
} else if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED) &&
(client.engine_state != ENGINE_REGISTRATION_DONE_RX_OFF) &&
(((k_uptime_get() - client.last_tx) / 1000) >=
CONFIG_LWM2M_QUEUE_MODE_UPTIME)) {
(now >= next_rx_off())) {
set_sm_state(ENGINE_REGISTRATION_DONE_RX_OFF);
next_event_at(next_update());
} else {
next_event_at(calc_next_event());
}
k_mutex_unlock(&client.mutex);
return ret;
}

static int update_registration(void)
Expand Down Expand Up @@ -1214,7 +1242,9 @@ static void sm_do_network_error(void)
{
int err;

if (--client.retry_delay > 0) {
if (client.retry_delay) {
client.retry_delay = 0;
next_event_at(k_uptime_get() + client.retry_delay * 1000);
return;
}

Expand Down Expand Up @@ -1252,6 +1282,7 @@ static void lwm2m_rd_client_service(struct k_work *work)
k_mutex_lock(&client.mutex, K_FOREVER);

if (client.ctx) {
LOG_DBG("State: %d", get_sm_state());
switch (get_sm_state()) {
case ENGINE_IDLE:
if (client.ctx->sock_fd > -1) {
Expand Down Expand Up @@ -1374,7 +1405,10 @@ int lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name,
client.ep_name[CLIENT_EP_LEN - 1] = '\0';
LOG_INF("Start LWM2M Client: %s", client.ep_name);

next_event_at(0);

k_mutex_unlock(&client.mutex);

return 0;
}

Expand Down Expand Up @@ -1402,12 +1436,14 @@ int lwm2m_rd_client_stop(struct lwm2m_ctx *client_ctx,

k_mutex_unlock(&client.mutex);


return 0;
}

int lwm2m_rd_client_pause(void)
{
enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED;
LOG_DBG("lwm2m_rd_client_pause()");

k_mutex_lock(&client.mutex, K_FOREVER);

Expand Down Expand Up @@ -1482,6 +1518,7 @@ int lwm2m_rd_client_resume(void)
}
}

next_event_at(0);
k_mutex_unlock(&client.mutex);

return 0;
Expand All @@ -1490,6 +1527,7 @@ int lwm2m_rd_client_resume(void)
void lwm2m_rd_client_update(void)
{
engine_trigger_update(false);
next_event_at(0);
}

struct lwm2m_ctx *lwm2m_rd_client_ctx(void)
Expand Down Expand Up @@ -1520,6 +1558,7 @@ int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx)
client.engine_state = ENGINE_DO_REGISTRATION;
}
}
next_event_at(0);

return 0;
}
Expand All @@ -1536,6 +1575,7 @@ int lwm2m_rd_client_timeout(struct lwm2m_ctx *client_ctx)
k_mutex_lock(&client.mutex, K_FOREVER);
LOG_WRN("Confirmable Timeout -> Re-connect and register");
client.engine_state = ENGINE_DO_REGISTRATION;
next_event_at(0);
k_mutex_unlock(&client.mutex);
return 0;
}
Expand Down Expand Up @@ -1565,9 +1605,7 @@ int lwm2m_rd_client_init(void)
client.engine_state = ENGINE_IDLE;
k_mutex_init(&client.mutex);

return lwm2m_engine_add_service(lwm2m_rd_client_service,
STATE_MACHINE_UPDATE_INTERVAL_MS);

return 0;
}

static int sys_lwm2m_rd_client_init(void)
Expand Down
22 changes: 5 additions & 17 deletions tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c
Expand Up @@ -167,7 +167,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand Down Expand Up @@ -198,10 +197,8 @@ ZTEST(lwm2m_rd_client, test_timeout_resume_registration)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);

lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_default;
lwm2m_sprint_ip_addr_fake.custom_fake = lwm2m_sprint_ip_addr_fake_default;
Expand All @@ -228,7 +225,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_timeout)

test_prepare_pending_message_cb(&message_reply_timeout_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand All @@ -250,7 +246,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand All @@ -272,7 +267,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand Down Expand Up @@ -300,7 +294,6 @@ ZTEST(lwm2m_rd_client, test_rx_off)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand Down Expand Up @@ -329,7 +322,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand Down Expand Up @@ -359,7 +351,6 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand All @@ -376,12 +367,12 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout)

test_prepare_pending_message_cb(&message_reply_timeout_cb_default);
lwm2m_rd_client_update();
zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE, 2));
zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT, 3),
zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE, 1));
zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT, 2),
NULL);

test_prepare_pending_message_cb(&message_reply_cb_default);
zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE, 4),
zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE, 3),
NULL);
}

Expand All @@ -393,7 +384,6 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand Down Expand Up @@ -421,7 +411,6 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand All @@ -448,7 +437,6 @@ ZTEST(lwm2m_rd_client, test_network_error_on_registration)

(void)memset(&ctx, 0x0, sizeof(ctx));

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand All @@ -461,6 +449,8 @@ ZTEST(lwm2m_rd_client, test_network_error_on_registration)
coap_packet_append_option_fake.custom_fake = coap_packet_append_option_fake_err;
zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0,
NULL);
wait_for_service(100);

zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR, 0), NULL);
}

Expand All @@ -472,7 +462,6 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand Down Expand Up @@ -506,7 +495,6 @@ ZTEST(lwm2m_rd_client, test_socket_error)

test_prepare_pending_message_cb(&message_reply_cb_default);

lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default;
lwm2m_rd_client_init();
test_lwm2m_engine_start_service();
wait_for_service(1);
Expand Down

0 comments on commit 518bbc1

Please sign in to comment.