coap_pdu_t * coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t size) { coap_pdu_t *pdu; #ifdef WITH_LWIP struct pbuf *p; #endif assert(size <= COAP_MAX_PDU_SIZE); /* Size must be large enough to fit the header. */ if (size < sizeof(coap_hdr_t) || size > COAP_MAX_PDU_SIZE) return NULL; /* size must be large enough for hdr */ #if defined(WITH_POSIX) || defined(WITH_CONTIKI) pdu = coap_malloc_type(COAP_PDU, sizeof(coap_pdu_t)); if (!pdu) return NULL; pdu->hdr = coap_malloc_type(COAP_PDU_BUF, size); if (pdu->hdr == NULL) { coap_free_type(COAP_PDU, pdu); pdu = NULL; } #endif /* WITH_POSIX or WITH_CONTIKI */ #ifdef WITH_LWIP pdu = (coap_pdu_t*)coap_malloc_type(COAP_PDU, sizeof(coap_pdu_t)); if (!pdu) return NULL; p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); if (p == NULL) { coap_free_type(COAP_PDU, pdu); pdu = NULL; } #endif if (pdu) { #ifdef WITH_LWIP pdu->pbuf = p; #endif coap_pdu_clear(pdu, size); pdu->hdr->id = id; pdu->hdr->type = type; pdu->hdr->code = code; } return pdu; }
coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf) { if (pbuf == NULL) return NULL; LWIP_ASSERT("Can only deal with contiguous PBUFs", pbuf->tot_len == pbuf->len); LWIP_ASSERT("coap_read needs to receive an exclusive copy of the incoming pbuf", pbuf->ref == 1); coap_pdu_t *result = coap_malloc_type(COAP_PDU, sizeof(coap_pdu_t)); if (!result) { pbuf_free(pbuf); return NULL; } memset(result, 0, sizeof(coap_pdu_t)); result->max_size = pbuf->tot_len; result->length = pbuf->tot_len; result->hdr = pbuf->payload; result->pbuf = pbuf; return result; }