@@ -1535,12 +1535,58 @@ handle_request(coap_context_t *context, coap_queue_t *node) {
15351535 assert (response == NULL );
15361536}
15371537
1538+ static int
1539+ coap_remove_separate_from_queue (coap_context_t * context , const coap_address_t * dst ,
1540+ const unsigned char * token , size_t token_length , coap_queue_t * * sent ) {
1541+ coap_queue_t * p , * q ;
1542+ if (!context -> sendqueue )
1543+ return 0 ;
1544+
1545+ if (coap_address_equals (dst , & context -> sendqueue -> remote ) &&
1546+ token_match (token , token_length ,
1547+ context -> sendqueue -> pdu -> hdr -> token ,
1548+ context -> sendqueue -> pdu -> hdr -> token_length ) &&
1549+ context -> sendqueue -> retransmit_cnt > COAP_DEFAULT_MAX_RETRANSMIT ) {
1550+ * sent = context -> sendqueue ;
1551+ context -> sendqueue = context -> sendqueue -> next ;
1552+ return 1 ;
1553+ }
1554+
1555+ p = context -> sendqueue ;
1556+ q = p -> next ;
1557+
1558+ /* when q is not NULL, it does not match (dst, token), so we can skip it */
1559+ while (q ) {
1560+ if (coap_address_equals (dst , & context -> sendqueue -> remote ) &&
1561+ token_match (token , token_length ,
1562+ context -> sendqueue -> pdu -> hdr -> token ,
1563+ context -> sendqueue -> pdu -> hdr -> token_length ) &&
1564+ context -> sendqueue -> retransmit_cnt > COAP_DEFAULT_MAX_RETRANSMIT ) {
1565+ p -> next = q -> next ;
1566+ q -> next = NULL ;
1567+ * sent = q ;
1568+ return 1 ;
1569+ } else {
1570+ p = q ;
1571+ q = q -> next ;
1572+ }
1573+ }
1574+ return 0 ;
1575+ }
1576+
15381577static inline void
15391578handle_response (coap_context_t * context ,
15401579 coap_queue_t * sent , coap_queue_t * rcvd ) {
15411580
15421581 coap_send_ack (context , & rcvd -> local_if , & rcvd -> remote , rcvd -> pdu );
1543-
1582+
1583+ /* Find separate response's request */
1584+ if (sent == NULL ) {
1585+ coap_remove_separate_from_queue (context , & rcvd -> remote ,
1586+ rcvd -> pdu -> hdr -> token ,
1587+ rcvd -> pdu -> hdr -> token_length , & sent );
1588+ }
1589+
15441590 /* In a lossy context, the ACK of a separate response may have
15451591 * been lost, so we need to stop retransmitting requests with the
15461592 * same token.
@@ -1580,8 +1626,15 @@ coap_dispatch(coap_context_t *context, coap_queue_t *rcvd) {
15801626 /* find transaction in sendqueue to stop retransmission */
15811627 coap_remove_from_queue (& context -> sendqueue , rcvd -> id , & sent );
15821628
1583- if (rcvd -> pdu -> hdr -> code == 0 )
1629+ if (rcvd -> pdu -> hdr -> code == 0 ) {
1630+ if (sent != NULL ) {
1631+ sent -> retransmit_cnt = COAP_DEFAULT_MAX_RETRANSMIT + 1 ;
1632+ sent -> t = sent -> timeout << COAP_DEFAULT_MAX_RETRANSMIT ;
1633+ coap_insert_node (& context -> sendqueue , sent );
1634+ sent = NULL ;
1635+ }
15841636 goto cleanup ;
1637+ }
15851638
15861639 /* if sent code was >= 64 the message might have been a
15871640 * notification. Then, we must flag the observer to be alive
0 commit comments