net: lwm2m: Allow CoAP block size to be changed
Allow changing the CoAP Block-wise transfers block-size for subsequent GET requests. It looks like Leshan switches block size back to its configured value, if it is smaller. So even when we send block N=0 with size of 512, Leshan seem to handle that properly but still asks N=2 with block size 256(if that is configured). Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
This commit is contained in:
parent
71437f71df
commit
51d80a9838
3 changed files with 45 additions and 33 deletions
|
@ -27,7 +27,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <zephyr/net/net_ip.h>
|
||||
|
||||
#include <zephyr/sys/math_extras.h>
|
||||
#include <zephyr/sys/slist.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -696,6 +696,27 @@ static inline uint16_t coap_block_size_to_bytes(
|
|||
return (1 << (block_size + 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper for converting block size in bytes to enumeration.
|
||||
*
|
||||
* NOTE: Only valid CoAP block sizes map correctly.
|
||||
*
|
||||
* @param bytes CoAP block size in bytes.
|
||||
* @return enum coap_block_size
|
||||
*/
|
||||
static inline enum coap_block_size coap_bytes_to_block_size(uint16_t bytes)
|
||||
{
|
||||
int sz = u32_count_trailing_zeros(bytes) - 4;
|
||||
|
||||
if (sz < COAP_BLOCK_16) {
|
||||
return COAP_BLOCK_16;
|
||||
}
|
||||
if (sz > COAP_BLOCK_1024) {
|
||||
return COAP_BLOCK_1024;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Represents the current state of a block-wise transaction.
|
||||
*/
|
||||
|
|
|
@ -103,7 +103,8 @@ sys_slist_t *lwm2m_engine_obj_inst_list(void);
|
|||
|
||||
static int handle_request(struct coap_packet *request, struct lwm2m_message *msg);
|
||||
#if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER)
|
||||
STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_num);
|
||||
STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_num,
|
||||
enum coap_block_size block_size);
|
||||
struct coap_block_context *lwm2m_output_block_context(void);
|
||||
#endif
|
||||
|
||||
|
@ -111,24 +112,7 @@ struct coap_block_context *lwm2m_output_block_context(void);
|
|||
|
||||
enum coap_block_size lwm2m_default_block_size(void)
|
||||
{
|
||||
switch (CONFIG_LWM2M_COAP_BLOCK_SIZE) {
|
||||
case 16:
|
||||
return COAP_BLOCK_16;
|
||||
case 32:
|
||||
return COAP_BLOCK_32;
|
||||
case 64:
|
||||
return COAP_BLOCK_64;
|
||||
case 128:
|
||||
return COAP_BLOCK_128;
|
||||
case 256:
|
||||
return COAP_BLOCK_256;
|
||||
case 512:
|
||||
return COAP_BLOCK_512;
|
||||
case 1024:
|
||||
return COAP_BLOCK_1024;
|
||||
}
|
||||
|
||||
return COAP_BLOCK_256;
|
||||
return coap_bytes_to_block_size(CONFIG_LWM2M_COAP_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void lwm2m_clear_block_contexts(void)
|
||||
|
@ -277,11 +261,12 @@ static inline void release_body_encode_buffer(uint8_t **buffer)
|
|||
}
|
||||
}
|
||||
|
||||
STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_num)
|
||||
STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_num,
|
||||
enum coap_block_size block_size)
|
||||
{
|
||||
int ret;
|
||||
uint16_t payload_size;
|
||||
const uint16_t block_size_bytes = coap_block_size_to_bytes(lwm2m_default_block_size());
|
||||
const uint16_t block_size_bytes = coap_block_size_to_bytes(block_size);
|
||||
uint16_t complete_payload_len;
|
||||
const uint8_t *complete_payload =
|
||||
coap_packet_get_payload(&msg->body_encode_buffer, &complete_payload_len);
|
||||
|
@ -350,7 +335,7 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu
|
|||
LOG_ERR("coap packet init error: no output block context available");
|
||||
return ret;
|
||||
}
|
||||
ret = coap_block_transfer_init(msg->out.block_ctx, lwm2m_default_block_size(),
|
||||
ret = coap_block_transfer_init(msg->out.block_ctx, block_size,
|
||||
complete_payload_len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@ -362,6 +347,7 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu
|
|||
} else {
|
||||
/* update block context */
|
||||
msg->out.block_ctx->current = block_num * block_size_bytes;
|
||||
msg->out.block_ctx->block_size = block_size;
|
||||
}
|
||||
|
||||
ret = coap_append_descriptive_block_option(&msg->cpkt, msg->out.block_ctx);
|
||||
|
@ -427,7 +413,7 @@ STATIC int prepare_msg_for_send(struct lwm2m_message *msg)
|
|||
(const uint8_t *)&hash, sizeof(hash));
|
||||
}
|
||||
|
||||
ret = build_msg_block_for_send(msg, 0);
|
||||
ret = build_msg_block_for_send(msg, 0, lwm2m_default_block_size());
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -2649,6 +2635,7 @@ static void handle_ongoing_block2_tx(struct lwm2m_message *msg, struct coap_pack
|
|||
#if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER)
|
||||
int r;
|
||||
uint8_t block;
|
||||
enum coap_block_size block_size;
|
||||
|
||||
r = coap_get_block2_option(cpkt, &block);
|
||||
if (r < 0) {
|
||||
|
@ -2656,9 +2643,10 @@ static void handle_ongoing_block2_tx(struct lwm2m_message *msg, struct coap_pack
|
|||
return;
|
||||
}
|
||||
|
||||
block_size = coap_bytes_to_block_size(r);
|
||||
msg->in.in_cpkt = cpkt;
|
||||
|
||||
r = build_msg_block_for_send(msg, block);
|
||||
r = build_msg_block_for_send(msg, block, block_size);
|
||||
if (r < 0) {
|
||||
clear_ongoing_block2_tx();
|
||||
LOG_ERR("Unable to build next block of lwm2m message! r=%d", r);
|
||||
|
@ -2745,6 +2733,8 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_
|
|||
return;
|
||||
}
|
||||
|
||||
enum coap_block_size block_size = coap_bytes_to_block_size(r);
|
||||
|
||||
if (r != CONFIG_LWM2M_COAP_BLOCK_SIZE) {
|
||||
LOG_WRN("Server requests different block size: ignore");
|
||||
}
|
||||
|
@ -2756,7 +2746,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_
|
|||
}
|
||||
|
||||
last_block_num = msg->out.block_ctx->current /
|
||||
coap_block_size_to_bytes(msg->out.block_ctx->block_size);
|
||||
coap_block_size_to_bytes(block_size);
|
||||
if (last_block_num > block_num) {
|
||||
LOG_INF("Block already sent: ignore");
|
||||
return;
|
||||
|
@ -2765,7 +2755,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_
|
|||
return;
|
||||
}
|
||||
|
||||
r = build_msg_block_for_send(msg, block_num + 1);
|
||||
r = build_msg_block_for_send(msg, block_num + 1, block_size);
|
||||
if (r < 0) {
|
||||
lwm2m_reset_message(msg, true);
|
||||
LOG_ERR("Unable to build next block of lwm2m message!");
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
/* Declaration of 'private' function */
|
||||
int prepare_msg_for_send(struct lwm2m_message *msg);
|
||||
int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_num);
|
||||
int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_num,
|
||||
enum coap_block_size block_size);
|
||||
int request_output_block_ctx(struct coap_block_context **ctx);
|
||||
void release_output_block_ctx(struct coap_block_context ** const ctx);
|
||||
|
||||
|
@ -270,7 +271,7 @@ ZTEST_F(net_block_transfer, test_build_blocks_for_send_exactly_2_blocks)
|
|||
"Last byte in payload wrong");
|
||||
|
||||
/* block 1 */
|
||||
ret = build_msg_block_for_send(msg, 1);
|
||||
ret = build_msg_block_for_send(msg, 1, COAP_BLOCK_64);
|
||||
zassert_equal(ret, 0, "Could not create second block");
|
||||
|
||||
ret = coap_get_option_int(&msg->cpkt, COAP_OPTION_BLOCK1);
|
||||
|
@ -285,7 +286,7 @@ ZTEST_F(net_block_transfer, test_build_blocks_for_send_exactly_2_blocks)
|
|||
"Last byte in payload wrong");
|
||||
|
||||
/* block 2 doesn't exist */
|
||||
ret = build_msg_block_for_send(msg, 2);
|
||||
ret = build_msg_block_for_send(msg, 2, COAP_BLOCK_64);
|
||||
zassert_equal(ret, -EINVAL, "Could not create second block");
|
||||
}
|
||||
|
||||
|
@ -346,7 +347,7 @@ ZTEST_F(net_block_transfer, test_build_blocks_for_send_more_than_2_blocks)
|
|||
"Last byte in payload wrong");
|
||||
|
||||
/* block 1 */
|
||||
ret = build_msg_block_for_send(msg, 1);
|
||||
ret = build_msg_block_for_send(msg, 1, COAP_BLOCK_64);
|
||||
zassert_equal(ret, 0, "Could not create second block");
|
||||
|
||||
ret = coap_get_option_int(&msg->cpkt, COAP_OPTION_BLOCK1);
|
||||
|
@ -361,7 +362,7 @@ ZTEST_F(net_block_transfer, test_build_blocks_for_send_more_than_2_blocks)
|
|||
"Last byte in payload wrong");
|
||||
|
||||
/* block 2 */
|
||||
ret = build_msg_block_for_send(msg, 2);
|
||||
ret = build_msg_block_for_send(msg, 2, COAP_BLOCK_64);
|
||||
zassert_equal(ret, 0, "Could not create second block");
|
||||
|
||||
ret = coap_get_option_int(&msg->cpkt, COAP_OPTION_BLOCK1);
|
||||
|
@ -374,7 +375,7 @@ ZTEST_F(net_block_transfer, test_build_blocks_for_send_more_than_2_blocks)
|
|||
zassert_equal(0x80, payload[0], "First (and only) byte in payload wrong");
|
||||
|
||||
/* block 3 doesn't exist */
|
||||
ret = build_msg_block_for_send(msg, 3);
|
||||
ret = build_msg_block_for_send(msg, 3, COAP_BLOCK_64);
|
||||
zassert_equal(ret, -EINVAL, "Could not create second block");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue