int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu) { coap_opt_t *opt; assert(data); assert(pdu); if (pdu->max_size < length) { debug("insufficient space to store parsed PDU\n"); return 0; } if (length < COAP_HDR_SIZE) { debug("discarded invalid PDU\n"); } #ifdef WITH_LWIP LWIP_ASSERT("coap_pdu_parse with unexpected addresses", data == pdu->hdr); LWIP_ASSERT("coap_pdu_parse with unexpected length", length == pdu->length); #else pdu->hdr->version = data[0] >> 6; pdu->hdr->type = (data[0] >> 4) & 0x03; pdu->hdr->token_length = data[0] & 0x0f; pdu->hdr->code = data[1]; #endif pdu->data = NULL; /* sanity checks */ if (pdu->hdr->code == 0) { if (length != COAP_HDR_SIZE || pdu->hdr->token_length) { debug("coap_pdu_parse: empty message is not empty\n"); goto discard; } } if (length < sizeof(coap_hdr_t) + pdu->hdr->token_length || pdu->hdr->token_length > 8) { debug("coap_pdu_parse: invalid Token\n"); goto discard; } #ifndef WITH_LWIP /* Copy message id in network byte order, so we can easily write the * response back to the network. */ memcpy(&pdu->hdr->id, data + 2, 2); /* append data (including the Token) to pdu structure */ memcpy(pdu->hdr + 1, data + COAP_HDR_SIZE, length - COAP_HDR_SIZE); pdu->length = (unsigned short)length; /* Finally calculate beginning of data block and thereby check integrity * of the PDU structure. */ #endif /* skip header + token */ length -= (pdu->hdr->token_length + COAP_HDR_SIZE); opt = (unsigned char *)(pdu->hdr + 1) + pdu->hdr->token_length; while (length && *opt != COAP_PAYLOAD_START) { if (!next_option_safe(&opt, (size_t *)&length)) { debug("coap_pdu_parse: drop\n"); goto discard; } } /* end of packet or start marker */ if (length) { assert(*opt == COAP_PAYLOAD_START); opt++; length--; if (!length) { debug("coap_pdu_parse: message ending in payload start marker\n"); goto discard; } debug("set data to %p (pdu ends at %p)\n", (unsigned char *)opt, (unsigned char *)pdu->hdr + pdu->length); pdu->data = (unsigned char *)opt; } return 1; discard: return 0; }
int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu) { coap_opt_t *opt; assert(data); assert(pdu); if (pdu->max_size < length) { debug("insufficient space to store parsed PDU\n"); printf("[COAP] insufficient space to store parsed PDU\n"); return 0; } if (length < sizeof(coap_hdr_t)) { debug("discarded invalid PDU\n"); } pdu->hdr->version = data[0] >> 6; pdu->hdr->type = (data[0] >> 4) & 0x03; pdu->hdr->token_length = data[0] & 0x0f; pdu->hdr->code = data[1]; /* printf("[COAP] pdu - version : %d\n", pdu->hdr->version); printf("[COAP] pdu - type : %d\n", pdu->hdr->type); printf("[COAP] pdu - token_length : %d\n", pdu->hdr->token_length); printf("[COAP] pdu - code : %d\n", pdu->hdr->code); */ pdu->data = NULL; /* sanity checks */ if (pdu->hdr->code == 0) { if (length != sizeof(coap_hdr_t) || pdu->hdr->token_length) { debug("coap_pdu_parse: empty message is not empty\n"); goto discard; } } if (length < sizeof(coap_hdr_t) + pdu->hdr->token_length || pdu->hdr->token_length > 8) { debug("coap_pdu_parse: invalid Token\n"); goto discard; } /* Copy message id in network byte order, so we can easily write the * response back to the network. */ memcpy(&pdu->hdr->id, data + 2, 2); //printf("[COAP] pdu - id : %d\n", pdu->hdr->id); /* append data (including the Token) to pdu structure */ memcpy(pdu->hdr + 1, data + sizeof(coap_hdr_t), length - sizeof(coap_hdr_t)); pdu->length = length; /* Finally calculate beginning of data block and thereby check integrity * of the PDU structure. */ /* skip header + token */ length -= (pdu->hdr->token_length + sizeof(coap_hdr_t)); opt = (unsigned char *) (pdu->hdr + 1) + pdu->hdr->token_length; while (length && *opt != COAP_PAYLOAD_START) { coap_option_t option; memset(&option, 0, sizeof(coap_option_t)); if (!next_option_safe(&opt, (size_t *) &length, &option)) { debug("coap_pdu_parse: drop\n"); goto discard; } } /* end of packet or start marker */ if (length) { assert(*opt == COAP_PAYLOAD_START); opt++; length--; if (!length) { debug("coap_pdu_parse: message ending in payload start marker\n"); goto discard; } debug( "set data to %p (pdu ends at %p)\n", (unsigned char *)opt, (unsigned char *)pdu->hdr + pdu->length); pdu->data = (unsigned char *) opt; //printf("[COAP] pdu - data : %s\n", pdu->data); } return 1; discard: return 0; }