net: lwm2m: Refactor RD client to be tickless
Call RD client service only when there is state transitioning. Remove periodic 500 ms timer. Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
This commit is contained in:
parent
2da8844d19
commit
518bbc1303
4 changed files with 75 additions and 47 deletions
|
@ -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 */
|
||||
/*
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -1482,6 +1518,7 @@ int lwm2m_rd_client_resume(void)
|
|||
}
|
||||
}
|
||||
|
||||
next_event_at(0);
|
||||
k_mutex_unlock(&client.mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -80,14 +80,14 @@ char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr)
|
|||
|
||||
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t);
|
||||
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int);
|
||||
DEFINE_FAKE_VALUE_FUNC(int, lwm2m_engine_add_service, k_work_handler_t, uint32_t);
|
||||
|
||||
k_work_handler_t lwm2m_engine_add_service_service;
|
||||
uint32_t lwm2m_engine_add_service_period_ms = 20;
|
||||
int lwm2m_engine_add_service_fake_default(k_work_handler_t service, uint32_t period_ms)
|
||||
k_work_handler_t service;
|
||||
int64_t next;
|
||||
|
||||
int lwm2m_engine_call_at(k_work_handler_t work, int64_t timestamp)
|
||||
{
|
||||
lwm2m_engine_add_service_service = service;
|
||||
lwm2m_engine_add_service_period_ms = period_ms;
|
||||
service = work;
|
||||
next = timestamp ? timestamp : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -97,18 +97,23 @@ void *(*pending_message_cb)();
|
|||
|
||||
static void service_work_fn(struct k_work *work)
|
||||
{
|
||||
while (lwm2m_engine_add_service_service != NULL) {
|
||||
while (true) {
|
||||
if (pending_message != NULL && pending_message_cb != NULL) {
|
||||
pending_message_cb(pending_message);
|
||||
pending_message = NULL;
|
||||
}
|
||||
|
||||
lwm2m_engine_add_service_service(work);
|
||||
k_sleep(K_MSEC(lwm2m_engine_add_service_period_ms));
|
||||
if (next && next < k_uptime_get()) {
|
||||
printk("Event!\n");
|
||||
next = 0;
|
||||
service(NULL);
|
||||
}
|
||||
k_sleep(K_MSEC(10));
|
||||
counter--;
|
||||
|
||||
/* avoid endless loop if rd client is stuck somewhere */
|
||||
if (counter == 0) {
|
||||
printk("Counter!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +124,7 @@ void wait_for_service(uint16_t cycles)
|
|||
uint16_t end = counter - cycles;
|
||||
|
||||
while (counter > end) {
|
||||
k_sleep(K_MSEC(1));
|
||||
k_sleep(K_MSEC(10));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,6 @@ DECLARE_FAKE_VALUE_FUNC(char *, lwm2m_sprint_ip_addr, const struct sockaddr *);
|
|||
char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr);
|
||||
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t);
|
||||
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int);
|
||||
DECLARE_FAKE_VALUE_FUNC(int, lwm2m_engine_add_service, k_work_handler_t, uint32_t);
|
||||
int lwm2m_engine_add_service_fake_default(k_work_handler_t service, uint32_t period_ms);
|
||||
void wait_for_service(uint16_t cycles);
|
||||
void test_lwm2m_engine_start_service(void);
|
||||
void test_lwm2m_engine_stop_service(void);
|
||||
|
@ -107,7 +105,6 @@ DECLARE_FAKE_VALUE_FUNC(int, do_register_op_link_format, struct lwm2m_message *)
|
|||
FUNC(lwm2m_sprint_ip_addr) \
|
||||
FUNC(lwm2m_server_short_id_to_inst) \
|
||||
FUNC(lwm2m_security_index_to_inst_id) \
|
||||
FUNC(lwm2m_engine_add_service) \
|
||||
FUNC(lwm2m_init_message) \
|
||||
FUNC(lwm2m_reset_message) \
|
||||
FUNC(lwm2m_send_message_async) \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue