1 /* pdu.c -- CoAP message structure
3 * Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
5 * This file is part of the CoAP library libcoap. Please see
6 * README for terms of use.
11 #if defined(HAVE_ASSERT_H) && !defined(assert)
18 #ifdef HAVE_ARPA_INET_H
19 #include <arpa/inet.h>
35 typedef unsigned char _pdu[sizeof(coap_pdu_t) + COAP_MAX_PDU_SIZE];
37 MEMB(pdu_storage, _pdu, COAP_PDU_MAXCNT);
41 coap_pdu_resources_init()
43 memb_init(&pdu_storage);
45 #else /* WITH_CONTIKI */
47 #endif /* WITH_CONTIKI */
49 void coap_pdu_clear(coap_pdu_t *pdu, size_t size, coap_transport_type transport, unsigned int length)
53 memset(pdu, 0, sizeof(coap_pdu_t) + size);
55 pdu->hdr = (coap_hdr_t *) ((unsigned char *) pdu + sizeof(coap_pdu_t));
57 if (coap_udp == transport)
59 pdu->hdr->coap_hdr_udp_t.version = COAP_DEFAULT_VERSION;
60 /* data is NULL unless explicitly set by coap_add_data() */
61 pdu->length = sizeof(pdu->hdr->coap_hdr_udp_t);
66 /* data is NULL unless explicitly set by coap_add_data() */
74 coap_pdu_from_pbuf(struct pbuf *pbuf)
76 LWIP_ASSERT("Can only deal with contiguous PBUFs", pbuf->tot_len == pbuf->len);
77 LWIP_ASSERT("coap_read needs to receive an exclusive copy of the incoming pbuf", pbuf->ref == 1);
79 void *data = pbuf->payload;
82 u8_t header_error = pbuf_header(pbuf, sizeof(coap_pdu_t));
83 LWIP_ASSERT("CoAP PDU header does not fit in existing header space", header_error == 0);
85 result = (coap_pdu_t *)pbuf->payload;
87 memset(result, 0, sizeof(coap_pdu_t));
89 result->max_size = pbuf->tot_len - sizeof(coap_pdu_t);
90 result->length = pbuf->tot_len - sizeof(coap_pdu_t);
99 coap_pdu_init(unsigned char type, unsigned char code, unsigned short id,
100 size_t size, coap_transport_type transport)
107 unsigned int length = 0;
111 length = sizeof(pdu->hdr->coap_hdr_udp_t);
115 length = COAP_TCP_HEADER_NO_FIELD;
118 length = COAP_TCP_HEADER_8_BIT;
121 length = COAP_TCP_HEADER_16_BIT;
124 length = COAP_TCP_HEADER_32_BIT;
128 debug("it has wrong type\n");
132 assert(size <= COAP_MAX_PDU_SIZE);
133 /* Size must be large enough to fit the header. */
134 if (size < length || size > COAP_MAX_PDU_SIZE)
138 /* size must be large enough for hdr */
139 #if defined(WITH_POSIX) || defined(WITH_ARDUINO)
140 pdu = (coap_pdu_t *) coap_malloc(sizeof(coap_pdu_t) + size);
143 pdu = (coap_pdu_t *)memb_alloc(&pdu_storage);
146 p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
149 u8_t header_error = pbuf_header(p, sizeof(coap_pdu_t));
150 /* we could catch that case and allocate larger memory in advance, but then
151 * again, we'd run into greater trouble with incoming packages anyway */
152 LWIP_ASSERT("CoAP PDU header does not fit in transport header", header_error == 0);
162 coap_pdu_clear(pdu, size, transport, length);
167 pdu->hdr->coap_hdr_udp_t.id = id;
168 pdu->hdr->coap_hdr_udp_t.type = type;
169 pdu->hdr->coap_hdr_udp_t.code = code;
173 pdu->hdr->coap_hdr_tcp_t.header_data[0] = 0;
174 pdu->hdr->coap_hdr_tcp_t.header_data[1] = code;
177 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_8_BIT << 4;
178 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[2] = code;
181 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_16_BIT << 4;
182 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[3] = code;
185 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_32_BIT << 4;
186 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5] = code;
190 debug("it has wrong type\n");
201 coap_new_pdu(coap_transport_type transport, unsigned int size)
206 pdu = coap_pdu_init(0, 0,
207 ntohs(COAP_INVALID_TID),
214 #else /* WITH_CONTIKI */
215 pdu = coap_pdu_init(0, 0, uip_ntohs(COAP_INVALID_TID),
222 #endif /* WITH_CONTIKI */
226 coap_log(LOG_CRIT, "coap_new_pdu: cannot allocate memory for new PDU\n");
231 void coap_delete_pdu(coap_pdu_t *pdu)
233 #if defined(WITH_POSIX) || defined(WITH_ARDUINO)
237 if (pdu != NULL) /* accepting double free as the other implementation accept that too */
238 pbuf_free(pdu->pbuf);
241 memb_free(&pdu_storage, pdu);
246 coap_transport_type coap_get_tcp_header_type_from_size(unsigned int size)
248 if (COAP_TCP_LENGTH_LIMIT_8_BIT < size && COAP_TCP_LENGTH_LIMIT_16_BIT >= size)
250 return coap_tcp_8bit;
252 else if (COAP_TCP_LENGTH_LIMIT_16_BIT < size && COAP_TCP_LENGTH_LIMIT_32_BIT >= size)
254 return coap_tcp_16bit;
256 else if (COAP_TCP_LENGTH_LIMIT_32_BIT < size)
258 return coap_tcp_32bit;
266 coap_transport_type coap_get_tcp_header_type_from_initbyte(unsigned int length)
268 coap_transport_type type;
271 case COAP_TCP_LENGTH_FIELD_NUM_8_BIT:
272 type = coap_tcp_8bit;
274 case COAP_TCP_LENGTH_FIELD_NUM_16_BIT:
275 type = coap_tcp_16bit;
277 case COAP_TCP_LENGTH_FIELD_NUM_32_BIT:
278 type = coap_tcp_32bit;
286 void coap_add_length(const coap_pdu_t *pdu, coap_transport_type transport, unsigned int length)
293 pdu->hdr->coap_hdr_tcp_t.header_data[0] = length << 4;
296 if (length > COAP_TCP_LENGTH_FIELD_8_BIT)
298 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[1] =
299 length - COAP_TCP_LENGTH_FIELD_8_BIT;
303 if (length > COAP_TCP_LENGTH_FIELD_16_BIT)
305 unsigned int total_length = length - COAP_TCP_LENGTH_FIELD_16_BIT;
306 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[1] = (total_length >> 8) & 0x0000ff;
307 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[2] = total_length & 0x000000ff;
311 if (length > COAP_TCP_LENGTH_FIELD_32_BIT)
313 unsigned int total_length = length - COAP_TCP_LENGTH_FIELD_32_BIT;
314 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[1] = total_length >> 24;
315 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[2] = (total_length >> 16) & 0x00ff;
316 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[3] = (total_length >> 8) & 0x0000ff;
317 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[4] = total_length & 0x000000ff;
321 debug("it has wrong type\n");
325 unsigned int coap_get_length_from_header(const unsigned char *header, coap_transport_type transport)
329 unsigned int length = 0;
330 unsigned int length_field_data = 0;
334 length = header[0] >> 4;
337 length = header[1] + COAP_TCP_LENGTH_FIELD_8_BIT;
340 length_field_data = (header[1] << 8 | header[2]);
341 length = length_field_data + COAP_TCP_LENGTH_FIELD_16_BIT;
344 length_field_data = header[1] << 24 | header[2] << 16 | header[3] << 8 | header[4];
345 length = length_field_data + COAP_TCP_LENGTH_FIELD_32_BIT;
348 debug("it has wrong type\n");
354 unsigned int coap_get_length(const coap_pdu_t *pdu, coap_transport_type transport)
358 unsigned int length = 0;
359 unsigned int length_field_data = 0;
363 length = pdu->hdr->coap_hdr_tcp_t.header_data[0] >> 4;
366 length = pdu->hdr->coap_hdr_tcp_8bit_t.header_data[1] + COAP_TCP_LENGTH_FIELD_8_BIT;
370 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[1] << 8 |
371 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[2];
372 length = length_field_data + COAP_TCP_LENGTH_FIELD_16_BIT;
376 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[1] << 24 |
377 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[2] << 16 |
378 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[3] << 8 |
379 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[4];
380 length = length_field_data + COAP_TCP_LENGTH_FIELD_32_BIT;
383 debug("it has wrong type\n");
389 unsigned int coap_get_tcp_header_length(unsigned char *data)
393 unsigned int tokenLength = data[0] & 0x0f;
394 coap_transport_type transport =
395 coap_get_tcp_header_type_from_initbyte(data[0] >> 4);
396 unsigned int length = 0;
398 length = coap_get_tcp_header_length_for_transport(transport) + tokenLength;
402 unsigned int coap_get_tcp_header_length_for_transport(coap_transport_type transport)
404 unsigned int length = 0;
408 length = COAP_TCP_HEADER_NO_FIELD;
411 length = COAP_TCP_HEADER_8_BIT;
414 length = COAP_TCP_HEADER_16_BIT;
417 length = COAP_TCP_HEADER_32_BIT;
420 debug("it has wrong type\n");
426 size_t coap_get_opt_header_length(unsigned short key, size_t length)
428 size_t headerLength = 0;
430 unsigned short optDeltaLength = 0;
431 if (COAP_OPTION_FIELD_8_BIT >= key)
435 else if (COAP_OPTION_FIELD_8_BIT < key && COAP_OPTION_FIELD_16_BIT >= key)
439 else if (COAP_OPTION_FIELD_16_BIT < key && COAP_OPTION_FIELD_32_BIT >= key)
445 printf("Error : Reserved for the Payload marker for Delta");
449 size_t optLength = 0;
450 if (COAP_OPTION_FIELD_8_BIT >= length)
454 else if (COAP_OPTION_FIELD_8_BIT < length && COAP_OPTION_FIELD_16_BIT >= length)
458 else if (COAP_OPTION_FIELD_16_BIT < length && COAP_OPTION_FIELD_32_BIT >= length)
464 printf("Error : Reserved for the Payload marker for length");
468 headerLength = length + optDeltaLength + optLength + 1;
475 void coap_add_code(const coap_pdu_t *pdu, coap_transport_type transport, unsigned int code)
482 pdu->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(code);
486 pdu->hdr->coap_hdr_tcp_t.header_data[1] = COAP_RESPONSE_CODE(code);
489 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[2] = COAP_RESPONSE_CODE(code);
492 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[3] = COAP_RESPONSE_CODE(code);
495 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5] = COAP_RESPONSE_CODE(code);
499 debug("it has wrong type\n");
503 unsigned int coap_get_code(const coap_pdu_t *pdu, coap_transport_type transport)
507 unsigned int code = 0;
511 code = pdu->hdr->coap_hdr_udp_t.code;
515 code = pdu->hdr->coap_hdr_tcp_t.header_data[1];
518 code = pdu->hdr->coap_hdr_tcp_8bit_t.header_data[2];
521 code = pdu->hdr->coap_hdr_tcp_16bit_t.header_data[3];
524 code = pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5];
528 debug("it has wrong type\n");
533 int coap_add_token(coap_pdu_t *pdu, size_t len, const unsigned char *data,
534 coap_transport_type transport)
536 const size_t HEADERLENGTH = len + 4;
537 /* must allow for pdu == NULL as callers may rely on this */
538 if (!pdu || len > 8 || pdu->max_size < HEADERLENGTH)
541 unsigned char* token = NULL;
545 pdu->hdr->coap_hdr_udp_t.token_length = len;
546 token = pdu->hdr->coap_hdr_udp_t.token;
547 pdu->length = HEADERLENGTH;
551 pdu->hdr->coap_hdr_tcp_t.header_data[0] =
552 pdu->hdr->coap_hdr_tcp_t.header_data[0] | len;
553 token = pdu->hdr->coap_hdr_tcp_t.token;
554 pdu->length = len + COAP_TCP_HEADER_NO_FIELD;
557 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[0] =
558 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[0] | len;
559 token = pdu->hdr->coap_hdr_tcp_8bit_t.token;
560 pdu->length = len + COAP_TCP_HEADER_8_BIT;
563 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[0] =
564 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[0] | len;
565 token = pdu->hdr->coap_hdr_tcp_16bit_t.token;
566 pdu->length = len + COAP_TCP_HEADER_16_BIT;
569 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] =
570 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] | len;
571 token = pdu->hdr->coap_hdr_tcp_32bit_t.token;
572 pdu->length = len + COAP_TCP_HEADER_32_BIT;
576 debug("it has wrong type\n");
581 memcpy(token, data, len);
590 void coap_get_token(const coap_hdr_t *pdu_hdr, coap_transport_type transport,
591 unsigned char **token, unsigned int *token_length)
595 assert(token_length);
600 *token_length = pdu_hdr->coap_hdr_udp_t.token_length;
601 *token = (unsigned char *)pdu_hdr->coap_hdr_udp_t.token;
605 *token_length = (pdu_hdr->coap_hdr_tcp_t.header_data[0]) & 0x0f;
606 *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_t.token;
609 *token_length = (pdu_hdr->coap_hdr_tcp_8bit_t.header_data[0]) & 0x0f;
610 *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_8bit_t.token;
613 *token_length = (pdu_hdr->coap_hdr_tcp_16bit_t.header_data[0]) & 0x0f;
614 *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_16bit_t.token;
617 *token_length = (pdu_hdr->coap_hdr_tcp_32bit_t.header_data[0]) & 0x0f;
618 *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_32bit_t.token;
622 debug("it has wrong type\n");
626 /** @FIXME de-duplicate code with coap_add_option_later */
627 size_t coap_add_option(coap_pdu_t *pdu, unsigned short type, unsigned int len,
628 const unsigned char *data, coap_transport_type transport)
636 if (type < pdu->max_delta)
638 warn("coap_add_option: options are not in correct order\n");
646 opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_t) + pdu->length;
649 opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_8bit_t) + pdu->length;
652 opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_16bit_t) + pdu->length;
655 opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_32bit_t) + pdu->length;
659 opt = (unsigned char *) &(pdu->hdr->coap_hdr_udp_t) + pdu->length;
663 /* encode option and check length */
664 optsize = coap_opt_encode(opt, pdu->max_size - pdu->length, type - pdu->max_delta, data, len);
668 warn("coap_add_option: cannot add option\n");
674 pdu->max_delta = type;
675 pdu->length += optsize;
681 /** @FIXME de-duplicate code with coap_add_option */
683 coap_add_option_later(coap_pdu_t *pdu, unsigned short type, unsigned int len)
691 if (type < pdu->max_delta)
693 warn("coap_add_option: options are not in correct order\n");
697 opt = (unsigned char *) pdu->hdr + pdu->length;
699 /* encode option and check length */
700 optsize = coap_opt_encode(opt, pdu->max_size - pdu->length, type - pdu->max_delta, NULL, len);
704 warn("coap_add_option: cannot add option\n");
710 pdu->max_delta = type;
711 pdu->length += optsize;
714 return ((unsigned char*) opt) + optsize - len;
717 int coap_add_data(coap_pdu_t *pdu, unsigned int len, const unsigned char *data)
720 assert(pdu->data == NULL);
725 if (pdu->length + len + 1 > pdu->max_size)
727 warn("coap_add_data: cannot add: data too large for PDU\n");
728 assert(pdu->data == NULL);
732 pdu->data = (unsigned char *) pdu->hdr + pdu->length;
733 *pdu->data = COAP_PAYLOAD_START;
736 memcpy(pdu->data, data, len);
737 pdu->length += len + 1;
741 int coap_get_data(const coap_pdu_t *pdu, size_t *len, unsigned char **data)
749 *len = (unsigned char *) pdu->hdr + pdu->length - pdu->data;
753 { /* no data, clear everything */
758 return *data != NULL;
761 #ifndef SHORT_ERROR_RESPONSE
768 /* if you change anything here, make sure, that the longest string does not
769 * exceed COAP_ERROR_PHRASE_LENGTH. */
770 error_desc_t coap_error[] =
772 { COAP_RESPONSE_CODE(65), "2.01 Created" },
773 { COAP_RESPONSE_CODE(66), "2.02 Deleted" },
774 { COAP_RESPONSE_CODE(67), "2.03 Valid" },
775 { COAP_RESPONSE_CODE(68), "2.04 Changed" },
776 { COAP_RESPONSE_CODE(69), "2.05 Content" },
777 { COAP_RESPONSE_CODE(400), "Bad Request" },
778 { COAP_RESPONSE_CODE(401), "Unauthorized" },
779 { COAP_RESPONSE_CODE(402), "Bad Option" },
780 { COAP_RESPONSE_CODE(403), "Forbidden" },
781 { COAP_RESPONSE_CODE(404), "Not Found" },
782 { COAP_RESPONSE_CODE(405), "Method Not Allowed" },
783 { COAP_RESPONSE_CODE(408), "Request Entity Incomplete" },
784 { COAP_RESPONSE_CODE(413), "Request Entity Too Large" },
785 { COAP_RESPONSE_CODE(415), "Unsupported Media Type" },
786 { COAP_RESPONSE_CODE(500), "Internal Server Error" },
787 { COAP_RESPONSE_CODE(501), "Not Implemented" },
788 { COAP_RESPONSE_CODE(502), "Bad Gateway" },
789 { COAP_RESPONSE_CODE(503), "Service Unavailable" },
790 { COAP_RESPONSE_CODE(504), "Gateway Timeout" },
791 { COAP_RESPONSE_CODE(505), "Proxying Not Supported" },
792 { 0, NULL } /* end marker */
796 coap_response_phrase(unsigned char code)
799 for (i = 0; coap_error[i].code; ++i)
801 if (coap_error[i].code == code)
802 return coap_error[i].phrase;
809 * Advances *optp to next option if still in PDU. This function
810 * returns the number of bytes opt has been advanced or @c 0
813 static size_t next_option_safe(coap_opt_t **optp, size_t *length, coap_option_t* option)
815 //coap_option_t option;
821 optsize = coap_opt_parse(*optp, *length, option);
824 assert(optsize <= *length);
833 int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu,
834 coap_transport_type transport)
839 if (pdu->max_size < length)
841 debug("insufficient space to store parsed PDU\n");
842 printf("[COAP] insufficient space to store parsed PDU\n");
846 unsigned int headerSize = 0;
848 if (coap_udp == transport)
850 headerSize = sizeof(pdu->hdr->coap_hdr_udp_t);
855 headerSize = coap_get_tcp_header_length_for_transport(transport);
859 if (length < headerSize)
861 debug("discarded invalid PDU\n");
864 coap_opt_t *opt = NULL;
865 unsigned int tokenLength = 0;
872 for (size_t i = 0 ; i < headerSize ; i++)
874 pdu->hdr->coap_hdr_tcp_t.header_data[i] = data[i];
877 tokenLength = data[0] & 0x0f;
878 opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_t) + 1) + tokenLength;
881 for (size_t i = 0 ; i < headerSize ; i++)
883 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[i] = data[i];
886 tokenLength = data[0] & 0x0f;
887 opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_8bit_t))
888 + tokenLength + COAP_TCP_HEADER_8_BIT;
891 for (size_t i = 0 ; i < headerSize ; i++)
893 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[i] = data[i];
896 tokenLength = data[0] & 0x0f;
897 opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_16bit_t) + 1) + tokenLength;
900 for (size_t i = 0 ; i < headerSize ; i++)
902 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[i] = data[i];
905 tokenLength = data[0] & 0x0f;
906 opt = ((unsigned char *) &(pdu->hdr->coap_hdr_tcp_32bit_t)) +
907 headerSize + tokenLength;
910 printf("it has wrong type\n");
913 pdu->length = length;
915 if (coap_udp == transport)
917 pdu->hdr->coap_hdr_udp_t.version = data[0] >> 6;
918 pdu->hdr->coap_hdr_udp_t.type = (data[0] >> 4) & 0x03;
919 pdu->hdr->coap_hdr_udp_t.token_length = data[0] & 0x0f;
920 pdu->hdr->coap_hdr_udp_t.code = data[1];
923 tokenLength = pdu->hdr->coap_hdr_udp_t.token_length;
926 if (pdu->hdr->coap_hdr_udp_t.code == 0)
928 if (length != headerSize || tokenLength)
930 debug("coap_pdu_parse: empty message is not empty\n");
935 if (length < headerSize + tokenLength || tokenLength > 8)
937 debug("coap_pdu_parse: invalid Token\n");
941 memcpy(&pdu->hdr->coap_hdr_udp_t.id, data + 2, 2);
943 /* Finally calculate beginning of data block and thereby check integrity
944 * of the PDU structure. */
946 /* append data (including the Token) to pdu structure */
947 memcpy(&(pdu->hdr->coap_hdr_udp_t) + 1, data + headerSize, length - headerSize);
949 /* skip header + token */
950 length -= (tokenLength + headerSize);
951 opt = (unsigned char *) (&(pdu->hdr->coap_hdr_udp_t) + 1) + tokenLength;
954 else // common for tcp header setting
958 if (length < headerSize + tokenLength || tokenLength > 8)
960 debug("coap_pdu_parse: invalid Token\n");
963 /* Finally calculate beginning of data block and thereby check integrity
964 * of the PDU structure. */
966 /* append data (including the Token) to pdu structure */
967 memcpy(((unsigned char *) pdu->hdr) + headerSize,
968 data + headerSize, length - headerSize);
970 /* skip header + token */
971 length -= (tokenLength + headerSize);
975 while (length && *opt != COAP_PAYLOAD_START)
977 coap_option_t option;
978 memset(&option, 0, sizeof(coap_option_t));
979 if (!next_option_safe(&opt, (size_t *) &length, &option))
981 debug("coap_pdu_parse: drop\n");
986 /* end of packet or start marker */
989 assert(*opt == COAP_PAYLOAD_START);
995 debug("coap_pdu_parse: message ending in payload start marker\n");
1000 "set data to %p (pdu ends at %p)\n", (unsigned char *)opt,
1001 (unsigned char *)pdu->hdr + pdu->length);
1002 pdu->data = (unsigned char *) opt;
1003 //printf("[COAP] pdu - data : %s\n", pdu->data);