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; }