diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index d166bce7f61..d9a1b3e17fa 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -2838,7 +2838,7 @@ static int lwm2m_delete_handler(struct lwm2m_message *msg) ret = lwm2m_delete_obj_inst(msg->path.obj_id, msg->path.obj_inst_id); #if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT) if (!ret && !msg->ctx->bootstrap_mode) { - engine_trigger_update(); + engine_trigger_update(true); } #endif @@ -3239,7 +3239,7 @@ int lwm2m_get_or_create_engine_obj(struct lwm2m_message *msg, #if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT) if (!msg->ctx->bootstrap_mode) { - engine_trigger_update(); + engine_trigger_update(true); } #endif } diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_server.c b/subsys/net/lib/lwm2m/lwm2m_obj_server.c index 7059412454b..1b56ece7fa7 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_server.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_server.c @@ -100,7 +100,28 @@ static int disable_cb(uint16_t obj_inst_id) static int update_trigger_cb(uint16_t obj_inst_id) { #ifdef CONFIG_LWM2M_RD_CLIENT_SUPPORT - engine_trigger_update(); + engine_trigger_update(false); + return 0; +#else + return -EPERM; +#endif +} + +static int lifetime_write_cb(uint16_t obj_inst_id, uint16_t res_id, + uint16_t res_inst_id, uint8_t *data, + uint16_t data_len, bool last_block, + size_t total_size) +{ + ARG_UNUSED(obj_inst_id); + ARG_UNUSED(res_id); + ARG_UNUSED(res_inst_id); + ARG_UNUSED(data); + ARG_UNUSED(data_len); + ARG_UNUSED(last_block); + ARG_UNUSED(total_size); + +#ifdef CONFIG_LWM2M_RD_CLIENT_SUPPORT + engine_trigger_update(false); return 0; #else return -EPERM; @@ -189,9 +210,9 @@ static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id) INIT_OBJ_RES_DATA(SERVER_SHORT_SERVER_ID, res[index], i, res_inst[index], j, &server_id[index], sizeof(*server_id)); - INIT_OBJ_RES_DATA(SERVER_LIFETIME_ID, res[index], i, - res_inst[index], j, - &lifetime[index], sizeof(*lifetime)); + INIT_OBJ_RES(SERVER_LIFETIME_ID, res[index], i, res_inst[index], j, + 1U, true, &lifetime[index], sizeof(*lifetime), + NULL, NULL, lifetime_write_cb, NULL); INIT_OBJ_RES_DATA(SERVER_DEFAULT_MIN_PERIOD_ID, res[index], i, res_inst[index], j, &default_min_period[index], diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index e59de93909c..69a62255b22 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -99,8 +99,6 @@ struct lwm2m_rd_client_info { uint32_t lifetime; struct lwm2m_ctx *ctx; uint8_t engine_state; - uint8_t use_bootstrap; - uint8_t trigger_update; int64_t last_update; int64_t last_tx; @@ -109,6 +107,10 @@ struct lwm2m_rd_client_info { char server_ep[CLIENT_EP_LEN]; lwm2m_ctx_event_cb_t event_cb; + + bool use_bootstrap : 1; + bool trigger_update : 1; + bool update_objects : 1; } client; /* buffers */ @@ -209,10 +211,14 @@ void engine_trigger_restart(void) } /* force re-update with remote peer */ -void engine_trigger_update(void) +void engine_trigger_update(bool update_objects) { /* TODO: add locking? */ - client.trigger_update = 1U; + client.trigger_update = true; + + if (update_objects) { + client.update_objects = true; + } } /* state machine reply callbacks */ @@ -424,15 +430,23 @@ static bool sm_bootstrap_verify(bool bootstrap_server, int sec_obj_inst) } } -static void sm_update_lifetime(int srv_obj_inst, uint32_t *lifetime) +static bool sm_update_lifetime(int srv_obj_inst, uint32_t *lifetime) { char pathstr[MAX_RESOURCE_LEN]; + uint32_t new_lifetime; snprintk(pathstr, sizeof(pathstr), "1/%d/1", srv_obj_inst); - if (lwm2m_engine_get_u32(pathstr, lifetime) < 0) { - *lifetime = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME; - LOG_INF("Using default lifetime: %u", *lifetime); + if (lwm2m_engine_get_u32(pathstr, &new_lifetime) < 0) { + new_lifetime = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME; + LOG_INF("Using default lifetime: %u", new_lifetime); } + + if (new_lifetime != *lifetime) { + *lifetime = new_lifetime; + return true; + } + + return false; } static int sm_select_server_inst(int sec_obj_inst, int *srv_obj_inst, @@ -457,7 +471,6 @@ static int sm_select_server_inst(int sec_obj_inst, int *srv_obj_inst, } *srv_obj_inst = obj_inst_id; - sm_update_lifetime(*srv_obj_inst, lifetime); return 0; } @@ -499,7 +512,7 @@ static int sm_do_init(void) { client.ctx->sec_obj_inst = -1; client.ctx->srv_obj_inst = -1; - client.trigger_update = 0U; + client.trigger_update = false; client.lifetime = 0U; /* Do bootstrap or registration */ @@ -645,47 +658,76 @@ static int sm_send_registration(bool send_obj_support_data, goto cleanup; } - /* TODO: handle return error */ - coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH, - LWM2M_RD_CLIENT_URI, - strlen(LWM2M_RD_CLIENT_URI)); - - if (!sm_is_registered()) { - /* include client endpoint in URI QUERY on 1st registration */ - coap_append_option_int(&msg->cpkt, COAP_OPTION_CONTENT_FORMAT, - LWM2M_FORMAT_APP_LINK_FORMAT); - snprintk(query_buffer, sizeof(query_buffer) - 1, - "lwm2m=%s", LWM2M_PROTOCOL_VERSION); - /* TODO: handle return error */ - coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY, - query_buffer, strlen(query_buffer)); - snprintk(query_buffer, sizeof(query_buffer) - 1, - "ep=%s", client.ep_name); - /* TODO: handle return error */ - coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY, - query_buffer, strlen(query_buffer)); - } else { - /* include server endpoint in URI PATH otherwise */ - /* TODO: handle return error */ - coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH, - client.server_ep, - strlen(client.server_ep)); + ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH, + LWM2M_RD_CLIENT_URI, + strlen(LWM2M_RD_CLIENT_URI)); + if (ret < 0) { + goto cleanup; } - snprintk(query_buffer, sizeof(query_buffer) - 1, - "lt=%d", client.lifetime); - /* TODO: handle return error */ - coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY, - query_buffer, strlen(query_buffer)); + if (sm_is_registered()) { + ret = coap_packet_append_option( + &msg->cpkt, COAP_OPTION_URI_PATH, + client.server_ep, strlen(client.server_ep)); + if (ret < 0) { + goto cleanup; + } + } + + if (send_obj_support_data) { + ret = coap_append_option_int( + &msg->cpkt, COAP_OPTION_CONTENT_FORMAT, + LWM2M_FORMAT_APP_LINK_FORMAT); + if (ret < 0) { + goto cleanup; + } + } + + if (!sm_is_registered()) { + snprintk(query_buffer, sizeof(query_buffer) - 1, + "lwm2m=%s", LWM2M_PROTOCOL_VERSION); + ret = coap_packet_append_option( + &msg->cpkt, COAP_OPTION_URI_QUERY, + query_buffer, strlen(query_buffer)); + if (ret < 0) { + goto cleanup; + } + + snprintk(query_buffer, sizeof(query_buffer) - 1, + "ep=%s", client.ep_name); + ret = coap_packet_append_option( + &msg->cpkt, COAP_OPTION_URI_QUERY, + query_buffer, strlen(query_buffer)); + if (ret < 0) { + goto cleanup; + } + } + + /* Send lifetime only if changed or on initial registration.*/ + if (sm_update_lifetime(client.ctx->srv_obj_inst, &client.lifetime) || + !sm_is_registered()) { + snprintk(query_buffer, sizeof(query_buffer) - 1, + "lt=%d", client.lifetime); + ret = coap_packet_append_option( + &msg->cpkt, COAP_OPTION_URI_QUERY, + query_buffer, strlen(query_buffer)); + if (ret < 0) { + goto cleanup; + } + } lwm2m_engine_get_binding(binding); /* UDP is a default binding, no need to add option if UDP is used. */ - if (strcmp(binding, "U") != 0) { + if ((!sm_is_registered() && strcmp(binding, "U") != 0)) { snprintk(query_buffer, sizeof(query_buffer) - 1, "b=%s", binding); - /* TODO: handle return error */ - coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY, - query_buffer, strlen(query_buffer)); + + ret = coap_packet_append_option( + &msg->cpkt, COAP_OPTION_URI_QUERY, + query_buffer, strlen(query_buffer)); + if (ret < 0) { + goto cleanup; + } } if (send_obj_support_data) { @@ -774,7 +816,7 @@ static int sm_do_registration(void) static int sm_registration_done(void) { int ret = 0; - bool forced_update; + bool update_objects; /* * check for lifetime seconds - SECONDS_TO_UPDATE_EARLY @@ -784,15 +826,11 @@ static int sm_registration_done(void) (client.trigger_update || ((client.lifetime - SECONDS_TO_UPDATE_EARLY) <= (k_uptime_get() - client.last_update) / 1000))) { - forced_update = client.trigger_update; - client.trigger_update = 0U; + update_objects = client.update_objects; + client.trigger_update = false; + client.update_objects = false; - /** The LwM2M server might've changed the lifetime, - * update it just in case. - */ - sm_update_lifetime(client.ctx->srv_obj_inst, &client.lifetime); - - ret = sm_send_registration(forced_update, + ret = sm_send_registration(update_objects, do_update_reply_cb, do_update_timeout_cb); if (!ret) { diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.h b/subsys/net/lib/lwm2m/lwm2m_rd_client.h index 78cbb7287ab..d5403b52d11 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.h +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.h @@ -39,7 +39,7 @@ #define LWM2M_RD_CLIENT_H void engine_trigger_restart(void); -void engine_trigger_update(void); +void engine_trigger_update(bool update_objects); #if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) void engine_bootstrap_finish(void); #endif diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c b/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c index 3eef9e0a806..69a8b1b9c0f 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c @@ -982,7 +982,7 @@ int do_write_op_tlv(struct lwm2m_message *msg) #ifdef CONFIG_LWM2M_RD_CLIENT_SUPPORT if (!msg->ctx->bootstrap_mode) { - engine_trigger_update(); + engine_trigger_update(true); } #endif }