From f223d0a86f78954652196c18700c81abf92f6fdc Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 24 Sep 2020 15:28:10 +0200 Subject: [PATCH] net: lwm2m: Store the actual resource size in the resource instance So far, the resource instance structure kept only the information about the buffer length provided to the resource (in the `data_len` field). While this approach might be enough for integer resources, where the actual data size is fixed, it did not work for opaque resources. It is impossible to determine the actual opaque resource length after it's been written into. Fix this, by replacing the current `data_len` field of the `lwm2m_engine_res_inst` with `max_data_len`, indicating the buffer size, and making the `data_len` field to hold the actual data size of the resource. Signed-off-by: Robert Lubos --- subsys/net/lib/lwm2m/lwm2m_engine.c | 19 +++++++++++++------ .../net/lib/lwm2m/lwm2m_obj_firmware_pull.c | 2 +- subsys/net/lib/lwm2m/lwm2m_object.h | 4 ++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 194b45c92ff..c5b1ddfb780 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -1361,6 +1361,7 @@ int lwm2m_engine_set_res_data(char *pathstr, void *data_ptr, uint16_t data_len, /* assign data elements */ res_inst->data_ptr = data_ptr; res_inst->data_len = data_len; + res_inst->max_data_len = data_len; res_inst->data_flags = data_flags; return ret; @@ -1374,7 +1375,7 @@ static int lwm2m_engine_set(char *pathstr, void *value, uint16_t len) struct lwm2m_engine_res *res = NULL; struct lwm2m_engine_res_inst *res_inst = NULL; void *data_ptr = NULL; - size_t data_len = 0; + size_t max_data_len = 0; int ret = 0; bool changed = false; @@ -1411,13 +1412,13 @@ static int lwm2m_engine_set(char *pathstr, void *value, uint16_t len) /* setup initial data elements */ data_ptr = res_inst->data_ptr; - data_len = res_inst->data_len; + max_data_len = res_inst->max_data_len; /* allow user to override data elements via callback */ if (res->pre_write_cb) { data_ptr = res->pre_write_cb(obj_inst->obj_inst_id, res->res_id, res_inst->res_inst_id, - &data_len); + &max_data_len); } if (!data_ptr) { @@ -1428,7 +1429,7 @@ static int lwm2m_engine_set(char *pathstr, void *value, uint16_t len) } /* check length (note: we add 1 to string length for NULL pad) */ - if (len > res_inst->data_len - + if (len > res_inst->max_data_len - (obj_field->data_type == LWM2M_RES_TYPE_STRING ? 1 : 0)) { LOG_ERR("length %u is too long for res instance %d data", len, path.res_id); @@ -1512,6 +1513,8 @@ static int lwm2m_engine_set(char *pathstr, void *value, uint16_t len) } + res_inst->data_len = len; + if (res->post_write_cb) { ret = res->post_write_cb(obj_inst->obj_inst_id, res->res_id, res_inst->res_inst_id, @@ -1951,6 +1954,7 @@ int lwm2m_engine_delete_res_inst(char *pathstr) } res_inst->data_ptr = NULL; + res_inst->max_data_len = 0U; res_inst->data_len = 0U; res_inst->res_inst_id = RES_INSTANCE_NOT_CREATED; @@ -2273,7 +2277,7 @@ static int lwm2m_write_handler_opaque(struct lwm2m_engine_obj_inst *obj_inst, in->block_ctx->opaque = opaque_ctx; } - return ret; + return opaque_ctx.len; } /* This function is exposed for the content format writers */ @@ -2302,7 +2306,7 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst, /* setup initial data elements */ data_ptr = res_inst->data_ptr; - data_len = res_inst->data_len; + data_len = res_inst->max_data_len; /* allow user to override data elements via callback */ if (res->pre_write_cb) { @@ -2334,6 +2338,7 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst, return ret; } + len = ret; break; case LWM2M_RES_TYPE_STRING: @@ -2421,6 +2426,8 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst, return -ENOENT; } + res_inst->data_len = len; + if (res->post_write_cb && obj_field->data_type != LWM2M_RES_TYPE_OPAQUE) { ret = res->post_write_cb(obj_inst->obj_inst_id, diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_firmware_pull.c b/subsys/net/lib/lwm2m/lwm2m_obj_firmware_pull.c index 156ca4dee22..dae27012255 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_firmware_pull.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_firmware_pull.c @@ -314,7 +314,7 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response, /* get buffer data */ write_buf = res->res_instances->data_ptr; - write_buflen = res->res_instances->data_len; + write_buflen = res->res_instances->max_data_len; /* check for user override to buffer */ if (res->pre_write_cb) { diff --git a/subsys/net/lib/lwm2m/lwm2m_object.h b/subsys/net/lib/lwm2m/lwm2m_object.h index ef5955ab965..63206fe0026 100644 --- a/subsys/net/lib/lwm2m/lwm2m_object.h +++ b/subsys/net/lib/lwm2m/lwm2m_object.h @@ -214,6 +214,8 @@ struct lwm2m_engine_obj { for (int _i = 0; _i < _ri_count; _i++) { \ _ri_ptr[_ri_idx + _i].data_ptr = \ (_data_ptr + _i); \ + _ri_ptr[_ri_idx + _i].max_data_len = \ + _data_len; \ _ri_ptr[_ri_idx + _i].data_len = \ _data_len; \ if (_ri_create) { \ @@ -233,6 +235,7 @@ struct lwm2m_engine_obj { if (_ri_count > 0) { \ for (int _i = 0; _i < _ri_count; _i++) { \ _ri_ptr[_ri_idx + _i].data_ptr = NULL; \ + _ri_ptr[_ri_idx + _i].max_data_len = 0; \ _ri_ptr[_ri_idx + _i].data_len = 0; \ if (_ri_create) { \ _ri_ptr[_ri_idx + _i].res_inst_id = \ @@ -323,6 +326,7 @@ struct lwm2m_attr { struct lwm2m_engine_res_inst { void *data_ptr; + uint16_t max_data_len; uint16_t data_len; uint16_t res_inst_id; /* 65535 == not "created" */ uint8_t data_flags;