net: lwm2m: Add support for object versioning

Each object now have to specify the object version it implements.
Based on this information the LwM2M engine can decide whether it's
needed to report the object version during Registration/Discovery
operations or not.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2021-02-02 13:14:21 +01:00 committed by Anas Nashif
commit c9f5337a91
21 changed files with 171 additions and 15 deletions

View file

@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define ACCEL_VERSION_MAJOR 1
#define ACCEL_VERSION_MINOR 0
#ifdef CONFIG_LWM2M_IPSO_ACCELEROMETER_TIMESTAMP #ifdef CONFIG_LWM2M_IPSO_ACCELEROMETER_TIMESTAMP
#define ADD_TIMESTAMPS 1 #define ADD_TIMESTAMPS 1
#else #else
@ -145,6 +148,9 @@ static struct lwm2m_engine_obj_inst *accel_create(uint16_t obj_inst_id)
static int ipso_accel_init(const struct device *dev) static int ipso_accel_init(const struct device *dev)
{ {
accel.obj_id = IPSO_OBJECT_ACCELEROMETER_ID; accel.obj_id = IPSO_OBJECT_ACCELEROMETER_ID;
accel.version_major = ACCEL_VERSION_MAJOR;
accel.version_minor = ACCEL_VERSION_MINOR;
accel.is_core = false;
accel.fields = fields; accel.fields = fields;
accel.field_count = ARRAY_SIZE(fields); accel.field_count = ARRAY_SIZE(fields);
accel.max_instance_count = ARRAY_SIZE(inst); accel.max_instance_count = ARRAY_SIZE(inst);

View file

@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define BUZZER_VERSION_MAJOR 1
#define BUZZER_VERSION_MINOR 0
/* resource IDs */ /* resource IDs */
#define BUZZER_ON_OFF_ID 5850 #define BUZZER_ON_OFF_ID 5850
#define BUZZER_LEVEL_ID 5548 #define BUZZER_LEVEL_ID 5548
@ -246,6 +249,9 @@ static struct lwm2m_engine_obj_inst *buzzer_create(uint16_t obj_inst_id)
static int ipso_buzzer_init(const struct device *dev) static int ipso_buzzer_init(const struct device *dev)
{ {
buzzer.obj_id = IPSO_OBJECT_BUZZER_ID; buzzer.obj_id = IPSO_OBJECT_BUZZER_ID;
buzzer.version_major = BUZZER_VERSION_MAJOR;
buzzer.version_minor = BUZZER_VERSION_MINOR;
buzzer.is_core = false;
buzzer.fields = fields; buzzer.fields = fields;
buzzer.field_count = ARRAY_SIZE(fields); buzzer.field_count = ARRAY_SIZE(fields);
buzzer.max_instance_count = ARRAY_SIZE(inst); buzzer.max_instance_count = ARRAY_SIZE(inst);

View file

@ -24,6 +24,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#include "lwm2m_resource_ids.h" #include "lwm2m_resource_ids.h"
#define GENERIC_VERSION_MAJOR 1
#define GENERIC_VERSION_MINOR 0
#ifdef CONFIG_LWM2M_IPSO_GENERIC_SENSOR_TIMESTAMP #ifdef CONFIG_LWM2M_IPSO_GENERIC_SENSOR_TIMESTAMP
#define ADD_TIMESTAMPS 1 #define ADD_TIMESTAMPS 1
#define NUMBER_OF_OBJ_FIELDS 10 #define NUMBER_OF_OBJ_FIELDS 10
@ -241,6 +244,9 @@ static struct lwm2m_engine_obj_inst *generic_sensor_create(uint16_t obj_inst_id)
static int ipso_generic_sensor_init(const struct device *dev) static int ipso_generic_sensor_init(const struct device *dev)
{ {
sensor.obj_id = IPSO_OBJECT_ID; sensor.obj_id = IPSO_OBJECT_ID;
sensor.version_major = GENERIC_VERSION_MAJOR;
sensor.version_minor = GENERIC_VERSION_MINOR;
sensor.is_core = false;
sensor.fields = fields; sensor.fields = fields;
sensor.field_count = ARRAY_SIZE(fields); sensor.field_count = ARRAY_SIZE(fields);
sensor.max_instance_count = MAX_INSTANCE_COUNT; sensor.max_instance_count = MAX_INSTANCE_COUNT;

View file

@ -19,6 +19,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#include "lwm2m_resource_ids.h" #include "lwm2m_resource_ids.h"
#define HUMIDITY_VERSION_MAJOR 1
#define HUMIDITY_VERSION_MINOR 0
#ifdef CONFIG_LWM2M_IPSO_HUMIDITY_SENSOR_TIMESTAMP #ifdef CONFIG_LWM2M_IPSO_HUMIDITY_SENSOR_TIMESTAMP
#define ADD_TIMESTAMPS 1 #define ADD_TIMESTAMPS 1
#define NUMBER_OF_OBJ_FIELDS 8 #define NUMBER_OF_OBJ_FIELDS 8
@ -219,6 +222,9 @@ humidity_sensor_create(uint16_t obj_inst_id)
static int ipso_humidity_sensor_init(const struct device *dev) static int ipso_humidity_sensor_init(const struct device *dev)
{ {
sensor.obj_id = IPSO_OBJECT_ID; sensor.obj_id = IPSO_OBJECT_ID;
sensor.version_major = HUMIDITY_VERSION_MAJOR;
sensor.version_minor = HUMIDITY_VERSION_MINOR;
sensor.is_core = false;
sensor.fields = fields; sensor.fields = fields;
sensor.field_count = ARRAY_SIZE(fields); sensor.field_count = ARRAY_SIZE(fields);
sensor.max_instance_count = MAX_INSTANCE_COUNT; sensor.max_instance_count = MAX_INSTANCE_COUNT;

View file

@ -23,6 +23,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define LIGHT_VERSION_MAJOR 1
#define LIGHT_VERSION_MINOR 0
/* Server resource IDs */ /* Server resource IDs */
#define LIGHT_ON_OFF_ID 5850 #define LIGHT_ON_OFF_ID 5850
#define LIGHT_DIMMER_ID 5851 #define LIGHT_DIMMER_ID 5851
@ -202,6 +205,9 @@ static struct lwm2m_engine_obj_inst *light_control_create(uint16_t obj_inst_id)
static int ipso_light_control_init(const struct device *dev) static int ipso_light_control_init(const struct device *dev)
{ {
light_control.obj_id = IPSO_OBJECT_LIGHT_CONTROL_ID; light_control.obj_id = IPSO_OBJECT_LIGHT_CONTROL_ID;
light_control.version_major = LIGHT_VERSION_MAJOR;
light_control.version_minor = LIGHT_VERSION_MINOR;
light_control.is_core = false;
light_control.fields = fields; light_control.fields = fields;
light_control.field_count = ARRAY_SIZE(fields); light_control.field_count = ARRAY_SIZE(fields);
light_control.max_instance_count = MAX_INSTANCE_COUNT; light_control.max_instance_count = MAX_INSTANCE_COUNT;

View file

@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define SWITCH_VERSION_MAJOR 1
#define SWITCH_VERSION_MINOR 0
#ifdef CONFIG_LWM2M_IPSO_ONOFF_SWITCH_TIMESTAMP #ifdef CONFIG_LWM2M_IPSO_ONOFF_SWITCH_TIMESTAMP
#define ADD_TIMESTAMPS 1 #define ADD_TIMESTAMPS 1
#else #else
@ -243,6 +246,9 @@ static struct lwm2m_engine_obj_inst *switch_create(uint16_t obj_inst_id)
static int ipso_switch_init(const struct device *dev) static int ipso_switch_init(const struct device *dev)
{ {
onoff_switch.obj_id = IPSO_OBJECT_ONOFF_SWITCH_ID; onoff_switch.obj_id = IPSO_OBJECT_ONOFF_SWITCH_ID;
onoff_switch.version_major = SWITCH_VERSION_MAJOR;
onoff_switch.version_minor = SWITCH_VERSION_MINOR;
onoff_switch.is_core = false;
onoff_switch.fields = fields; onoff_switch.fields = fields;
onoff_switch.field_count = ARRAY_SIZE(fields); onoff_switch.field_count = ARRAY_SIZE(fields);
onoff_switch.max_instance_count = ARRAY_SIZE(inst); onoff_switch.max_instance_count = ARRAY_SIZE(inst);

View file

@ -19,6 +19,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#include "lwm2m_resource_ids.h" #include "lwm2m_resource_ids.h"
#define PRESSURE_VERSION_MAJOR 1
#define PRESSURE_VERSION_MINOR 0
#ifdef CONFIG_LWM2M_IPSO_PRESSURE_SENSOR_TIMESTAMP #ifdef CONFIG_LWM2M_IPSO_PRESSURE_SENSOR_TIMESTAMP
#define ADD_TIMESTAMPS 1 #define ADD_TIMESTAMPS 1
#define NUMBER_OF_OBJ_FIELDS 8 #define NUMBER_OF_OBJ_FIELDS 8
@ -219,6 +222,9 @@ pressure_sensor_create(uint16_t obj_inst_id)
static int ipso_pressure_sensor_init(const struct device *dev) static int ipso_pressure_sensor_init(const struct device *dev)
{ {
sensor.obj_id = IPSO_OBJECT_ID; sensor.obj_id = IPSO_OBJECT_ID;
sensor.version_major = PRESSURE_VERSION_MAJOR;
sensor.version_minor = PRESSURE_VERSION_MINOR;
sensor.is_core = false;
sensor.fields = fields; sensor.fields = fields;
sensor.field_count = ARRAY_SIZE(fields); sensor.field_count = ARRAY_SIZE(fields);
sensor.max_instance_count = MAX_INSTANCE_COUNT; sensor.max_instance_count = MAX_INSTANCE_COUNT;

View file

@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define BUTTON_VERSION_MAJOR 1
#define BUTTON_VERSION_MINOR 0
#ifdef CONFIG_LWM2M_IPSO_PUSH_BUTTON_TIMESTAMP #ifdef CONFIG_LWM2M_IPSO_PUSH_BUTTON_TIMESTAMP
#define ADD_TIMESTAMPS 1 #define ADD_TIMESTAMPS 1
#else #else
@ -169,6 +172,9 @@ static struct lwm2m_engine_obj_inst *button_create(uint16_t obj_inst_id)
static int ipso_button_init(const struct device *dev) static int ipso_button_init(const struct device *dev)
{ {
onoff_switch.obj_id = IPSO_OBJECT_PUSH_BUTTON_ID; onoff_switch.obj_id = IPSO_OBJECT_PUSH_BUTTON_ID;
onoff_switch.version_major = BUTTON_VERSION_MAJOR;
onoff_switch.version_minor = BUTTON_VERSION_MINOR;
onoff_switch.is_core = false;
onoff_switch.fields = fields; onoff_switch.fields = fields;
onoff_switch.field_count = ARRAY_SIZE(fields); onoff_switch.field_count = ARRAY_SIZE(fields);
onoff_switch.max_instance_count = ARRAY_SIZE(inst); onoff_switch.max_instance_count = ARRAY_SIZE(inst);

View file

@ -23,6 +23,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define TEMP_VERSION_MAJOR 1
#define TEMP_VERSION_MINOR 0
#ifdef CONFIG_LWM2M_IPSO_TEMP_SENSOR_TIMESTAMP #ifdef CONFIG_LWM2M_IPSO_TEMP_SENSOR_TIMESTAMP
#define ADD_TIMESTAMPS 1 #define ADD_TIMESTAMPS 1
#else #else
@ -236,6 +239,9 @@ static struct lwm2m_engine_obj_inst *temp_sensor_create(uint16_t obj_inst_id)
static int ipso_temp_sensor_init(const struct device *dev) static int ipso_temp_sensor_init(const struct device *dev)
{ {
temp_sensor.obj_id = IPSO_OBJECT_TEMP_SENSOR_ID; temp_sensor.obj_id = IPSO_OBJECT_TEMP_SENSOR_ID;
temp_sensor.version_major = TEMP_VERSION_MAJOR;
temp_sensor.version_minor = TEMP_VERSION_MINOR;
temp_sensor.is_core = false;
temp_sensor.fields = fields; temp_sensor.fields = fields;
temp_sensor.field_count = ARRAY_SIZE(fields); temp_sensor.field_count = ARRAY_SIZE(fields);
temp_sensor.max_instance_count = MAX_INSTANCE_COUNT; temp_sensor.max_instance_count = MAX_INSTANCE_COUNT;

View file

@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define TIMER_VERSION_MAJOR 1
#define TIMER_VERSION_MINOR 0
/* Server resource IDs */ /* Server resource IDs */
#define TIMER_DELAY_DURATION_ID 5521 #define TIMER_DELAY_DURATION_ID 5521
#define TIMER_REMAINING_TIME_ID 5538 #define TIMER_REMAINING_TIME_ID 5538
@ -386,6 +389,9 @@ static struct lwm2m_engine_obj_inst *timer_create(uint16_t obj_inst_id)
static int ipso_timer_init(const struct device *dev) static int ipso_timer_init(const struct device *dev)
{ {
timer.obj_id = IPSO_OBJECT_TIMER_ID; timer.obj_id = IPSO_OBJECT_TIMER_ID;
timer.version_major = TIMER_VERSION_MAJOR;
timer.version_minor = TIMER_VERSION_MINOR;
timer.is_core = false;
timer.fields = fields; timer.fields = fields;
timer.field_count = ARRAY_SIZE(fields); timer.field_count = ARRAY_SIZE(fields);
timer.max_instance_count = MAX_INSTANCE_COUNT; timer.max_instance_count = MAX_INSTANCE_COUNT;

View file

@ -1094,8 +1094,11 @@ int lwm2m_register_payload_handler(struct lwm2m_message *msg)
continue; continue;
} }
/* Only report <OBJ_ID> when no instance available */ /* Only report <OBJ_ID> when no instance available or it's
if (obj->instance_count == 0U) { * needed to report object version.
*/
if (obj->instance_count == 0U ||
lwm2m_engine_shall_report_obj_version(obj)) {
struct lwm2m_obj_path path = { struct lwm2m_obj_path path = {
.obj_id = obj->obj_id, .obj_id = obj->obj_id,
.level = LWM2M_PATH_LEVEL_OBJECT, .level = LWM2M_PATH_LEVEL_OBJECT,
@ -1106,8 +1109,10 @@ int lwm2m_register_payload_handler(struct lwm2m_message *msg)
return ret; return ret;
} }
if (obj->instance_count == 0U) {
continue; continue;
} }
}
SYS_SLIST_FOR_EACH_CONTAINER(&engine_obj_inst_list, SYS_SLIST_FOR_EACH_CONTAINER(&engine_obj_inst_list,
obj_inst, node) { obj_inst, node) {
@ -3263,11 +3268,13 @@ int lwm2m_discover_handler(struct lwm2m_message *msg, bool is_bootstrap)
} }
/* For bootstrap discover, only report object ID when no /* For bootstrap discover, only report object ID when no
* instance is available. * instance is available or it's needed to report object
* version.
* For device management discovery, only report object ID with * For device management discovery, only report object ID with
* attributes if object ID (alone) was provided. * attributes if object ID (alone) was provided.
*/ */
if ((is_bootstrap && obj->instance_count == 0U) || if ((is_bootstrap && (obj->instance_count == 0U ||
lwm2m_engine_shall_report_obj_version(obj))) ||
(!is_bootstrap && msg->path.level == LWM2M_PATH_LEVEL_OBJECT)) { (!is_bootstrap && msg->path.level == LWM2M_PATH_LEVEL_OBJECT)) {
struct lwm2m_obj_path path = { struct lwm2m_obj_path path = {
.obj_id = obj->obj_id, .obj_id = obj->obj_id,
@ -3281,7 +3288,7 @@ int lwm2m_discover_handler(struct lwm2m_message *msg, bool is_bootstrap)
reported = true; reported = true;
if (is_bootstrap) { if (obj->instance_count == 0U) {
continue; continue;
} }
} }
@ -3434,6 +3441,16 @@ struct lwm2m_engine_res *lwm2m_engine_get_res(
return res; return res;
} }
bool lwm2m_engine_shall_report_obj_version(const struct lwm2m_engine_obj *obj)
{
if (obj->is_core) {
return obj->version_major != LWM2M_PROTOCOL_VERSION_MAJOR ||
obj->version_minor != LWM2M_PROTOCOL_VERSION_MINOR;
}
return obj->version_major != 1 || obj->version_minor != 0;
}
static int do_write_op(struct lwm2m_message *msg, static int do_write_op(struct lwm2m_message *msg,
uint16_t format) uint16_t format)
{ {

View file

@ -10,7 +10,12 @@
#include "lwm2m_object.h" #include "lwm2m_object.h"
#define LWM2M_PROTOCOL_VERSION "1.0" #define LWM2M_PROTOCOL_VERSION_MAJOR 1
#define LWM2M_PROTOCOL_VERSION_MINOR 0
#define LWM2M_PROTOCOL_VERSION_STRING STRINGIFY(LWM2M_PROTOCOL_VERSION_MAJOR) \
"." \
STRINGIFY(LWM2M_PROTOCOL_VERSION_MINOR)
/* LWM2M / CoAP Content-Formats */ /* LWM2M / CoAP Content-Formats */
#define LWM2M_FORMAT_PLAIN_TEXT 0 #define LWM2M_FORMAT_PLAIN_TEXT 0
@ -72,6 +77,8 @@ struct lwm2m_engine_obj_inst *lwm2m_engine_get_obj_inst(
struct lwm2m_engine_res *lwm2m_engine_get_res( struct lwm2m_engine_res *lwm2m_engine_get_res(
const struct lwm2m_obj_path *path); const struct lwm2m_obj_path *path);
bool lwm2m_engine_shall_report_obj_version(const struct lwm2m_engine_obj *obj);
/* LwM2M context functions */ /* LwM2M context functions */
int lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx); int lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx);
void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx); void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx);

View file

@ -18,6 +18,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define CONNMON_VERSION_MAJOR 1
#define CONNMON_VERSION_MINOR 0
/* Connectivity Monitoring resource IDs */ /* Connectivity Monitoring resource IDs */
#define CONNMON_NETWORK_BEARER_ID 0 #define CONNMON_NETWORK_BEARER_ID 0
#define CONNMON_AVAIL_NETWORK_BEARER_ID 1 #define CONNMON_AVAIL_NETWORK_BEARER_ID 1
@ -148,6 +151,9 @@ static int lwm2m_connmon_init(const struct device *dev)
/* initialize the Connection Monitoring field data */ /* initialize the Connection Monitoring field data */
connmon.obj_id = LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID; connmon.obj_id = LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID;
connmon.version_major = CONNMON_VERSION_MAJOR;
connmon.version_minor = CONNMON_VERSION_MINOR;
connmon.is_core = true;
connmon.fields = fields; connmon.fields = fields;
connmon.field_count = ARRAY_SIZE(fields); connmon.field_count = ARRAY_SIZE(fields);
connmon.max_instance_count = 1U; connmon.max_instance_count = 1U;

View file

@ -23,6 +23,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define DEVICE_VERSION_MAJOR 1
#define DEVICE_VERSION_MINOR 0
/* Device resource IDs */ /* Device resource IDs */
#define DEVICE_MANUFACTURER_ID 0 #define DEVICE_MANUFACTURER_ID 0
#define DEVICE_MODEL_NUMBER_ID 1 #define DEVICE_MODEL_NUMBER_ID 1
@ -260,6 +263,9 @@ static int lwm2m_device_init(const struct device *dev)
/* initialize the device field data */ /* initialize the device field data */
device.obj_id = LWM2M_OBJECT_DEVICE_ID; device.obj_id = LWM2M_OBJECT_DEVICE_ID;
device.version_major = DEVICE_VERSION_MAJOR;
device.version_minor = DEVICE_VERSION_MINOR;
device.is_core = true;
device.fields = fields; device.fields = fields;
device.field_count = ARRAY_SIZE(fields); device.field_count = ARRAY_SIZE(fields);
device.max_instance_count = 1U; device.max_instance_count = 1U;

View file

@ -17,6 +17,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define FIRMWARE_VERSION_MAJOR 1
#define FIRMWARE_VERSION_MINOR 0
/* Firmware resource IDs */ /* Firmware resource IDs */
#define FIRMWARE_PACKAGE_ID 0 #define FIRMWARE_PACKAGE_ID 0
#define FIRMWARE_PACKAGE_URI_ID 1 #define FIRMWARE_PACKAGE_URI_ID 1
@ -357,6 +360,9 @@ static int lwm2m_firmware_init(const struct device *dev)
#endif #endif
firmware.obj_id = LWM2M_OBJECT_FIRMWARE_ID; firmware.obj_id = LWM2M_OBJECT_FIRMWARE_ID;
firmware.version_major = FIRMWARE_VERSION_MAJOR;
firmware.version_minor = FIRMWARE_VERSION_MINOR;
firmware.is_core = true;
firmware.fields = fields; firmware.fields = fields;
firmware.field_count = ARRAY_SIZE(fields); firmware.field_count = ARRAY_SIZE(fields);
firmware.max_instance_count = 1U; firmware.max_instance_count = 1U;

View file

@ -16,6 +16,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define LOCATION_VERSION_MAJOR 1
#define LOCATION_VERSION_MINOR 0
/* resource IDs */ /* resource IDs */
#define LOCATION_LATITUDE_ID 0 #define LOCATION_LATITUDE_ID 0
#define LOCATION_LONGITUDE_ID 1 #define LOCATION_LONGITUDE_ID 1
@ -96,6 +99,9 @@ static int ipso_location_init(const struct device *dev)
struct lwm2m_engine_obj_inst *obj_inst = NULL; struct lwm2m_engine_obj_inst *obj_inst = NULL;
location.obj_id = LWM2M_OBJECT_LOCATION_ID; location.obj_id = LWM2M_OBJECT_LOCATION_ID;
location.version_major = LOCATION_VERSION_MAJOR;
location.version_minor = LOCATION_VERSION_MINOR;
location.is_core = true;
location.fields = fields; location.fields = fields;
location.field_count = ARRAY_SIZE(fields); location.field_count = ARRAY_SIZE(fields);
location.max_instance_count = 1U; location.max_instance_count = 1U;

View file

@ -17,6 +17,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_engine.h" #include "lwm2m_engine.h"
#define SECURITY_VERSION_MAJOR 1
#define SECURITY_VERSION_MINOR 0
/* Security resource IDs */ /* Security resource IDs */
#define SECURITY_SERVER_URI_ID 0 #define SECURITY_SERVER_URI_ID 0
#define SECURITY_BOOTSTRAP_FLAG_ID 1 #define SECURITY_BOOTSTRAP_FLAG_ID 1
@ -176,6 +179,9 @@ static int lwm2m_security_init(const struct device *dev)
int ret = 0; int ret = 0;
security.obj_id = LWM2M_OBJECT_SECURITY_ID; security.obj_id = LWM2M_OBJECT_SECURITY_ID;
security.version_major = SECURITY_VERSION_MAJOR;
security.version_minor = SECURITY_VERSION_MINOR;
security.is_core = true;
security.fields = fields; security.fields = fields;
security.field_count = ARRAY_SIZE(fields); security.field_count = ARRAY_SIZE(fields);
security.max_instance_count = MAX_INSTANCE_COUNT; security.max_instance_count = MAX_INSTANCE_COUNT;

View file

@ -20,6 +20,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_rd_client.h" #include "lwm2m_rd_client.h"
#endif #endif
#define SERVER_VERSION_MAJOR 1
#define SERVER_VERSION_MINOR 0
/* Server resource IDs */ /* Server resource IDs */
#define SERVER_SHORT_SERVER_ID 0 #define SERVER_SHORT_SERVER_ID 0
#define SERVER_LIFETIME_ID 1 #define SERVER_LIFETIME_ID 1
@ -250,6 +253,9 @@ static int lwm2m_server_init(const struct device *dev)
int ret = 0; int ret = 0;
server.obj_id = LWM2M_OBJECT_SERVER_ID; server.obj_id = LWM2M_OBJECT_SERVER_ID;
server.version_major = SERVER_VERSION_MAJOR;
server.version_minor = SERVER_VERSION_MINOR;
server.is_core = true;
server.fields = fields; server.fields = fields;
server.field_count = ARRAY_SIZE(fields); server.field_count = ARRAY_SIZE(fields);
server.max_instance_count = MAX_INSTANCE_COUNT; server.max_instance_count = MAX_INSTANCE_COUNT;

View file

@ -198,6 +198,13 @@ struct lwm2m_engine_obj {
uint16_t field_count; uint16_t field_count;
uint16_t instance_count; uint16_t instance_count;
uint16_t max_instance_count; uint16_t max_instance_count;
/* Object version information. */
uint8_t version_major;
uint8_t version_minor;
/* Object is a core object (defined in the official LwM2M spec.) */
bool is_core : 1;
}; };
/* Resource instances with this value are considered "not created" yet */ /* Resource instances with this value are considered "not created" yet */

View file

@ -714,7 +714,7 @@ static int sm_send_registration(bool send_obj_support_data,
if (!sm_is_registered()) { if (!sm_is_registered()) {
snprintk(query_buffer, sizeof(query_buffer) - 1, snprintk(query_buffer, sizeof(query_buffer) - 1,
"lwm2m=%s", LWM2M_PROTOCOL_VERSION); "lwm2m=%s", LWM2M_PROTOCOL_VERSION_STRING);
ret = coap_packet_append_option( ret = coap_packet_append_option(
&msg->cpkt, COAP_OPTION_URI_QUERY, &msg->cpkt, COAP_OPTION_URI_QUERY,
query_buffer, strlen(query_buffer)); query_buffer, strlen(query_buffer));

View file

@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(net_lwm2m_link_format, CONFIG_LWM2M_LOG_LEVEL);
#define CORELINK_BUF_SIZE 24 #define CORELINK_BUF_SIZE 24
#define ENABLER_VERSION "lwm2m=\"" LWM2M_PROTOCOL_VERSION "\"" #define ENABLER_VERSION "lwm2m=\"" LWM2M_PROTOCOL_VERSION_STRING "\""
/* /*
* TODO: to implement a way for clients to specify alternate path * TODO: to implement a way for clients to specify alternate path
@ -105,6 +105,26 @@ static int put_corelink_separator(struct lwm2m_output_context *out)
return (int)sizeof(comma); return (int)sizeof(comma);
} }
static int put_corelink_version(struct lwm2m_output_context *out,
const struct lwm2m_engine_obj *obj,
uint8_t *buf, uint16_t buflen)
{
int ret, len;
len = snprintk(buf, buflen, ";ver=%u.%u", obj->version_major,
obj->version_minor);
if (len < 0 || len >= buflen) {
return -ENOMEM;
}
ret = buf_append(CPKT_BUF_WRITE(out->out_cpkt), buf, len);
if (ret < 0) {
return ret;
}
return len;
}
static int put_corelink_dimension(struct lwm2m_output_context *out, static int put_corelink_dimension(struct lwm2m_output_context *out,
const struct lwm2m_engine_res *res, const struct lwm2m_engine_res *res,
uint8_t *buf, uint16_t buflen) uint8_t *buf, uint16_t buflen)
@ -264,6 +284,7 @@ static int put_obj_corelink(struct lwm2m_output_context *out,
struct link_format_out_formatter_data *fd) struct link_format_out_formatter_data *fd)
{ {
char obj_buf[CORELINK_BUF_SIZE]; char obj_buf[CORELINK_BUF_SIZE];
struct lwm2m_engine_obj *obj;
int len = 0; int len = 0;
int ret; int ret;
@ -279,16 +300,24 @@ static int put_obj_corelink(struct lwm2m_output_context *out,
return ret; return ret;
} }
if (fd->mode == LINK_FORMAT_MODE_DISCOVERY) { obj = lwm2m_engine_get_obj(path);
/* Report object attributes only in device management mode
* (5.4.2).
*/
struct lwm2m_engine_obj *obj = lwm2m_engine_get_obj(path);
if (obj == NULL) { if (obj == NULL) {
return -EINVAL; return -EINVAL;
} }
if (lwm2m_engine_shall_report_obj_version(obj)) {
ret = put_corelink_version(out, obj, obj_buf, sizeof(obj_buf));
if (ret < 0) {
return ret;
}
len += ret;
}
if (fd->mode == LINK_FORMAT_MODE_DISCOVERY) {
/* Report object attributes only in device management mode
* (5.4.2).
*/
ret = put_corelink_attributes(out, obj, obj_buf, ret = put_corelink_attributes(out, obj, obj_buf,
sizeof(obj_buf)); sizeof(obj_buf));
if (ret < 0) { if (ret < 0) {