From f1e0b5413cca807b16d61864c469c75cb3135ea5 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 9 Nov 2021 12:48:12 +0200 Subject: [PATCH] net: lwm2m: Allow changing the protocol version to 1.1 This is a bare minimal changes to tell the server that we are using LwM2M 1.1 version. Queue-mode parameter has changed between 1.0 and 1.1 so it must be changed in the same time. Other 1.1 features may follow on separate commits. This is still an experimental feature that allows developing and testing of 1.1 features. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/Kconfig | 24 +++++++++++++++++++++--- subsys/net/lib/lwm2m/lwm2m_engine.c | 20 +++++++++++++++++--- subsys/net/lib/lwm2m/lwm2m_engine.h | 5 +++++ subsys/net/lib/lwm2m/lwm2m_rd_client.c | 25 +++++++++++++++++++++---- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index f3d28a2c29c..7034e4fbd8b 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -17,6 +17,21 @@ module-dep = LOG module-str = Log level for LWM2M library source "subsys/net/Kconfig.template.log_config.net" +choice + prompt "LwM2M protocol version" + default LWM2M_VERSION_1_0 + help + Select which version of the LwM2M protocol is used + +config LWM2M_VERSION_1_0 + bool "LwM2M version 1.0" + +config LWM2M_VERSION_1_1 + bool "LwM2M version 1.1 [EXPERIMENTAL]" + select EXPERIMENTAL + +endchoice + config LWM2M_DTLS_SUPPORT bool "Enable DTLS support in the LwM2M client" select TLS_CREDENTIALS @@ -25,7 +40,8 @@ config LWM2M_DTLS_SUPPORT choice prompt "LwM2M Security object version" - default LWM2M_SECURITY_OBJECT_VERSION_1_0 + default LWM2M_SECURITY_OBJECT_VERSION_1_0 if LWM2M_VERSION_1_0 + default LWM2M_SECURITY_OBJECT_VERSION_1_1 if LWM2M_VERSION_1_1 help Select which version of the security object should be used. @@ -40,7 +56,8 @@ endchoice choice prompt "LwM2M Server object version" - default LWM2M_SERVER_OBJECT_VERSION_1_0 + default LWM2M_SERVER_OBJECT_VERSION_1_0 if LWM2M_VERSION_1_0 + default LWM2M_SERVER_OBJECT_VERSION_1_1 if LWM2M_VERSION_1_1 help Select which version of the Server object should be used. @@ -273,7 +290,8 @@ config LWM2M_CONN_MON_OBJ_SUPPORT choice prompt "LwM2M Connectivity Monitor object version" - default LWM2M_CONNMON_OBJECT_VERSION_1_0 + default LWM2M_CONNMON_OBJECT_VERSION_1_0 if LWM2M_VERSION_1_0 + default LWM2M_CONNMON_OBJECT_VERSION_1_2 if LWM2M_VERSION_1_1 depends on LWM2M_CONN_MON_OBJ_SUPPORT help Select Which version of the Connectivity Monitor object should be used. diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 0b07cf53e74..b2cb11fd59a 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -67,6 +67,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define COAP_OPTION_BUF_LEN 13 #endif +#define BINDING_OPT_MAX_LEN 3 /* "UQ" */ +#define QUEUE_OPT_MAX_LEN 2 /* "Q" */ #define MAX_TOKEN_LEN 8 struct observe_node { @@ -2011,12 +2013,24 @@ int lwm2m_engine_update_observer_max_period(const char *pathstr, uint32_t period } void lwm2m_engine_get_binding(char *binding) +{ + /* Defaults to UDP. */ + strncpy(binding, "U", BINDING_OPT_MAX_LEN); +#if CONFIG_LWM2M_VERSION_1_0 + /* In LwM2M 1.0 binding and queue mode are in same parameter */ + char queue[QUEUE_OPT_MAX_LEN]; + + lwm2m_engine_get_queue_mode(queue); + strncat(binding, queue, QUEUE_OPT_MAX_LEN); +#endif +} + +void lwm2m_engine_get_queue_mode(char *queue) { if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED)) { - strcpy(binding, "UQ"); + strncpy(queue, "Q", QUEUE_OPT_MAX_LEN); } else { - /* Defaults to UDP. */ - strcpy(binding, "U"); + strncpy(queue, "", QUEUE_OPT_MAX_LEN); } } diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.h b/subsys/net/lib/lwm2m/lwm2m_engine.h index 38b930565e9..235af591a2c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.h +++ b/subsys/net/lib/lwm2m/lwm2m_engine.h @@ -11,7 +11,11 @@ #include "lwm2m_object.h" #define LWM2M_PROTOCOL_VERSION_MAJOR 1 +#if CONFIG_LWM2M_VERSION_1_1 +#define LWM2M_PROTOCOL_VERSION_MINOR 1 +#else #define LWM2M_PROTOCOL_VERSION_MINOR 0 +#endif #define LWM2M_PROTOCOL_VERSION_STRING STRINGIFY(LWM2M_PROTOCOL_VERSION_MAJOR) \ "." \ @@ -123,6 +127,7 @@ int lwm2m_engine_get_resource(const char *pathstr, struct lwm2m_engine_res **res); void lwm2m_engine_get_binding(char *binding); +void lwm2m_engine_get_queue_mode(char *queue); size_t lwm2m_engine_get_opaque_more(struct lwm2m_input_context *in, uint8_t *buf, size_t buflen, diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index f33fb63949e..c101ccc55d5 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -67,8 +67,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define CLIENT_EP_LEN CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH -/* Up to 3 characters + NULL */ -#define CLIENT_BINDING_LEN sizeof("UQS") +#define CLIENT_BINDING_LEN sizeof("U") +#define CLIENT_QUEUE_LEN sizeof("Q") /* The states for the RD client state machine */ /* @@ -712,6 +712,7 @@ static int sm_send_registration(bool send_obj_support_data, struct lwm2m_message *msg; int ret; char binding[CLIENT_BINDING_LEN]; + char queue[CLIENT_QUEUE_LEN]; msg = lwm2m_get_message(client.ctx); if (!msg) { @@ -793,8 +794,9 @@ static int sm_send_registration(bool send_obj_support_data, } lwm2m_engine_get_binding(binding); - /* UDP is a default binding, no need to add option if UDP is used. */ - if ((!sm_is_registered() && strcmp(binding, "U") != 0)) { + lwm2m_engine_get_queue_mode(queue); + /* UDP is a default binding, no need to add option if UDP without queue is used. */ + if ((!sm_is_registered() && (strcmp(binding, "U") != 0 || strcmp(queue, "Q") == 0))) { snprintk(query_buffer, sizeof(query_buffer) - 1, "b=%s", binding); @@ -804,6 +806,20 @@ static int sm_send_registration(bool send_obj_support_data, if (ret < 0) { goto cleanup; } + +#if CONFIG_LWM2M_VERSION_1_1 + /* In LwM2M 1.1, queue mode is a separate parameter */ + uint16_t len = strlen(queue); + + if (len) { + ret = coap_packet_append_option( + &msg->cpkt, COAP_OPTION_URI_QUERY, + queue, len); + if (ret < 0) { + goto cleanup; + } + } +#endif } if (send_obj_support_data) { @@ -830,6 +846,7 @@ static int sm_send_registration(bool send_obj_support_data, return 0; cleanup: + LOG_ERR("error %d when sending registration message", ret); lwm2m_reset_message(msg, true); return ret; }