From 33c54ee6fd63189be96e237cd85b99aedf0e0770 Mon Sep 17 00:00:00 2001 From: Robert Chou Date: Thu, 13 Jul 2017 20:50:40 +0800 Subject: [PATCH] net: zoap: advance block context by checking M bit from block option According to RFC7959 page 30, "The end of a block-wise transfer is governed by the M bits in the Block options, _not_ by exhausting the size estimates exchanges." Therefore, we should check the M bit instead of total size (which is not always available, too) Signed-off-by: Robert Chou --- include/net/zoap.h | 4 +++- samples/net/zoap_server/src/zoap-server.c | 2 +- subsys/net/lib/zoap/zoap.c | 12 ++++++++++-- tests/net/lib/zoap/src/main.c | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/include/net/zoap.h b/include/net/zoap.h index b655fd0866f..19357daa577 100644 --- a/include/net/zoap.h +++ b/include/net/zoap.h @@ -687,12 +687,14 @@ int zoap_update_from_block(const struct zoap_packet *zpkt, * indicates the correct offset in the body of data being * transferred. * + * @param zpkt Packet in which to look for block-wise transfers options * @param ctx Block context to be updated * * @return The offset in the block-wise transfer, 0 if the transfer * has finished. */ -size_t zoap_next_block(struct zoap_block_context *ctx); +size_t zoap_next_block(const struct zoap_packet *zpkt, + struct zoap_block_context *ctx); /** * @brief Returns the version present in a CoAP packet. diff --git a/samples/net/zoap_server/src/zoap-server.c b/samples/net/zoap_server/src/zoap-server.c index 73a61216323..caf8e588c98 100644 --- a/samples/net/zoap_server/src/zoap-server.c +++ b/samples/net/zoap_server/src/zoap-server.c @@ -656,7 +656,7 @@ static int large_get(struct zoap_resource *resource, return -EINVAL; } - r = zoap_next_block(&ctx); + r = zoap_next_block(&response, &ctx); if (!r) { /* Will return 0 when it's the last block. */ memset(&ctx, 0, sizeof(ctx)); diff --git a/subsys/net/lib/zoap/zoap.c b/subsys/net/lib/zoap/zoap.c index 4fd05f66eec..f86fadf19f9 100644 --- a/subsys/net/lib/zoap/zoap.c +++ b/subsys/net/lib/zoap/zoap.c @@ -1270,9 +1270,17 @@ int zoap_update_from_block(const struct zoap_packet *zpkt, return update_descriptive_block(ctx, block2, size2); } -size_t zoap_next_block(struct zoap_block_context *ctx) +size_t zoap_next_block(const struct zoap_packet *zpkt, + struct zoap_block_context *ctx) { - if (ctx->current >= ctx->total_size) { + int block; + if (is_request(zpkt)) { + block = get_block_option(zpkt, ZOAP_OPTION_BLOCK1); + } else { + block = get_block_option(zpkt, ZOAP_OPTION_BLOCK2); + } + + if (!GET_MORE(block)) { return 0; } diff --git a/tests/net/lib/zoap/src/main.c b/tests/net/lib/zoap/src/main.c index 479433faf15..ad0b36cbb29 100644 --- a/tests/net/lib/zoap/src/main.c +++ b/tests/net/lib/zoap/src/main.c @@ -997,7 +997,7 @@ static int test_block_size(void) net_pkt_unref(pkt); /* Let's try the second packet */ - zoap_next_block(&req_ctx); + zoap_next_block(&req, &req_ctx); pkt = net_pkt_get_reserve(&zoap_pkt_slab, 0, K_NO_WAIT); if (!pkt) {