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 <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <zephyr/net/net_ip.h>
|
#include <zephyr/net/net_ip.h>
|
||||||
|
#include <zephyr/sys/math_extras.h>
|
||||||
#include <zephyr/sys/slist.h>
|
#include <zephyr/sys/slist.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -696,6 +696,27 @@ static inline uint16_t coap_block_size_to_bytes(
|
||||||
return (1 << (block_size + 4));
|
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.
|
* @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);
|
static int handle_request(struct coap_packet *request, struct lwm2m_message *msg);
|
||||||
#if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER)
|
#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);
|
struct coap_block_context *lwm2m_output_block_context(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -111,24 +112,7 @@ struct coap_block_context *lwm2m_output_block_context(void);
|
||||||
|
|
||||||
enum coap_block_size lwm2m_default_block_size(void)
|
enum coap_block_size lwm2m_default_block_size(void)
|
||||||
{
|
{
|
||||||
switch (CONFIG_LWM2M_COAP_BLOCK_SIZE) {
|
return coap_bytes_to_block_size(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lwm2m_clear_block_contexts(void)
|
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;
|
int ret;
|
||||||
uint16_t payload_size;
|
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;
|
uint16_t complete_payload_len;
|
||||||
const uint8_t *complete_payload =
|
const uint8_t *complete_payload =
|
||||||
coap_packet_get_payload(&msg->body_encode_buffer, &complete_payload_len);
|
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");
|
LOG_ERR("coap packet init error: no output block context available");
|
||||||
return ret;
|
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);
|
complete_payload_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -362,6 +347,7 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu
|
||||||
} else {
|
} else {
|
||||||
/* update block context */
|
/* update block context */
|
||||||
msg->out.block_ctx->current = block_num * block_size_bytes;
|
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);
|
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));
|
(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) {
|
if (ret != 0) {
|
||||||
return ret;
|
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)
|
#if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER)
|
||||||
int r;
|
int r;
|
||||||
uint8_t block;
|
uint8_t block;
|
||||||
|
enum coap_block_size block_size;
|
||||||
|
|
||||||
r = coap_get_block2_option(cpkt, &block);
|
r = coap_get_block2_option(cpkt, &block);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
@ -2656,9 +2643,10 @@ static void handle_ongoing_block2_tx(struct lwm2m_message *msg, struct coap_pack
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block_size = coap_bytes_to_block_size(r);
|
||||||
msg->in.in_cpkt = cpkt;
|
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) {
|
if (r < 0) {
|
||||||
clear_ongoing_block2_tx();
|
clear_ongoing_block2_tx();
|
||||||
LOG_ERR("Unable to build next block of lwm2m message! r=%d", r);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum coap_block_size block_size = coap_bytes_to_block_size(r);
|
||||||
|
|
||||||
if (r != CONFIG_LWM2M_COAP_BLOCK_SIZE) {
|
if (r != CONFIG_LWM2M_COAP_BLOCK_SIZE) {
|
||||||
LOG_WRN("Server requests different block size: ignore");
|
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 /
|
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) {
|
if (last_block_num > block_num) {
|
||||||
LOG_INF("Block already sent: ignore");
|
LOG_INF("Block already sent: ignore");
|
||||||
return;
|
return;
|
||||||
|
@ -2765,7 +2755,7 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_
|
||||||
return;
|
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) {
|
if (r < 0) {
|
||||||
lwm2m_reset_message(msg, true);
|
lwm2m_reset_message(msg, true);
|
||||||
LOG_ERR("Unable to build next block of lwm2m message!");
|
LOG_ERR("Unable to build next block of lwm2m message!");
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
|
|
||||||
/* Declaration of 'private' function */
|
/* Declaration of 'private' function */
|
||||||
int prepare_msg_for_send(struct lwm2m_message *msg);
|
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);
|
int request_output_block_ctx(struct coap_block_context **ctx);
|
||||||
void release_output_block_ctx(struct coap_block_context ** const 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");
|
"Last byte in payload wrong");
|
||||||
|
|
||||||
/* block 1 */
|
/* 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");
|
zassert_equal(ret, 0, "Could not create second block");
|
||||||
|
|
||||||
ret = coap_get_option_int(&msg->cpkt, COAP_OPTION_BLOCK1);
|
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");
|
"Last byte in payload wrong");
|
||||||
|
|
||||||
/* block 2 doesn't exist */
|
/* 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");
|
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");
|
"Last byte in payload wrong");
|
||||||
|
|
||||||
/* block 1 */
|
/* 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");
|
zassert_equal(ret, 0, "Could not create second block");
|
||||||
|
|
||||||
ret = coap_get_option_int(&msg->cpkt, COAP_OPTION_BLOCK1);
|
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");
|
"Last byte in payload wrong");
|
||||||
|
|
||||||
/* block 2 */
|
/* 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");
|
zassert_equal(ret, 0, "Could not create second block");
|
||||||
|
|
||||||
ret = coap_get_option_int(&msg->cpkt, COAP_OPTION_BLOCK1);
|
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");
|
zassert_equal(0x80, payload[0], "First (and only) byte in payload wrong");
|
||||||
|
|
||||||
/* block 3 doesn't exist */
|
/* 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");
|
zassert_equal(ret, -EINVAL, "Could not create second block");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue