@@ -1535,26 +1535,57 @@ handle_request(coap_context_t *context, coap_queue_t *node) {
15351535 assert (response == NULL );
15361536}
15371537
1538+ static inline int
1539+ is_separate (const coap_queue_t * node ) {
1540+ return node -> retransmit_cnt > COAP_DEFAULT_MAX_RETRANSMIT ;
1541+ }
1542+
1543+ static int
1544+ coap_find_separate_from_queue (coap_context_t * context , const coap_address_t * dst ,
1545+ const unsigned char * token , size_t token_length , coap_queue_t * * sent ) {
1546+ for (coap_queue_t * p = context -> sendqueue ; p ; p = p -> next )
1547+ if (coap_address_equals (dst , & p -> remote ) &&
1548+ token_match (token , token_length ,
1549+ p -> pdu -> hdr -> token ,
1550+ p -> pdu -> hdr -> token_length ) &&
1551+ is_separate (p )) {
1552+ * sent = p ;
1553+ return 1 ;
1554+ }
1555+ return 0 ;
1556+ }
1557+
15381558static inline void
15391559handle_response (coap_context_t * context ,
15401560 coap_queue_t * sent , coap_queue_t * rcvd ) {
15411561
15421562 coap_send_ack (context , & rcvd -> local_if , & rcvd -> remote , rcvd -> pdu );
1543-
1544- /* In a lossy context, the ACK of a separate response may have
1545- * been lost, so we need to stop retransmitting requests with the
1546- * same token.
1563+
1564+ /* In case of separate response, the request cannot be matched with
1565+ * transaction id which is based on message id and remote address.
1566+ * Besides, excludes type Acknowledgement since separate response
1567+ * cannot be be of that type.
15471568 */
1548- coap_cancel_all_messages (context , & rcvd -> remote ,
1549- rcvd -> pdu -> hdr -> token ,
1550- rcvd -> pdu -> hdr -> token_length );
1569+ if (sent == NULL && rcvd -> pdu -> hdr -> type != COAP_MESSAGE_ACK ) {
1570+ coap_find_separate_from_queue (context , & rcvd -> remote ,
1571+ rcvd -> pdu -> hdr -> token ,
1572+ rcvd -> pdu -> hdr -> token_length , & sent );
1573+ }
15511574
15521575 /* Call application-specific response handler when available. */
15531576 if (context -> response_handler ) {
15541577 context -> response_handler (context , & rcvd -> local_if ,
15551578 & rcvd -> remote , sent ? sent -> pdu : NULL ,
15561579 rcvd -> pdu , rcvd -> id );
15571580 }
1581+
1582+ /* In a lossy context, the ACK of a separate response may have
1583+ * been lost, so we need to stop retransmitting requests with the
1584+ * same token.
1585+ */
1586+ coap_cancel_all_messages (context , & rcvd -> remote ,
1587+ rcvd -> pdu -> hdr -> token ,
1588+ rcvd -> pdu -> hdr -> token_length );
15581589}
15591590
15601591void
@@ -1580,8 +1611,15 @@ coap_dispatch(coap_context_t *context, coap_queue_t *rcvd) {
15801611 /* find transaction in sendqueue to stop retransmission */
15811612 coap_remove_from_queue (& context -> sendqueue , rcvd -> id , & sent );
15821613
1583- if (rcvd -> pdu -> hdr -> code == 0 )
1614+ if (rcvd -> pdu -> hdr -> code == 0 ) {
1615+ if (sent != NULL ) {
1616+ sent -> retransmit_cnt = COAP_DEFAULT_MAX_RETRANSMIT + 1 ;
1617+ sent -> t = sent -> timeout << COAP_DEFAULT_MAX_RETRANSMIT ;
1618+ coap_insert_node (& context -> sendqueue , sent );
1619+ sent = NULL ;
1620+ }
15841621 goto cleanup ;
1622+ }
15851623
15861624 /* if sent code was >= 64 the message might have been a
15871625 * notification. Then, we must flag the observer to be alive
0 commit comments