net: lwm2m: DTLS session cache enable and queue mode update
Enabled DTLS session cache for support session resume. Fixed LwM2M queue mode for close connection and reconnect automatically. Re-connect will do Registration update before it send queued data. Session resume is helping a case when NAT change address and cause less network traffic. Signed-off-by: Juha Heiskanen <juha.heiskanen@nordicsemi.no>
This commit is contained in:
parent
5249e43e54
commit
f20eeebbd1
6 changed files with 230 additions and 15 deletions
|
@ -192,6 +192,11 @@ config LWM2M_QUEUE_MODE_UPTIME
|
|||
defaults to 93 seconds, see RFC 7252), it does not forbid other
|
||||
values though.
|
||||
|
||||
config LWM2M_TLS_SESSION_CACHING
|
||||
bool "TLS session caching"
|
||||
help
|
||||
Enabling this only when feature is supported in TLS library.
|
||||
|
||||
config LWM2M_RD_CLIENT_SUPPORT
|
||||
bool "support for LWM2M client bootstrap/registration state machine"
|
||||
default y
|
||||
|
|
|
@ -1338,6 +1338,9 @@ void lwm2m_reset_message(struct lwm2m_message *msg, bool release)
|
|||
|
||||
if (msg->ctx) {
|
||||
sys_slist_find_and_remove(&msg->ctx->pending_sends, &msg->node);
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
sys_slist_find_and_remove(&msg->ctx->queued_messages, &msg->node);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (release) {
|
||||
|
@ -1421,15 +1424,85 @@ cleanup:
|
|||
return r;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
int lwm2m_engine_connection_resume(struct lwm2m_ctx *client_ctx)
|
||||
{
|
||||
#ifdef CONFIG_LWM2M_DTLS_SUPPORT
|
||||
if (!client_ctx->use_dtls) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (client_ctx->connection_suspended) {
|
||||
client_ctx->connection_suspended = false;
|
||||
LOG_DBG("Resume suspended connection");
|
||||
return lwm2m_socket_start(client_ctx);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
int lwm2m_push_queued_buffers(struct lwm2m_ctx *client_ctx)
|
||||
{
|
||||
client_ctx->buffer_client_messages = false;
|
||||
while (!sys_slist_is_empty(&client_ctx->queued_messages)) {
|
||||
sys_snode_t *msg_node = sys_slist_get(&client_ctx->queued_messages);
|
||||
struct lwm2m_message *msg;
|
||||
|
||||
if (!msg_node) {
|
||||
break;
|
||||
}
|
||||
msg = SYS_SLIST_CONTAINER(msg_node, msg, node);
|
||||
sys_slist_append(&msg->ctx->pending_sends, &msg->node);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int lwm2m_send_message_async(struct lwm2m_message *msg)
|
||||
{
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED) && defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT)
|
||||
int ret;
|
||||
|
||||
ret = lwm2m_rd_client_connection_resume(msg->ctx);
|
||||
if (ret) {
|
||||
lwm2m_reset_message(msg, true);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
sys_slist_append(&msg->ctx->pending_sends, &msg->node);
|
||||
|
||||
if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT) &&
|
||||
IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED)) {
|
||||
engine_update_tx_time();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lwm2m_information_interface_send(struct lwm2m_message *msg)
|
||||
{
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED) && defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT)
|
||||
int ret;
|
||||
|
||||
ret = lwm2m_rd_client_connection_resume(msg->ctx);
|
||||
if (ret) {
|
||||
lwm2m_reset_message(msg, true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (msg->ctx->buffer_client_messages) {
|
||||
sys_slist_append(&msg->ctx->queued_messages, &msg->node);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
sys_slist_append(&msg->ctx->pending_sends, &msg->node);
|
||||
|
||||
if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT) &&
|
||||
IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED)) {
|
||||
engine_update_tx_time();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5250,7 +5323,7 @@ static int generate_notify_message(struct lwm2m_ctx *ctx,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
lwm2m_send_message_async(msg);
|
||||
lwm2m_information_interface_send(msg);
|
||||
|
||||
LOG_DBG("NOTIFY MSG: SENT");
|
||||
return 0;
|
||||
|
@ -5344,6 +5417,44 @@ static int32_t lwm2m_engine_service(const int64_t timestamp)
|
|||
timestamp);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
|
||||
int lwm2m_engine_close_socket_connection(struct lwm2m_ctx *client_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
/* Enable Queue mode buffer store */
|
||||
client_ctx->buffer_client_messages = true;
|
||||
|
||||
#ifdef CONFIG_LWM2M_DTLS_SUPPORT
|
||||
if (!client_ctx->use_dtls) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (client_ctx->sock_fd >= 0) {
|
||||
ret = close(client_ctx->sock_fd);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to close socket: %d", errno);
|
||||
ret = -errno;
|
||||
return ret;
|
||||
}
|
||||
client_ctx->sock_fd = -1;
|
||||
client_ctx->connection_suspended = true;
|
||||
}
|
||||
|
||||
/* Open socket again that Observation and re-send functionality works */
|
||||
client_ctx->sock_fd =
|
||||
socket(client_ctx->remote_addr.sa_family, SOCK_DGRAM, IPPROTO_DTLS_1_2);
|
||||
|
||||
if (client_ctx->sock_fd < 0) {
|
||||
LOG_ERR("Failed to create socket: %d", errno);
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx)
|
||||
{
|
||||
int sock_fd = client_ctx->sock_fd;
|
||||
|
@ -5369,7 +5480,10 @@ int lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx)
|
|||
CONFIG_LWM2M_ENGINE_MAX_PENDING);
|
||||
coap_replies_clear(client_ctx->replies,
|
||||
CONFIG_LWM2M_ENGINE_MAX_REPLIES);
|
||||
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
client_ctx->connection_suspended = false;
|
||||
client_ctx->buffer_client_messages = true;
|
||||
#endif
|
||||
lwm2m_socket_del(client_ctx);
|
||||
client_ctx->sock_fd = -1;
|
||||
if (sock_fd >= 0) {
|
||||
|
@ -5383,6 +5497,11 @@ void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx)
|
|||
{
|
||||
sys_slist_init(&client_ctx->pending_sends);
|
||||
sys_slist_init(&client_ctx->observer);
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
client_ctx->buffer_client_messages = true;
|
||||
client_ctx->connection_suspended = false;
|
||||
sys_slist_init(&client_ctx->queued_messages);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* LwM2M Socket Integration */
|
||||
|
@ -5633,6 +5752,7 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
|||
socklen_t addr_len;
|
||||
int flags;
|
||||
int ret;
|
||||
bool allocate_socket = false;
|
||||
|
||||
#if defined(CONFIG_LWM2M_DTLS_SUPPORT)
|
||||
uint8_t tmp;
|
||||
|
@ -5653,15 +5773,20 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (client_ctx->use_dtls) {
|
||||
client_ctx->sock_fd = socket(client_ctx->remote_addr.sa_family,
|
||||
SOCK_DGRAM, IPPROTO_DTLS_1_2);
|
||||
} else
|
||||
#endif /* CONFIG_LWM2M_DTLS_SUPPORT */
|
||||
{
|
||||
client_ctx->sock_fd = socket(client_ctx->remote_addr.sa_family,
|
||||
SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (client_ctx->sock_fd < 0) {
|
||||
allocate_socket = true;
|
||||
#if defined(CONFIG_LWM2M_DTLS_SUPPORT)
|
||||
if (client_ctx->use_dtls) {
|
||||
client_ctx->sock_fd = socket(client_ctx->remote_addr.sa_family, SOCK_DGRAM,
|
||||
IPPROTO_DTLS_1_2);
|
||||
} else
|
||||
#endif /* CONFIG_LWM2M_DTLS_SUPPORT */
|
||||
{
|
||||
client_ctx->sock_fd =
|
||||
socket(client_ctx->remote_addr.sa_family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
}
|
||||
}
|
||||
|
||||
if (client_ctx->sock_fd < 0) {
|
||||
|
@ -5683,6 +5808,18 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_LWM2M_TLS_SESSION_CACHING)) {
|
||||
int session_cache = TLS_SESSION_CACHE_ENABLED;
|
||||
|
||||
ret = setsockopt(client_ctx->sock_fd, SOL_TLS, TLS_SESSION_CACHE,
|
||||
&session_cache, sizeof(session_cache));
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
LOG_ERR("Failed to set TLS_SESSION_CACHE option: %d", errno);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (client_ctx->hostname_verify && (client_ctx->desthostname != NULL)) {
|
||||
/** store character at len position */
|
||||
tmp = client_ctx->desthostname[client_ctx->desthostnamelen];
|
||||
|
@ -5734,9 +5871,10 @@ int lwm2m_socket_start(struct lwm2m_ctx *client_ctx)
|
|||
}
|
||||
|
||||
LOG_INF("Connected, sock id %d", client_ctx->sock_fd);
|
||||
|
||||
return lwm2m_socket_add(client_ctx);
|
||||
|
||||
if (allocate_socket) {
|
||||
return lwm2m_socket_add(client_ctx);
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
lwm2m_engine_context_close(client_ctx);
|
||||
return ret;
|
||||
|
@ -6334,7 +6472,7 @@ int lwm2m_engine_send(struct lwm2m_ctx *ctx, char const *path_list[], uint8_t pa
|
|||
goto cleanup;
|
||||
}
|
||||
LOG_INF("Send op to server (/dp)");
|
||||
lwm2m_send_message_async(msg);
|
||||
lwm2m_information_interface_send(msg);
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
|
|
|
@ -123,6 +123,8 @@ struct lwm2m_message *lwm2m_get_message(struct lwm2m_ctx *client_ctx);
|
|||
void lwm2m_reset_message(struct lwm2m_message *msg, bool release);
|
||||
int lwm2m_init_message(struct lwm2m_message *msg);
|
||||
int lwm2m_send_message_async(struct lwm2m_message *msg);
|
||||
/* Notification and Send operation */
|
||||
int lwm2m_information_interface_send(struct lwm2m_message *msg);
|
||||
int lwm2m_send_empty_ack(struct lwm2m_ctx *client_ctx, uint16_t mid);
|
||||
|
||||
int lwm2m_register_payload_handler(struct lwm2m_message *msg);
|
||||
|
@ -192,6 +194,11 @@ const char *lwm2m_engine_get_attr_name(const struct lwm2m_attr *attr);
|
|||
int lwm2m_socket_add(struct lwm2m_ctx *ctx);
|
||||
void lwm2m_socket_del(struct lwm2m_ctx *ctx);
|
||||
int lwm2m_socket_start(struct lwm2m_ctx *client_ctx);
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
int lwm2m_engine_close_socket_connection(struct lwm2m_ctx *client_ctx);
|
||||
int lwm2m_engine_connection_resume(struct lwm2m_ctx *client_ctx);
|
||||
int lwm2m_push_queued_buffers(struct lwm2m_ctx *client_ctx);
|
||||
#endif
|
||||
int lwm2m_parse_peerinfo(char *url, struct lwm2m_ctx *client_ctx, bool is_firmware_uri);
|
||||
|
||||
#endif /* LWM2M_ENGINE_H */
|
||||
|
|
|
@ -146,11 +146,20 @@ static void set_sm_state(uint8_t sm_state)
|
|||
if (client.engine_state == ENGINE_UPDATE_SENT &&
|
||||
(sm_state == ENGINE_REGISTRATION_DONE ||
|
||||
sm_state == ENGINE_REGISTRATION_DONE_RX_OFF)) {
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
lwm2m_push_queued_buffers(client.ctx);
|
||||
#endif
|
||||
event = LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE;
|
||||
} else if (sm_state == ENGINE_REGISTRATION_DONE) {
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
lwm2m_push_queued_buffers(client.ctx);
|
||||
#endif
|
||||
event = LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE;
|
||||
} else if (sm_state == ENGINE_REGISTRATION_DONE_RX_OFF) {
|
||||
event = LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF;
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
lwm2m_engine_close_socket_connection(client.ctx);
|
||||
#endif
|
||||
} else if ((sm_state == ENGINE_INIT ||
|
||||
sm_state == ENGINE_DEREGISTERED) &&
|
||||
(client.engine_state >= ENGINE_DO_REGISTRATION &&
|
||||
|
@ -919,6 +928,15 @@ static int sm_registration_done(void)
|
|||
update_objects = client.update_objects;
|
||||
client.trigger_update = false;
|
||||
client.update_objects = false;
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
ret = lwm2m_engine_connection_resume(client.ctx);
|
||||
if (ret) {
|
||||
lwm2m_engine_context_close(client.ctx);
|
||||
/* perform full registration */
|
||||
set_sm_state(ENGINE_DO_REGISTRATION);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = sm_send_registration(update_objects,
|
||||
do_update_reply_cb,
|
||||
|
@ -1154,6 +1172,35 @@ struct lwm2m_ctx *lwm2m_rd_client_ctx(void)
|
|||
return client.ctx;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx)
|
||||
{
|
||||
if (client.ctx != client_ctx) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (client.engine_state == ENGINE_REGISTRATION_DONE_RX_OFF) {
|
||||
#ifdef CONFIG_LWM2M_DTLS_SUPPORT
|
||||
/*
|
||||
* Switch state for triggering a proper registration message
|
||||
* if CONFIG_LWM2M_TLS_SESSION_CACHING is false we force full
|
||||
* registration after Fully DTLS handshake
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_LWM2M_TLS_SESSION_CACHING)) {
|
||||
client.engine_state = ENGINE_REGISTRATION_DONE;
|
||||
} else {
|
||||
client.engine_state = ENGINE_DO_REGISTRATION;
|
||||
}
|
||||
#else
|
||||
client.engine_state = ENGINE_REGISTRATION_DONE;
|
||||
#endif
|
||||
client.trigger_update = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lwm2m_rd_client_init(const struct device *dev)
|
||||
{
|
||||
k_mutex_init(&client.mutex);
|
||||
|
|
|
@ -43,7 +43,9 @@ int engine_trigger_bootstrap(void);
|
|||
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
|
||||
void engine_bootstrap_finish(void);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
|
||||
int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx);
|
||||
#endif
|
||||
void engine_update_tx_time(void);
|
||||
|
||||
#endif /* LWM2M_RD_CLIENT_H */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue