Skip to content

Commit d646d90

Browse files
committed
net.c: handle separate response
1 parent cc49fbd commit d646d90

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed

src/net.c

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
15381558
static inline void
15391559
handle_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

15601591
void
@@ -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

Comments
 (0)