Skip to content

Commit 4764567

Browse files
committed
handle separate
1 parent 771f013 commit 4764567

File tree

1 file changed

+64
-2
lines changed

1 file changed

+64
-2
lines changed

src/net.c

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,12 +1535,67 @@ 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_remove_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+
coap_queue_t *p, *q;
1547+
if (!context->sendqueue)
1548+
return 0;
1549+
1550+
if (coap_address_equals(dst, &context->sendqueue->remote) &&
1551+
token_match(token, token_length,
1552+
context->sendqueue->pdu->hdr->token,
1553+
context->sendqueue->pdu->hdr->token_length) &&
1554+
is_separate(context->sendqueue)) {
1555+
*sent = context->sendqueue;
1556+
context->sendqueue = context->sendqueue->next;
1557+
return 1;
1558+
}
1559+
1560+
p = context->sendqueue;
1561+
q = p->next;
1562+
1563+
/* when q is not NULL, it does not match (dst, token), so we can skip it */
1564+
while (q) {
1565+
if (coap_address_equals(dst, &q->remote) &&
1566+
token_match(token, token_length,
1567+
q->pdu->hdr->token,
1568+
q->pdu->hdr->token_length) &&
1569+
is_separate(q)) {
1570+
p->next = q->next;
1571+
q->next = NULL;
1572+
*sent = q;
1573+
return 1;
1574+
} else {
1575+
p = q;
1576+
q = q->next;
1577+
}
1578+
}
1579+
return 0;
1580+
}
1581+
15381582
static inline void
15391583
handle_response(coap_context_t *context,
15401584
coap_queue_t *sent, coap_queue_t *rcvd) {
15411585

15421586
coap_send_ack(context, &rcvd->local_if, &rcvd->remote, rcvd->pdu);
1543-
1587+
1588+
/* In case of separate response, the request cannot be matched with
1589+
* transaction id which is based on message id and remote address.
1590+
* Besides, excludes type Acknowledgement since separate response
1591+
* cannot be be of that type.
1592+
*/
1593+
if (sent == NULL && rcvd->pdu->hdr->type != COAP_MESSAGE_ACK) {
1594+
coap_remove_separate_from_queue(context, &rcvd->remote,
1595+
rcvd->pdu->hdr->token,
1596+
rcvd->pdu->hdr->token_length, &sent);
1597+
}
1598+
15441599
/* In a lossy context, the ACK of a separate response may have
15451600
* been lost, so we need to stop retransmitting requests with the
15461601
* same token.
@@ -1580,8 +1635,15 @@ coap_dispatch(coap_context_t *context, coap_queue_t *rcvd) {
15801635
/* find transaction in sendqueue to stop retransmission */
15811636
coap_remove_from_queue(&context->sendqueue, rcvd->id, &sent);
15821637

1583-
if (rcvd->pdu->hdr->code == 0)
1638+
if (rcvd->pdu->hdr->code == 0) {
1639+
if (sent != NULL) {
1640+
sent->retransmit_cnt = COAP_DEFAULT_MAX_RETRANSMIT + 1;
1641+
sent->t = sent->timeout << COAP_DEFAULT_MAX_RETRANSMIT;
1642+
coap_insert_node(&context->sendqueue, sent);
1643+
sent = NULL;
1644+
}
15841645
goto cleanup;
1646+
}
15851647

15861648
/* if sent code was >= 64 the message might have been a
15871649
* notification. Then, we must flag the observer to be alive

0 commit comments

Comments
 (0)