@@ -56,8 +56,9 @@ static void sn_coap_protocol_linked_list_duplication_info_remov
56
56
#endif
57
57
#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
58
58
static void sn_coap_protocol_linked_list_blockwise_msg_remove (struct coap_s * handle , coap_blockwise_msg_s * removed_msg_ptr );
59
- static void sn_coap_protocol_linked_list_blockwise_payload_store (struct coap_s * handle , sn_nsdl_addr_s * addr_ptr , uint16_t stored_payload_len , uint8_t * stored_payload_ptr );
59
+ static void sn_coap_protocol_linked_list_blockwise_payload_store (struct coap_s * handle , sn_nsdl_addr_s * addr_ptr , uint16_t stored_payload_len , uint8_t * stored_payload_ptr , uint32_t block_number );
60
60
static uint8_t * sn_coap_protocol_linked_list_blockwise_payload_search (struct coap_s * handle , sn_nsdl_addr_s * src_addr_ptr , uint16_t * payload_length );
61
+ static bool sn_coap_protocol_linked_list_blockwise_payload_compare_block_number (struct coap_s * handle , sn_nsdl_addr_s * src_addr_ptr , uint32_t block_number );
61
62
static void sn_coap_protocol_linked_list_blockwise_payload_remove (struct coap_s * handle , coap_blockwise_payload_s * removed_payload_ptr );
62
63
static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest (struct coap_s * handle );
63
64
static uint32_t sn_coap_protocol_linked_list_blockwise_payloads_get_len (struct coap_s * handle , sn_nsdl_addr_s * src_addr_ptr );
@@ -653,9 +654,11 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src
653
654
returned_dst_coap_msg_ptr -> msg_id );
654
655
/* Send ACK response */
655
656
if (response ) {
656
- response -> coap -> sn_coap_tx_callback (response -> packet_ptr ,
657
- response -> packet_len , response -> address , response -> param );
658
-
657
+ /* Check that response has been created */
658
+ if (response -> packet_ptr ) {
659
+ response -> coap -> sn_coap_tx_callback (response -> packet_ptr ,
660
+ response -> packet_len , response -> address , response -> param );
661
+ }
659
662
}
660
663
661
664
return returned_dst_coap_msg_ptr ;
@@ -795,7 +798,6 @@ int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time)
795
798
796
799
if (tmp_coap_hdr_ptr != 0 ) {
797
800
tmp_coap_hdr_ptr -> coap_status = COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED ;
798
-
799
801
stored_msg_ptr -> coap -> sn_coap_rx_callback (tmp_coap_hdr_ptr , stored_msg_ptr -> send_msg_ptr -> dst_addr_ptr , stored_msg_ptr -> param );
800
802
801
803
sn_coap_parser_release_allocated_coap_msg_mem (stored_msg_ptr -> coap , tmp_coap_hdr_ptr );
@@ -1210,7 +1212,8 @@ static void sn_coap_protocol_linked_list_blockwise_msg_remove(struct coap_s *han
1210
1212
1211
1213
static void sn_coap_protocol_linked_list_blockwise_payload_store (struct coap_s * handle , sn_nsdl_addr_s * addr_ptr ,
1212
1214
uint16_t stored_payload_len ,
1213
- uint8_t * stored_payload_ptr )
1215
+ uint8_t * stored_payload_ptr ,
1216
+ uint32_t block_number )
1214
1217
{
1215
1218
if (!addr_ptr || !stored_payload_len || !stored_payload_ptr ) {
1216
1219
return ;
@@ -1227,6 +1230,7 @@ static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s *
1227
1230
return ;
1228
1231
}
1229
1232
1233
+
1230
1234
/* Allocate memory for stored Payload's data */
1231
1235
stored_blockwise_payload_ptr -> payload_ptr = handle -> sn_coap_protocol_malloc (stored_payload_len );
1232
1236
@@ -1259,6 +1263,8 @@ static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s *
1259
1263
1260
1264
stored_blockwise_payload_ptr -> coap = handle ;
1261
1265
1266
+ stored_blockwise_payload_ptr -> block_number = block_number ;
1267
+
1262
1268
/* * * * Storing Payload to Linked list * * * */
1263
1269
1264
1270
ns_list_add_to_end (& handle -> linked_list_blockwise_received_payloads , stored_blockwise_payload_ptr );
@@ -1295,6 +1301,27 @@ static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(struct coa
1295
1301
return NULL ;
1296
1302
}
1297
1303
1304
+ static bool sn_coap_protocol_linked_list_blockwise_payload_compare_block_number (struct coap_s * handle ,
1305
+ sn_nsdl_addr_s * src_addr_ptr ,
1306
+ uint32_t block_number )
1307
+ {
1308
+ /* Loop all stored blockwise payloads in Linked list */
1309
+ ns_list_foreach (coap_blockwise_payload_s , stored_payload_info_ptr , & handle -> linked_list_blockwise_received_payloads ) {
1310
+ /* If payload's Source address is same than is searched */
1311
+ if (0 == memcmp (src_addr_ptr -> addr_ptr , stored_payload_info_ptr -> addr_ptr , src_addr_ptr -> addr_len )) {
1312
+ /* If payload's Source address port is same than is searched */
1313
+ if (stored_payload_info_ptr -> port == src_addr_ptr -> port ) {
1314
+ // Check that incoming block number matches to last received one
1315
+ if (block_number - 1 == stored_payload_info_ptr -> block_number ) {
1316
+ tr_debug ("sn_coap_protocol_linked_list_blockwise_payload_search_block_number - found %d" , stored_payload_info_ptr -> block_number );
1317
+ return true;
1318
+ }
1319
+ }
1320
+ }
1321
+ }
1322
+ return false;
1323
+ }
1324
+
1298
1325
/**************************************************************************/ /**
1299
1326
* \fn static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(struct coap_s *handle)
1300
1327
*
@@ -1326,7 +1353,6 @@ static void sn_coap_protocol_linked_list_blockwise_payload_remove(struct coap_s
1326
1353
coap_blockwise_payload_s * removed_payload_ptr )
1327
1354
{
1328
1355
ns_list_remove (& handle -> linked_list_blockwise_received_payloads , removed_payload_ptr );
1329
-
1330
1356
/* Free memory of stored payload */
1331
1357
if (removed_payload_ptr -> addr_ptr != NULL ) {
1332
1358
handle -> sn_coap_protocol_free (removed_payload_ptr -> addr_ptr );
@@ -1658,7 +1684,22 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn
1658
1684
received_coap_msg_ptr -> payload_len = handle -> sn_coap_block_data_size ;
1659
1685
}
1660
1686
1661
- sn_coap_protocol_linked_list_blockwise_payload_store (handle , src_addr_ptr , received_coap_msg_ptr -> payload_len , received_coap_msg_ptr -> payload_ptr );
1687
+ // Check that incoming block number is in order.
1688
+ uint32_t block_number = received_coap_msg_ptr -> options_list_ptr -> block1 >> 4 ;
1689
+ bool blocks_in_order = true;
1690
+ if (block_number > 0 &&
1691
+ !sn_coap_protocol_linked_list_blockwise_payload_compare_block_number (handle ,
1692
+ src_addr_ptr ,
1693
+ block_number )) {
1694
+ blocks_in_order = false;
1695
+ }
1696
+
1697
+ sn_coap_protocol_linked_list_blockwise_payload_store (handle ,
1698
+ src_addr_ptr ,
1699
+ received_coap_msg_ptr -> payload_len ,
1700
+ received_coap_msg_ptr -> payload_ptr ,
1701
+ block_number );
1702
+
1662
1703
/* If not last block (more value is set) */
1663
1704
/* Block option length can be 1-3 bytes. First 4-20 bits are for block number. Last 4 bits are ALWAYS more bit + block size. */
1664
1705
if (received_coap_msg_ptr -> options_list_ptr -> block1 & 0x08 ) {
@@ -1678,12 +1719,14 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn
1678
1719
1679
1720
// Response with COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE if the payload size is more than we can handle
1680
1721
tr_debug ("sn_coap_handle_blockwise_message - block1 received - incoming size: [%d]" , received_coap_msg_ptr -> options_list_ptr -> size1 );
1722
+
1681
1723
uint32_t max_size = SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE ;
1682
- if (received_coap_msg_ptr -> options_list_ptr -> size1 > max_size ) {
1724
+ if (!blocks_in_order ) {
1725
+ src_coap_blockwise_ack_msg_ptr -> msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE ;
1726
+ } else if (received_coap_msg_ptr -> options_list_ptr -> size1 > max_size ) {
1683
1727
// Include maximum size that stack can handle into response
1684
1728
src_coap_blockwise_ack_msg_ptr -> msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE ;
1685
1729
src_coap_blockwise_ack_msg_ptr -> options_list_ptr -> size1 = max_size ;
1686
-
1687
1730
} else if (received_coap_msg_ptr -> msg_code == COAP_MSG_CODE_REQUEST_GET ) {
1688
1731
src_coap_blockwise_ack_msg_ptr -> msg_code = COAP_MSG_CODE_RESPONSE_CONTENT ;
1689
1732
} else if (received_coap_msg_ptr -> msg_code == COAP_MSG_CODE_REQUEST_POST ) {
@@ -1706,6 +1749,13 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn
1706
1749
1707
1750
src_coap_blockwise_ack_msg_ptr -> msg_id = received_coap_msg_ptr -> msg_id ;
1708
1751
1752
+ // Copy token to response
1753
+ src_coap_blockwise_ack_msg_ptr -> token_ptr = handle -> sn_coap_protocol_malloc (received_coap_msg_ptr -> token_len );
1754
+ if (src_coap_blockwise_ack_msg_ptr -> token_ptr ) {
1755
+ memcpy (src_coap_blockwise_ack_msg_ptr -> token_ptr , received_coap_msg_ptr -> token_ptr , received_coap_msg_ptr -> token_len );
1756
+ src_coap_blockwise_ack_msg_ptr -> token_len = received_coap_msg_ptr -> token_len ;
1757
+ }
1758
+
1709
1759
dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size_2 (src_coap_blockwise_ack_msg_ptr , handle -> sn_coap_block_data_size );
1710
1760
1711
1761
dst_ack_packet_data_ptr = handle -> sn_coap_protocol_malloc (dst_packed_data_needed_mem );
@@ -1776,7 +1826,11 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn
1776
1826
1777
1827
/* Store blockwise payload to Linked list */
1778
1828
//todo: add block number to stored values - just to make sure all packets are in order
1779
- sn_coap_protocol_linked_list_blockwise_payload_store (handle , src_addr_ptr , received_coap_msg_ptr -> payload_len , received_coap_msg_ptr -> payload_ptr );
1829
+ sn_coap_protocol_linked_list_blockwise_payload_store (handle ,
1830
+ src_addr_ptr ,
1831
+ received_coap_msg_ptr -> payload_len ,
1832
+ received_coap_msg_ptr -> payload_ptr ,
1833
+ received_coap_msg_ptr -> options_list_ptr -> block1 >> 4 );
1780
1834
1781
1835
/* If not last block (more value is set) */
1782
1836
if (received_coap_msg_ptr -> options_list_ptr -> block2 & 0x08 ) {
0 commit comments