Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c
- index bbf68d1..bf65c5e 100644
- --- a/subsys/net/lib/lwm2m/lwm2m_engine.c
- +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c
- @@ -110,7 +110,9 @@ static sys_slist_t engine_observer_list;
- /* TODO: figure out what's correct value */
- #define TIMEOUT_BLOCKWISE_TRANSFER K_SECONDS(30)
- -#define GET_BLOCK_NUM(v) ((v) >> 4)
- +#define GET_BLOCK_NUM(v) ((v) >> 4)
- +#define GET_BLOCK_SIZE(v) (((v) & 0x7))
- +#define GET_MORE(v) (!!((v) & 0x08))
- struct block_context {
- struct zoap_block_context ctx;
- @@ -548,6 +550,20 @@ int lwm2m_delete_obj_inst(u16_t obj_id, u16_t obj_inst_id)
- /* utility functions */
- +static int get_option_int(const struct zoap_packet *zpkt, u8_t opt)
- +{
- + struct zoap_option option = {};
- + u16_t count = 1;
- + int r;
- +
- + r = zoap_find_options(zpkt, opt, &option, count);
- + if (r <= 0) {
- + return -ENOENT;
- + }
- +
- + return zoap_option_value_to_int(&option);
- +}
- +
- static void engine_clear_context(struct lwm2m_engine_context *context)
- {
- if (context->in) {
- @@ -1625,11 +1641,12 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
- void *data_ptr = NULL;
- size_t data_len = 0;
- size_t len = 0;
- + size_t total_size = 0;
- int ret = 0;
- - struct block_context *block_ctx = NULL;
- u8_t tkl = 0;
- const u8_t *token;
- bool last_block = true;
- + struct block_context *block_ctx = NULL;
- if (!obj_inst || !res || !obj_field || !context) {
- return -EINVAL;
- @@ -1639,6 +1656,13 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
- data_ptr = res->data_ptr;
- data_len = res->data_len;
- + /* setup data_ptr/data_len for OPAQUE when it has none setup */
- + if (obj_field->data_type == LWM2M_RES_TYPE_OPAQUE &&
- + data_ptr == NULL && data_len == 0) {
- + data_ptr = in->inbuf;
- + data_len = in->insize;
- + }
- +
- /* allow user to override data elements via callback */
- if (res->pre_write_cb) {
- data_ptr = res->pre_write_cb(obj_inst->obj_inst_id, &data_len);
- @@ -1731,14 +1755,22 @@ int lwm2m_write_handler(struct lwm2m_engine_obj_inst *obj_inst,
- }
- if (res->post_write_cb) {
- - token = zoap_header_get_token(in->in_zpkt, &tkl);
- - if (token != NULL && !get_block_ctx(token, tkl, &block_ctx)) {
- - last_block = block_ctx->ctx.current == 0;
- + /* Get block1 option for checking MORE block flag */
- + ret = get_option_int(in->in_zpkt, ZOAP_OPTION_BLOCK1);
- + if (ret >= 0) {
- + last_block = !GET_MORE(ret);
- +
- + /* Get block_ctx for total_size (might be zero) */
- + token = zoap_header_get_token(in->in_zpkt, &tkl);
- + if (token != NULL &&
- + !get_block_ctx(token, tkl, &block_ctx)) {
- + total_size = block_ctx->ctx.total_size;
- + }
- }
- /* ignore return value here */
- ret = res->post_write_cb(obj_inst->obj_inst_id, data_ptr, len,
- - last_block, 0);
- + last_block, total_size);
- if (ret >= 0) {
- ret = 0;
- }
- @@ -2054,20 +2086,6 @@ static int do_write_op(struct lwm2m_engine_obj *obj,
- }
- }
- -static int get_option_int(const struct zoap_packet *zpkt, u8_t opt)
- -{
- - struct zoap_option option = {};
- - u16_t count = 1;
- - int r;
- -
- - r = zoap_find_options(zpkt, opt, &option, count);
- - if (r <= 0) {
- - return -ENOENT;
- - }
- -
- - return zoap_option_value_to_int(&option);
- -}
- -
- static int handle_request(struct zoap_packet *request,
- struct zoap_packet *response,
- struct sockaddr *from_addr)
- @@ -2086,6 +2104,8 @@ static int handle_request(struct zoap_packet *request,
- int observe = -1; /* default to -1, 0 = ENABLE, 1 = DISABLE */
- bool discover = false;
- struct block_context *block_ctx = NULL;
- + size_t block_offset = 0;
- + enum zoap_block_size block_size;
- /* setup engine context */
- memset(&context, 0, sizeof(struct lwm2m_engine_context));
- @@ -2201,6 +2221,15 @@ static int handle_request(struct zoap_packet *request,
- /* Check for block transfer */
- r = get_option_int(in.in_zpkt, ZOAP_OPTION_BLOCK1);
- if (r > 0) {
- + /* RFC7252: 4.6. Message Size */
- + block_size = GET_BLOCK_SIZE(r);
- + if (GET_MORE(r) &&
- + zoap_block_size_to_bytes(block_size) > in.insize) {
- + SYS_LOG_DBG("Trailing payload is discarded!");
- + r = -EFBIG;
- + goto error;
- + }
- +
- if (GET_BLOCK_NUM(r) == 0) {
- r = init_block_ctx(token, tkl, &block_ctx);
- } else {
- @@ -2211,7 +2240,8 @@ static int handle_request(struct zoap_packet *request,
- goto error;
- }
- - zoap_next_block(in.in_zpkt, &block_ctx->ctx);
- + /* 0 will be returned if it's the last block */
- + block_offset = zoap_next_block(in.in_zpkt, &block_ctx->ctx);
- }
- switch (context.operation) {
- @@ -2289,7 +2319,7 @@ static int handle_request(struct zoap_packet *request,
- /* Handle blockwise 1 */
- if (block_ctx) {
- - if (block_ctx->ctx.current > 0) {
- + if (block_offset > 0) {
- /* More to come, ack with correspond block # */
- r = zoap_add_block1_option(
- out.out_zpkt, &block_ctx->ctx);
- @@ -2327,6 +2357,9 @@ error:
- } else if (r == -EEXIST) {
- zoap_header_set_code(out.out_zpkt,
- ZOAP_RESPONSE_CODE_BAD_REQUEST);
- + } else if (r == -EFBIG) {
- + zoap_header_set_code(out.out_zpkt,
- + ZOAP_RESPONSE_CODE_REQUEST_TOO_LARGE);
- } else {
- /* Failed to handle the request */
- zoap_header_set_code(out.out_zpkt,
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement