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 12, 2017
1 parent cc49fbd commit 2f42f89
Showing 1 changed file with 47 additions and 8 deletions.
55 changes: 47 additions & 8 deletions src/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1535,26 +1535,58 @@ 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_find_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 = NULL;
for (p = context->sendqueue; p; p = p->next)
if (coap_address_equals(dst, &p->remote) &&
token_match(token, token_length,
p->pdu->hdr->token,
p->pdu->hdr->token_length) &&
is_separate(p)) {
*sent = p;
return 1;
}
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 a lossy context, the ACK of a separate response may have
* been lost, so we need to stop retransmitting requests with the
* same token.

/* 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.
*/
coap_cancel_all_messages(context, &rcvd->remote,
rcvd->pdu->hdr->token,
rcvd->pdu->hdr->token_length);
if (sent == NULL && rcvd->pdu->hdr->type != COAP_MESSAGE_ACK) {
coap_find_separate_from_queue(context, &rcvd->remote,
rcvd->pdu->hdr->token,
rcvd->pdu->hdr->token_length, &sent);
}

/* Call application-specific response handler when available. */
if (context->response_handler) {
context->response_handler(context, &rcvd->local_if,
&rcvd->remote, sent ? sent->pdu : NULL,
rcvd->pdu, rcvd->id);
}

/* 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.
*/
coap_cancel_all_messages(context, &rcvd->remote,
rcvd->pdu->hdr->token,
rcvd->pdu->hdr->token_length);
}

void
Expand All @@ -1580,8 +1612,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 2f42f89

Please sign in to comment.