Skip to content

Commit

Permalink
net.c: handle separate response
Browse files Browse the repository at this point in the history
  • Loading branch information
codable committed Jun 5, 2017
1 parent cc49fbd commit d31ed51
Showing 1 changed file with 64 additions and 2 deletions.
66 changes: 64 additions & 2 deletions src/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1535,12 +1535,67 @@ handle_request(coap_context_t *context, coap_queue_t *node) {
assert(response == NULL);
}

static inline int
is_separate(const coap_queue_t *node) {
return node->retransmit_cnt > COAP_DEFAULT_MAX_RETRANSMIT;
}

static int
coap_remove_separate_from_queue(coap_context_t *context, const coap_address_t *dst,
const unsigned char *token, size_t token_length, coap_queue_t **sent) {
coap_queue_t *p, *q;
if (!context->sendqueue)
return 0;

if (coap_address_equals(dst, &context->sendqueue->remote) &&
token_match(token, token_length,
context->sendqueue->pdu->hdr->token,
context->sendqueue->pdu->hdr->token_length) &&
is_separate(context->sendqueue)) {
*sent = context->sendqueue;
context->sendqueue = context->sendqueue->next;
return 1;
}

p = context->sendqueue;
q = p->next;

/* when q is not NULL, it does not match (dst, token), so we can skip it */
while (q) {
if (coap_address_equals(dst, &q->remote) &&
token_match(token, token_length,
q->pdu->hdr->token,
q->pdu->hdr->token_length) &&
is_separate(q)) {
p->next = q->next;
q->next = NULL;
*sent = q;
return 1;
} else {
p = q;
q = q->next;
}
}
return 0;
}

static inline void
handle_response(coap_context_t *context,
coap_queue_t *sent, coap_queue_t *rcvd) {

coap_send_ack(context, &rcvd->local_if, &rcvd->remote, rcvd->pdu);


/* In case of separate response, the request cannot be matched with
* transaction id which is based on message id and remote address.
* Besides, excludes type Acknowledgement since separate response
* cannot be be of that type.
*/
if (sent == NULL && rcvd->pdu->hdr->type != COAP_MESSAGE_ACK) {
coap_remove_separate_from_queue(context, &rcvd->remote,
rcvd->pdu->hdr->token,
rcvd->pdu->hdr->token_length, &sent);
}

/* In a lossy context, the ACK of a separate response may have
* been lost, so we need to stop retransmitting requests with the
* same token.
Expand Down Expand Up @@ -1580,8 +1635,15 @@ coap_dispatch(coap_context_t *context, coap_queue_t *rcvd) {
/* find transaction in sendqueue to stop retransmission */
coap_remove_from_queue(&context->sendqueue, rcvd->id, &sent);

if (rcvd->pdu->hdr->code == 0)
if (rcvd->pdu->hdr->code == 0) {
if (sent != NULL) {
sent->retransmit_cnt = COAP_DEFAULT_MAX_RETRANSMIT + 1;
sent->t = sent->timeout << COAP_DEFAULT_MAX_RETRANSMIT;
coap_insert_node(&context->sendqueue, sent);
sent = NULL;
}
goto cleanup;
}

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

0 comments on commit d31ed51

Please sign in to comment.