net: lwm2m: Add dimension discovery support

Multi-instance resources shall report its dimension (number of
resource instances) on discovery. Since it was not possible to tell
simply on the instance count whether the resource is multi-instance or
not (there could be a multi-instance resource with only one instance
avaialble) add a new parameter to the structure representing resource,
indicating whether it's multi-instance or not.

Add dimension information to the discovery result.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2020-11-26 16:51:49 +01:00 committed by Carles Cufí
parent 18cfc3761e
commit 366a2147cc
14 changed files with 69 additions and 36 deletions

View file

@ -213,7 +213,7 @@ static struct lwm2m_engine_obj_inst *buzzer_create(uint16_t obj_inst_id)
/* initialize instance resource data */
INIT_OBJ_RES(BUZZER_ON_OFF_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
&buzzer_data[avail].onoff,
sizeof(buzzer_data[avail].onoff),
NULL, NULL, onoff_post_write_cb, NULL);

View file

@ -206,8 +206,8 @@ static struct lwm2m_engine_obj_inst *generic_sensor_create(uint16_t obj_inst_id)
/* initialize instance resource data */
INIT_OBJ_RES(SENSOR_VALUE_RID, res[index], i, res_inst[index], j, 1,
true, &sensor_value[index], sizeof(*sensor_value), NULL,
NULL, sensor_value_write_cb, NULL);
false, true, &sensor_value[index], sizeof(*sensor_value),
NULL, NULL, sensor_value_write_cb, NULL);
INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j,
units[index], UNIT_STR_MAX_SIZE);
INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i,

View file

@ -189,8 +189,8 @@ humidity_sensor_create(uint16_t obj_inst_id)
/* initialize instance resource data */
INIT_OBJ_RES(SENSOR_VALUE_RID, res[index], i, res_inst[index], j, 1,
true, &sensor_value[index], sizeof(*sensor_value), NULL,
NULL, sensor_value_write_cb, NULL);
false, true, &sensor_value[index], sizeof(*sensor_value),
NULL, NULL, sensor_value_write_cb, NULL);
INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j,
units[index], UNIT_STR_MAX_SIZE);
INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i,

View file

@ -171,7 +171,7 @@ static struct lwm2m_engine_obj_inst *light_control_create(uint16_t obj_inst_id)
INIT_OBJ_RES_DATA(LIGHT_DIMMER_ID, res[avail], i, res_inst[avail], j,
&dimmer_value[avail], sizeof(*dimmer_value));
INIT_OBJ_RES(LIGHT_ON_TIME_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
&on_time_value[avail], sizeof(*on_time_value),
on_time_read_cb, NULL, on_time_post_write_cb, NULL);
INIT_OBJ_RES_DATA(LIGHT_CUMULATIVE_ACTIVE_POWER_ID, res[avail], i,

View file

@ -211,7 +211,7 @@ static struct lwm2m_engine_obj_inst *switch_create(uint16_t obj_inst_id)
/* initialize instance resource data */
INIT_OBJ_RES(SWITCH_DIGITAL_STATE_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
&switch_data[avail].state,
sizeof(switch_data[avail].state),
NULL, NULL, state_post_write_cb, NULL);
@ -220,10 +220,10 @@ static struct lwm2m_engine_obj_inst *switch_create(uint16_t obj_inst_id)
&switch_data[avail].counter,
sizeof(switch_data[avail].counter));
INIT_OBJ_RES_OPT(SWITCH_ON_TIME_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
on_time_read_cb, NULL, time_post_write_cb, NULL);
INIT_OBJ_RES_OPT(SWITCH_OFF_TIME_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
off_time_read_cb, NULL, time_post_write_cb, NULL);
INIT_OBJ_RES_OPTDATA(SWITCH_APPLICATION_TYPE_ID, res[avail], i,
res_inst[avail], j);

View file

@ -189,8 +189,8 @@ pressure_sensor_create(uint16_t obj_inst_id)
/* initialize instance resource data */
INIT_OBJ_RES(SENSOR_VALUE_RID, res[index], i, res_inst[index], j, 1,
true, &sensor_value[index], sizeof(*sensor_value), NULL,
NULL, sensor_value_write_cb, NULL);
false, true, &sensor_value[index], sizeof(*sensor_value),
NULL, NULL, sensor_value_write_cb, NULL);
INIT_OBJ_RES_DATA(SENSOR_UNITS_RID, res[index], i, res_inst[index], j,
units[index], UNIT_STR_MAX_SIZE);
INIT_OBJ_RES_DATA(MIN_MEASURED_VALUE_RID, res[index], i,

View file

@ -143,7 +143,7 @@ static struct lwm2m_engine_obj_inst *button_create(uint16_t obj_inst_id)
/* initialize instance resource data */
INIT_OBJ_RES(BUTTON_DIGITAL_STATE_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
&button_data[avail].state,
sizeof(button_data[avail].state),
NULL, NULL, state_post_write_cb, NULL);

View file

@ -203,7 +203,7 @@ static struct lwm2m_engine_obj_inst *temp_sensor_create(uint16_t obj_inst_id)
/* initialize instance resource data */
INIT_OBJ_RES(TEMP_SENSOR_VALUE_ID, res[index], i,
res_inst[index], j, 1, true,
res_inst[index], j, 1, false, true,
&sensor_value[index], sizeof(*sensor_value),
NULL, NULL, sensor_value_write_cb, NULL);
INIT_OBJ_RES_DATA(TEMP_UNITS_ID, res[index], i, res_inst[index], j,

View file

@ -341,7 +341,7 @@ static struct lwm2m_engine_obj_inst *timer_create(uint16_t obj_inst_id)
res_inst[avail], j, &timer_data[avail].delay_duration,
sizeof(timer_data[avail].delay_duration));
INIT_OBJ_RES(TIMER_REMAINING_TIME_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
&timer_data[avail].remaining_time,
sizeof(timer_data[avail].remaining_time),
remaining_time_read_cb, NULL, NULL, NULL);
@ -351,12 +351,12 @@ static struct lwm2m_engine_obj_inst *timer_create(uint16_t obj_inst_id)
INIT_OBJ_RES_EXECUTE(TIMER_TRIGGER_ID, res[avail], i,
timer_trigger_cb);
INIT_OBJ_RES(TIMER_ON_OFF_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
&timer_data[avail].enabled,
sizeof(timer_data[avail].enabled),
NULL, NULL, enabled_post_write_cb, NULL);
INIT_OBJ_RES(TIMER_CUMULATIVE_TIME_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
&timer_data[avail].cumulative_time,
sizeof(timer_data[avail].cumulative_time),
cumulative_time_read_cb, NULL,
@ -365,7 +365,7 @@ static struct lwm2m_engine_obj_inst *timer_create(uint16_t obj_inst_id)
res_inst[avail], j, &timer_data[avail].active,
sizeof(timer_data[avail].active));
INIT_OBJ_RES(TIMER_COUNTER_ID, res[avail], i,
res_inst[avail], j, 1, true,
res_inst[avail], j, 1, false, true,
&timer_data[avail].trigger_counter,
sizeof(timer_data[avail].trigger_counter),
NULL, NULL, trigger_counter_post_write_cb, NULL);

View file

@ -3089,6 +3089,31 @@ static int print_attr(struct lwm2m_output_context *out,
return 0;
}
static int print_resource_dimension(struct lwm2m_output_context *out,
uint8_t *buf, uint16_t buflen,
struct lwm2m_engine_res *res)
{
int ret, i, inst_count = 0;
if (res->multi_res_inst) {
for (i = 0; i < res->res_inst_count; i++) {
if (res->res_instances[i].res_inst_id !=
RES_INSTANCE_NOT_CREATED) {
inst_count++;
}
}
snprintk(buf, buflen, ";dim=%d", inst_count);
ret = buf_append(CPKT_BUF_WRITE(out->out_cpkt), buf,
strlen(buf));
if (ret < 0) {
return ret;
}
}
return 0;
}
static int do_discover_op(struct lwm2m_message *msg, bool well_known)
{
static char disc_buf[24];
@ -3233,6 +3258,13 @@ static int do_discover_op(struct lwm2m_message *msg, bool well_known)
/* report resource attrs when path > 1 (5.4.2) */
if (msg->path.level > 1) {
ret = print_resource_dimension(
&msg->out, disc_buf, sizeof(disc_buf),
&obj_inst->resources[i]);
if (ret < 0) {
return ret;
}
ret = print_attr(&msg->out,
disc_buf, sizeof(disc_buf),
&obj_inst->resources[i]);

View file

@ -227,9 +227,8 @@ static struct lwm2m_engine_obj_inst *device_create(uint16_t obj_inst_id)
error_code_list, sizeof(*error_code_list));
INIT_OBJ_RES_EXECUTE(DEVICE_RESET_ERROR_CODE_ID, res, i,
reset_error_list_cb);
INIT_OBJ_RES_OPT(DEVICE_CURRENT_TIME_ID, res, i, res_inst, j, 1, true,
current_time_read_cb,
current_time_pre_write_cb,
INIT_OBJ_RES_OPT(DEVICE_CURRENT_TIME_ID, res, i, res_inst, j, 1, false,
true, current_time_read_cb, current_time_pre_write_cb,
current_time_post_write_cb, NULL);
INIT_OBJ_RES_OPTDATA(DEVICE_UTC_OFFSET_ID, res, i, res_inst, j);
INIT_OBJ_RES_OPTDATA(DEVICE_TIMEZONE_ID, res, i, res_inst, j);

View file

@ -319,10 +319,10 @@ static struct lwm2m_engine_obj_inst *firmware_create(uint16_t obj_inst_id)
init_res_instance(res_inst, ARRAY_SIZE(res_inst));
/* initialize instance resource data */
INIT_OBJ_RES_OPT(FIRMWARE_PACKAGE_ID, res, i, res_inst, j, 1, true,
NULL, NULL, package_write_cb, NULL);
INIT_OBJ_RES(FIRMWARE_PACKAGE_URI_ID, res, i, res_inst, j, 1, true,
package_uri, PACKAGE_URI_LEN,
INIT_OBJ_RES_OPT(FIRMWARE_PACKAGE_ID, res, i, res_inst, j, 1, false,
true, NULL, NULL, package_write_cb, NULL);
INIT_OBJ_RES(FIRMWARE_PACKAGE_URI_ID, res, i, res_inst, j, 1, false,
true, package_uri, PACKAGE_URI_LEN,
NULL, NULL, package_uri_write_cb, NULL);
INIT_OBJ_RES_EXECUTE(FIRMWARE_UPDATE_ID, res, i, firmware_update_cb);
INIT_OBJ_RES_DATA(FIRMWARE_STATE_ID, res, i, res_inst, j,

View file

@ -212,7 +212,7 @@ static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id)
res_inst[index], j,
&server_id[index], sizeof(*server_id));
INIT_OBJ_RES(SERVER_LIFETIME_ID, res[index], i, res_inst[index], j,
1U, true, &lifetime[index], sizeof(*lifetime),
1U, false, 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,

View file

@ -197,11 +197,12 @@ struct lwm2m_engine_obj {
#define RES_INSTANCE_NOT_CREATED 65535
/* Resource macros */
#define _INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_count, \
#define _INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_count, _multi_ri, \
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
_r_ptr[_r_idx].res_id = _id; \
_r_ptr[_r_idx].res_instances = _ri_ptr; \
_r_ptr[_r_idx].res_inst_count = _ri_count; \
_r_ptr[_r_idx].multi_res_inst = _multi_ri; \
_r_ptr[_r_idx].read_cb = _r_cb; \
_r_ptr[_r_idx].pre_write_cb = _pre_w_cb; \
_r_ptr[_r_idx].post_write_cb = _post_w_cb; \
@ -250,12 +251,12 @@ struct lwm2m_engine_obj {
} while (false)
#define INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
_ri_ptr, _ri_idx, _ri_count, _multi_ri, _ri_create, \
_data_ptr, _data_len, \
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
do { \
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
(_ri_ptr + _ri_idx), _ri_count, \
(_ri_ptr + _ri_idx), _ri_count, _multi_ri, \
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb); \
_INIT_OBJ_RES_INST(_ri_ptr, _ri_idx, _ri_count, _ri_create, \
_data_ptr, _data_len); \
@ -264,11 +265,11 @@ struct lwm2m_engine_obj {
#define INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, \
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
_ri_ptr, _ri_idx, _ri_count, _multi_ri, _ri_create, \
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb) \
do { \
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
(_ri_ptr + _ri_idx), _ri_count, \
(_ri_ptr + _ri_idx), _ri_count, _multi_ri, \
_r_cb, _pre_w_cb, _post_w_cb, _ex_cb); \
_INIT_OBJ_RES_INST_OPT(_ri_ptr, _ri_idx, _ri_count, _ri_create); \
++_r_idx; \
@ -278,27 +279,27 @@ struct lwm2m_engine_obj {
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
_data_ptr, _data_len) \
INIT_OBJ_RES(_id, _r_ptr, _r_idx, \
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
_ri_ptr, _ri_idx, _ri_count, true, _ri_create, \
_data_ptr, _data_len, NULL, NULL, NULL, NULL)
#define INIT_OBJ_RES_MULTI_OPTDATA(_id, _r_ptr, _r_idx, \
_ri_ptr, _ri_idx, _ri_count, _ri_create) \
INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, \
_ri_ptr, _ri_idx, _ri_count, _ri_create, \
_ri_ptr, _ri_idx, _ri_count, true, _ri_create, \
NULL, NULL, NULL, NULL)
#define INIT_OBJ_RES_DATA(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, \
_data_ptr, _data_len) \
INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, true, \
INIT_OBJ_RES(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, false, true, \
_data_ptr, _data_len, NULL, NULL, NULL, NULL)
#define INIT_OBJ_RES_OPTDATA(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx) \
INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, true, \
NULL, NULL, NULL, NULL)
INIT_OBJ_RES_OPT(_id, _r_ptr, _r_idx, _ri_ptr, _ri_idx, 1U, false, \
true, NULL, NULL, NULL, NULL)
#define INIT_OBJ_RES_EXECUTE(_id, _r_ptr, _r_idx, _ex_cb) \
do { \
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, NULL, 0, \
_INIT_OBJ_RES(_id, _r_ptr, _r_idx, NULL, 0, false, \
NULL, NULL, NULL, _ex_cb); \
++_r_idx; \
} while (false)
@ -341,6 +342,7 @@ struct lwm2m_engine_res {
struct lwm2m_engine_res_inst *res_instances;
uint16_t res_id;
uint8_t res_inst_count;
bool multi_res_inst;
};
struct lwm2m_engine_obj_inst {