Skip to content

Commit

Permalink
coap_block.c: Handle missing Size1 option when using Block1
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdeep1 committed Jan 9, 2025
1 parent ea86105 commit 080da9a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 23 deletions.
3 changes: 2 additions & 1 deletion include/coap3/coap_block_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,15 @@ struct coap_lg_range {
* Structure to keep track of received blocks
*/
typedef struct coap_rblock_t {
uint32_t used;
uint32_t used; /**< Number of range blocks in use */
uint32_t retry;
#if COAP_Q_BLOCK_SUPPORT
uint32_t processing_payload_set;
uint32_t latest_payload_set;
#endif /* COAP_Q_BLOCK_SUPPORT */
struct coap_lg_range range[COAP_RBLOCK_CNT];
coap_tick_t last_seen;
uint32_t total_blocks; /**< Set to block no + 1 when More bit unset */
} coap_rblock_t;

/**
Expand Down
49 changes: 27 additions & 22 deletions src/coap_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -1657,20 +1657,21 @@ check_if_next_block(coap_rblock_t *rec_blocks, uint32_t block_num) {
#endif /* COAP_SERVER_SUPPORT */

static int
check_all_blocks_in(coap_rblock_t *rec_blocks, size_t total_blocks) {
check_all_blocks_in(coap_rblock_t *rec_blocks) {
uint32_t i;
uint32_t block = 0;

if (rec_blocks->total_blocks == 0) {
/* Not seen block with More bit unset yet */
return 0;
}

for (i = 0; i < rec_blocks->used; i++) {
if (block < rec_blocks->range[i].begin)
return 0;
if (block < rec_blocks->range[i].end)
block = rec_blocks->range[i].end;
}
/* total_blocks counts from 1 */
if (block + 1 < total_blocks)
return 0;

return 1;
}

Expand Down Expand Up @@ -2785,9 +2786,14 @@ coap_handle_request_send_block(coap_session_t *session,
#endif /* COAP_SERVER_SUPPORT */

static int
update_received_blocks(coap_rblock_t *rec_blocks, uint32_t block_num) {
update_received_blocks(coap_rblock_t *rec_blocks, uint32_t block_num, uint32_t block_m) {
uint32_t i;

if (rec_blocks->total_blocks && block_num + 1 > rec_blocks->total_blocks) {
/* received block number greater than Block No defined when More bit unset */
return 0;
}

/* Reset as there is activity */
rec_blocks->retry = 0;

Expand Down Expand Up @@ -2834,6 +2840,9 @@ update_received_blocks(coap_rblock_t *rec_blocks, uint32_t block_num) {
rec_blocks->range[i].begin = rec_blocks->range[i].end = block_num;
rec_blocks->used++;
}
if (!block_m)
rec_blocks->total_blocks = block_num + 1;

coap_ticks(&rec_blocks->last_seen);
return 1;
}
Expand Down Expand Up @@ -2872,7 +2881,6 @@ coap_handle_request_put_block(coap_context_t *context,
size_t rtag_length;
const uint8_t *rtag;
uint32_t max_block_szx;
size_t chunk;
int update_data;
unsigned int saved_num;
size_t saved_offset;
Expand Down Expand Up @@ -3065,15 +3073,14 @@ coap_handle_request_put_block(coap_context_t *context,
lg_srcv->last_mid = pdu->mid;
lg_srcv->last_type = pdu->type;

chunk = (size_t)1 << (block.szx + 4);
update_data = 0;
saved_num = block.num;
saved_offset = offset;

while (offset < saved_offset + length) {
if (!check_if_received_block(&lg_srcv->rec_blocks, block.num)) {
/* Update list of blocks received */
if (!update_received_blocks(&lg_srcv->rec_blocks, block.num)) {
if (!update_received_blocks(&lg_srcv->rec_blocks, block.num, block.m)) {
coap_handle_event_lkd(context, COAP_EVENT_PARTIAL_BLOCK, session);
coap_add_data(response, sizeof("Too many missing blocks")-1,
(const uint8_t *)"Too many missing blocks");
Expand Down Expand Up @@ -3107,16 +3114,14 @@ coap_handle_request_put_block(coap_context_t *context,
}

if (block.m ||
!check_all_blocks_in(&lg_srcv->rec_blocks,
(uint32_t)(lg_srcv->total_len + chunk -1)/chunk)) {
!check_all_blocks_in(&lg_srcv->rec_blocks)) {
/* Not all the payloads of the body have arrived */
if (block.m) {
uint8_t buf[4];

#if COAP_Q_BLOCK_SUPPORT
if (block_option == COAP_OPTION_Q_BLOCK1) {
if (check_all_blocks_in(&lg_srcv->rec_blocks,
(uint32_t)(lg_srcv->total_len + chunk -1)/chunk)) {
if (check_all_blocks_in(&lg_srcv->rec_blocks)) {
goto give_app_data;
}
if (lg_srcv->rec_blocks.used == 1 &&
Expand Down Expand Up @@ -3148,8 +3153,7 @@ coap_handle_request_put_block(coap_context_t *context,
* complete payload to application and acknowledge this current
* block.
*/
if (!check_all_blocks_in(&lg_srcv->rec_blocks,
(uint32_t)(lg_srcv->total_len + chunk -1)/chunk)) {
if ((total == 0 && block.m) || !check_all_blocks_in(&lg_srcv->rec_blocks)) {
/* Ask for the next block */
coap_insert_option(response, block_option,
coap_encode_var_safe(buf, sizeof(buf),
Expand All @@ -3169,8 +3173,10 @@ coap_handle_request_put_block(coap_context_t *context,
tmp_pdu->code = COAP_RESPONSE_CODE(231);
coap_send_internal(session, tmp_pdu);
}
coap_update_token(response, lg_srcv->last_token->length, lg_srcv->last_token->s);
coap_update_token(pdu, lg_srcv->last_token->length, lg_srcv->last_token->s);
if (lg_srcv->last_token) {
coap_update_token(response, lg_srcv->last_token->length, lg_srcv->last_token->s);
coap_update_token(pdu, lg_srcv->last_token->length, lg_srcv->last_token->s);
}
/* Pass the assembled pdu and body to the application */
goto give_app_data;
}
Expand Down Expand Up @@ -3869,6 +3875,7 @@ coap_handle_response_get_block(coap_context_t *context,
lg_crcv->block_option = block_opt;
lg_crcv->last_type = rcvd->type;
lg_crcv->rec_blocks.used = 0;
lg_crcv->rec_blocks.total_blocks = 0;
#if COAP_Q_BLOCK_SUPPORT
lg_crcv->rec_blocks.processing_payload_set = 0;
#endif /* COAP_Q_BLOCK_SUPPORT */
Expand Down Expand Up @@ -3963,7 +3970,7 @@ coap_handle_response_get_block(coap_context_t *context,
lg_crcv->rec_blocks.latest_payload_set = this_payload_set;
#endif /* COAP_Q_BLOCK_SUPPORT */
/* Update list of blocks received */
if (!update_received_blocks(&lg_crcv->rec_blocks, block.num)) {
if (!update_received_blocks(&lg_crcv->rec_blocks, block.num, block.m)) {
coap_handle_event_lkd(context, COAP_EVENT_PARTIAL_BLOCK, session);
goto fail_resp;
}
Expand All @@ -3987,8 +3994,7 @@ coap_handle_response_get_block(coap_context_t *context,
goto fail_resp;
}
}
if (block.m || !check_all_blocks_in(&lg_crcv->rec_blocks,
(size2 + chunk -1) / chunk)) {
if (block.m || !check_all_blocks_in(&lg_crcv->rec_blocks)) {
/* Not all the payloads of the body have arrived */
size_t len;
coap_pdu_t *pdu;
Expand All @@ -3998,8 +4004,7 @@ coap_handle_response_get_block(coap_context_t *context,
#if COAP_Q_BLOCK_SUPPORT
if (block_opt == COAP_OPTION_Q_BLOCK2) {
/* Blocks could arrive in wrong order */
if (check_all_blocks_in(&lg_crcv->rec_blocks,
(size2 + chunk -1) / chunk)) {
if (check_all_blocks_in(&lg_crcv->rec_blocks)) {
goto give_to_app;
}
if (check_all_blocks_in_for_payload_set(session,
Expand Down

0 comments on commit 080da9a

Please sign in to comment.