diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 70f2610adf0227..93852fd29298ef 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1808,6 +1808,8 @@ struct coap_reply *coap_response_received( { struct coap_reply *r; uint8_t token[COAP_TOKEN_MAX_LEN]; + bool piggybacked = false; + uint8_t type; uint16_t id; uint8_t tkl; size_t i; @@ -1817,9 +1819,14 @@ struct coap_reply *coap_response_received( return NULL; } + type = coap_header_get_type(response); id = coap_header_get_id(response); tkl = coap_header_get_token(response, token); + if (type == COAP_TYPE_ACK || type == COAP_TYPE_RESET) { + piggybacked = true; + } + for (i = 0, r = replies; i < len; i++, r++) { int age; @@ -1827,13 +1834,29 @@ struct coap_reply *coap_response_received( continue; } - /* Piggybacked must match id when token is empty */ - if ((r->id != id) && (tkl == 0U)) { - continue; - } + if (piggybacked) { + /* In a piggybacked response, the Message ID of the + * Confirmable request and the Acknowledgment MUST + * match, and the tokens of the response and original + * request MUST match. + */ + if ((r->id != id || (r->tkl != tkl))) { + continue; + } - if (tkl > 0 && memcmp(r->token, token, tkl)) { - continue; + if (r->tkl > 0) { + if (memcmp(r->token, token, r->tkl) != 0) { + continue; + } + } + } else { + /* In a separate response, just the tokens of the + * response and original request MUST match. + */ + if ((r->tkl == 0) || (r->tkl != tkl) || + (memcmp(r->token, token, r->tkl) != 0)) { + continue; + } } age = coap_get_option_int(response, COAP_OPTION_OBSERVE);