net: lwm2m: Add proper resource-level discovery attribute handling

In case an individual resource is being discovered, the LwM2M client
should not only fill the attributes assinged at the resource level, but
also the ones inherited from the object and object instance levels.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2022-02-03 16:58:28 +01:00 committed by Marti Bolivar
commit 9ac83be650
2 changed files with 110 additions and 38 deletions

View file

@ -142,20 +142,16 @@ static int put_corelink_dimension(struct lwm2m_output_context *out,
return len;
}
static int put_corelink_attributes(struct lwm2m_output_context *out,
const void *ref, uint8_t *buf,
static int put_attribute(struct lwm2m_output_context *out,
struct lwm2m_attr *attr, uint8_t *buf,
uint16_t buflen)
{
struct lwm2m_attr *attr = NULL;
int used, ret;
int len = 0;
while ((attr = lwm2m_engine_get_next_attr(ref, attr)) != NULL) {
const char *name = lwm2m_engine_get_attr_name(attr);
if (name == NULL) {
/* Invalid attribute, ignore. */
continue;
return 0;
}
if (attr->type <= LWM2M_ATTR_PMAX) {
@ -176,17 +172,84 @@ static int put_corelink_attributes(struct lwm2m_output_context *out,
return -ENOMEM;
}
len += used;
ret = buf_append(CPKT_BUF_WRITE(out->out_cpkt), buf, used);
if (ret < 0) {
return ret;
}
return used;
}
static int put_attributes(struct lwm2m_output_context *out,
struct lwm2m_attr **attrs, uint8_t *buf,
uint16_t buflen)
{
int ret;
int len = 0;
for (int i = 0; i < NR_LWM2M_ATTR; i++) {
if (attrs[i] == NULL) {
continue;
}
ret = put_attribute(out, attrs[i], buf, buflen);
if (ret < 0) {
return ret;
}
len += ret;
}
return len;
}
static void get_attributes(const void *ref, struct lwm2m_attr **attrs)
{
struct lwm2m_attr *attr = NULL;
while ((attr = lwm2m_engine_get_next_attr(ref, attr)) != NULL) {
if (attr->type >= NR_LWM2M_ATTR) {
continue;
}
attrs[attr->type] = attr;
}
}
static int put_corelink_attributes(struct lwm2m_output_context *out,
const void *ref, uint8_t *buf,
uint16_t buflen)
{
struct lwm2m_attr *attrs[NR_LWM2M_ATTR] = { 0 };
get_attributes(ref, attrs);
return put_attributes(out, attrs, buf, buflen);
}
/* Resource-level attribute request - should propagate attributes from Object
* and Object Instance.
*/
static int put_corelink_attributes_resource(struct lwm2m_output_context *out,
const struct lwm2m_obj_path *path,
uint8_t *buf, uint16_t buflen)
{
struct lwm2m_attr *attrs[NR_LWM2M_ATTR] = { 0 };
struct lwm2m_engine_obj *obj = lwm2m_engine_get_obj(path);
struct lwm2m_engine_obj_inst *obj_inst = lwm2m_engine_get_obj_inst(path);
struct lwm2m_engine_res *res = lwm2m_engine_get_res(path);
if (obj == NULL || obj_inst == NULL || res == NULL) {
return -ENOENT;
}
get_attributes(obj, attrs);
get_attributes(obj_inst, attrs);
get_attributes(res, attrs);
return put_attributes(out, attrs, buf, buflen);
}
static int put_corelink_ssid(struct lwm2m_output_context *out,
const struct lwm2m_obj_path *path,
uint8_t *buf, uint16_t buflen)
@ -424,11 +487,19 @@ static int put_res_corelink(struct lwm2m_output_context *out,
len += ret;
ret = put_corelink_attributes(out, res, obj_buf,
sizeof(obj_buf));
if (fd->request_level == LWM2M_PATH_LEVEL_RESOURCE) {
ret = put_corelink_attributes_resource(
out, path, obj_buf, sizeof(obj_buf));
if (ret < 0) {
return ret;
}
} else {
ret = put_corelink_attributes(
out, res, obj_buf, sizeof(obj_buf));
if (ret < 0) {
return ret;
}
}
len += ret;
}

View file

@ -218,7 +218,8 @@ static void test_put_corelink_discovery(void)
{
.request_level = LWM2M_PATH_LEVEL_RESOURCE,
.path_level = LWM2M_PATH_LEVEL_RESOURCE,
.expected_payload = "</65535/0/0>;pmax=" STRINGIFY(TEST_PMAX)
.expected_payload = "</65535/0/0>;pmin=" STRINGIFY(TEST_PMIN)
";pmax=" STRINGIFY(TEST_PMAX)
},
};