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:
parent
18cfc3761e
commit
366a2147cc
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue