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)
19 #ifdef HAVE_ARPA_INET_H
20 #include <arpa/inet.h>
36 typedef unsigned char _pdu[sizeof(coap_pdu_t) + COAP_MAX_PDU_SIZE];
38 MEMB(pdu_storage, _pdu, COAP_PDU_MAXCNT);
42 coap_pdu_resources_init()
44 memb_init(&pdu_storage);
46 #else /* WITH_CONTIKI */
48 #endif /* WITH_CONTIKI */
50 void coap_pdu_clear(coap_pdu_t *pdu, size_t size, coap_transport_type transport, unsigned int length)
54 memset(pdu, 0, sizeof(coap_pdu_t) + size);
56 pdu->hdr = (coap_hdr_t *) ((unsigned char *) pdu + sizeof(coap_pdu_t));
58 if (coap_udp == transport)
60 pdu->hdr->coap_hdr_udp_t.version = COAP_DEFAULT_VERSION;
61 /* data is NULL unless explicitly set by coap_add_data() */
62 pdu->length = sizeof(pdu->hdr->coap_hdr_udp_t);
67 /* data is NULL unless explicitly set by coap_add_data() */
75 coap_pdu_from_pbuf(struct pbuf *pbuf)
77 LWIP_ASSERT("Can only deal with contiguous PBUFs", pbuf->tot_len == pbuf->len);
78 LWIP_ASSERT("coap_read needs to receive an exclusive copy of the incoming pbuf", pbuf->ref == 1);
80 void *data = pbuf->payload;
83 u8_t header_error = pbuf_header(pbuf, sizeof(coap_pdu_t));
84 LWIP_ASSERT("CoAP PDU header does not fit in existing header space", header_error == 0);
86 result = (coap_pdu_t *)pbuf->payload;
88 memset(result, 0, sizeof(coap_pdu_t));
90 result->max_size = pbuf->tot_len - sizeof(coap_pdu_t);
91 result->length = pbuf->tot_len - sizeof(coap_pdu_t);
100 coap_pdu_init(unsigned char type, unsigned char code, unsigned short id,
101 size_t size, coap_transport_type transport)
108 unsigned int length = 0;
112 length = sizeof(pdu->hdr->coap_hdr_udp_t);
116 length = COAP_TCP_HEADER_NO_FIELD;
119 length = COAP_TCP_HEADER_8_BIT;
122 length = COAP_TCP_HEADER_16_BIT;
125 length = COAP_TCP_HEADER_32_BIT;
129 debug("it has wrong type\n");
133 assert(size <= COAP_MAX_PDU_SIZE);
134 /* Size must be large enough to fit the header. */
135 if (size < length || size > COAP_MAX_PDU_SIZE)
139 /* size must be large enough for hdr */
140 #if defined(WITH_POSIX) || defined(WITH_ARDUINO) || defined(_WIN32)
141 pdu = (coap_pdu_t *) coap_malloc(sizeof(coap_pdu_t) + size);
144 pdu = (coap_pdu_t *)memb_alloc(&pdu_storage);
147 p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
150 u8_t header_error = pbuf_header(p, sizeof(coap_pdu_t));
151 /* we could catch that case and allocate larger memory in advance, but then
152 * again, we'd run into greater trouble with incoming packages anyway */
153 LWIP_ASSERT("CoAP PDU header does not fit in transport header", header_error == 0);
163 coap_pdu_clear(pdu, size, transport, length);
168 pdu->hdr->coap_hdr_udp_t.id = id;
169 pdu->hdr->coap_hdr_udp_t.type = type;
170 pdu->hdr->coap_hdr_udp_t.code = code;
174 pdu->hdr->coap_hdr_tcp_t.header_data[0] = 0;
175 pdu->hdr->coap_hdr_tcp_t.header_data[1] = code;
178 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_8_BIT << 4;
179 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[2] = code;
182 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_16_BIT << 4;
183 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[3] = code;
186 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_32_BIT << 4;
187 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5] = code;
191 debug("it has wrong type\n");
202 coap_new_pdu(coap_transport_type transport, unsigned int size)
207 pdu = coap_pdu_init(0, 0,
208 ntohs(COAP_INVALID_TID),
215 #else /* WITH_CONTIKI */
216 pdu = coap_pdu_init(0, 0, uip_ntohs(COAP_INVALID_TID),
223 #endif /* WITH_CONTIKI */
227 coap_log(LOG_CRIT, "coap_new_pdu: cannot allocate memory for new PDU\n");
232 void coap_delete_pdu(coap_pdu_t *pdu)
234 #if defined(WITH_POSIX) || defined(WITH_ARDUINO)
238 if (pdu != NULL) /* accepting double free as the other implementation accept that too */
239 pbuf_free(pdu->pbuf);
242 memb_free(&pdu_storage, pdu);
247 size_t coap_get_total_message_length(const unsigned char *data, size_t size)
251 debug("received data length is null\n");
255 coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
256 ((unsigned char *)data)[0] >> 4);
257 size_t optPaylaodLen = coap_get_length_from_header((unsigned char *)data,
259 size_t headerLen = coap_get_tcp_header_length((unsigned char *)data);
261 return headerLen + optPaylaodLen;
264 coap_transport_type coap_get_tcp_header_type_from_size(unsigned int size)
266 if (size < COAP_TCP_LENGTH_FIELD_8_BIT)
270 else if (size < COAP_TCP_LENGTH_FIELD_16_BIT)
272 return coap_tcp_8bit;
274 else if (size < COAP_TCP_LENGTH_FIELD_32_BIT)
276 return coap_tcp_16bit;
278 else if (size - COAP_TCP_LENGTH_FIELD_32_BIT < ULONG_MAX)
280 return coap_tcp_32bit;
286 coap_transport_type coap_get_tcp_header_type_from_initbyte(unsigned int length)
288 coap_transport_type type;
291 case COAP_TCP_LENGTH_FIELD_NUM_8_BIT:
292 type = coap_tcp_8bit;
294 case COAP_TCP_LENGTH_FIELD_NUM_16_BIT:
295 type = coap_tcp_16bit;
297 case COAP_TCP_LENGTH_FIELD_NUM_32_BIT:
298 type = coap_tcp_32bit;
306 void coap_add_length(const coap_pdu_t *pdu, coap_transport_type transport, unsigned int length)
313 pdu->hdr->coap_hdr_tcp_t.header_data[0] = length << 4;
316 if (length > COAP_TCP_LENGTH_FIELD_8_BIT)
318 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[1] =
319 length - COAP_TCP_LENGTH_FIELD_8_BIT;
323 if (length > COAP_TCP_LENGTH_FIELD_16_BIT)
325 unsigned int total_length = length - COAP_TCP_LENGTH_FIELD_16_BIT;
326 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[1] = (total_length >> 8) & 0x0000ff;
327 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[2] = total_length & 0x000000ff;
331 if (length > COAP_TCP_LENGTH_FIELD_32_BIT)
333 unsigned int total_length = length - COAP_TCP_LENGTH_FIELD_32_BIT;
334 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[1] = total_length >> 24;
335 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[2] = (total_length >> 16) & 0x00ff;
336 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[3] = (total_length >> 8) & 0x0000ff;
337 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[4] = total_length & 0x000000ff;
341 debug("it has wrong type\n");
345 unsigned int coap_get_length_from_header(const unsigned char *header, coap_transport_type transport)
349 unsigned int length = 0;
350 unsigned int length_field_data = 0;
354 length = header[0] >> 4;
357 length = header[1] + COAP_TCP_LENGTH_FIELD_8_BIT;
360 length_field_data = (header[1] << 8 | header[2]);
361 length = length_field_data + COAP_TCP_LENGTH_FIELD_16_BIT;
364 length_field_data = header[1] << 24 | header[2] << 16 | header[3] << 8 | header[4];
365 length = length_field_data + COAP_TCP_LENGTH_FIELD_32_BIT;
368 debug("it has wrong type\n");
374 unsigned int coap_get_length(const coap_pdu_t *pdu, coap_transport_type transport)
378 unsigned int length = 0;
379 unsigned int length_field_data = 0;
383 length = pdu->hdr->coap_hdr_tcp_t.header_data[0] >> 4;
386 length = pdu->hdr->coap_hdr_tcp_8bit_t.header_data[1] + COAP_TCP_LENGTH_FIELD_8_BIT;
390 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[1] << 8 |
391 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[2];
392 length = length_field_data + COAP_TCP_LENGTH_FIELD_16_BIT;
396 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[1] << 24 |
397 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[2] << 16 |
398 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[3] << 8 |
399 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[4];
400 length = length_field_data + COAP_TCP_LENGTH_FIELD_32_BIT;
403 debug("it has wrong type\n");
409 unsigned int coap_get_tcp_header_length(unsigned char *data)
413 unsigned int tokenLength = data[0] & 0x0f;
414 coap_transport_type transport =
415 coap_get_tcp_header_type_from_initbyte(data[0] >> 4);
416 unsigned int length = 0;
418 length = coap_get_tcp_header_length_for_transport(transport) + tokenLength;
422 unsigned int coap_get_tcp_header_length_for_transport(coap_transport_type transport)
424 unsigned int length = 0;
428 length = COAP_TCP_HEADER_NO_FIELD;
430 case coap_tcp_8bit: /* len(4bit) + TKL(4bit) + Len+bytes(1byte) + Code(1byte) */
431 length = COAP_TCP_HEADER_8_BIT;
433 case coap_tcp_16bit: /* len(4bit) + TKL(4bit) + Len+bytes(2byte) + Code(1byte) */
434 length = COAP_TCP_HEADER_16_BIT;
436 case coap_tcp_32bit: /* len(4bit) + TKL(4bit) + Len+bytes(4byte) + Code(1byte) */
437 length = COAP_TCP_HEADER_32_BIT;
440 debug("it has wrong type\n");
446 size_t coap_get_opt_header_length(unsigned short key, size_t length)
448 size_t headerLength = 0;
450 unsigned short optDeltaLength = 0;
451 if (COAP_OPTION_FIELD_8_BIT >= key)
455 else if (COAP_OPTION_FIELD_8_BIT < key && COAP_OPTION_FIELD_16_BIT >= key)
464 size_t optLength = 0;
465 if (COAP_OPTION_FIELD_8_BIT >= length)
469 else if (COAP_OPTION_FIELD_8_BIT < length && COAP_OPTION_FIELD_16_BIT >= length)
473 else if (COAP_OPTION_FIELD_16_BIT < length && COAP_OPTION_FIELD_32_BIT >= length)
479 printf("Error : Reserved for the Payload marker for length");
483 headerLength = length + optDeltaLength + optLength + 1;
490 void coap_add_code(const coap_pdu_t *pdu, coap_transport_type transport, unsigned int code)
497 pdu->hdr->coap_hdr_udp_t.code = COAP_RESPONSE_CODE(code);
501 pdu->hdr->coap_hdr_tcp_t.header_data[1] = COAP_RESPONSE_CODE(code);
504 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[2] = COAP_RESPONSE_CODE(code);
507 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[3] = COAP_RESPONSE_CODE(code);
510 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5] = COAP_RESPONSE_CODE(code);
514 debug("it has wrong type\n");
518 unsigned int coap_get_code(const coap_pdu_t *pdu, coap_transport_type transport)
522 unsigned int code = 0;
526 code = pdu->hdr->coap_hdr_udp_t.code;
530 code = pdu->hdr->coap_hdr_tcp_t.header_data[1];
533 code = pdu->hdr->coap_hdr_tcp_8bit_t.header_data[2];
536 code = pdu->hdr->coap_hdr_tcp_16bit_t.header_data[3];
539 code = pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5];
543 debug("it has wrong type\n");
548 int coap_add_token(coap_pdu_t *pdu, size_t len, const unsigned char *data,
549 coap_transport_type transport)
551 const size_t HEADERLENGTH = len + 4;
552 /* must allow for pdu == NULL as callers may rely on this */
553 if (!pdu || len > 8 || pdu->max_size < HEADERLENGTH)
556 unsigned char* token = NULL;
560 pdu->hdr->coap_hdr_udp_t.token_length = len;
561 token = pdu->hdr->coap_hdr_udp_t.token;
562 pdu->length = HEADERLENGTH;
566 pdu->hdr->coap_hdr_tcp_t.header_data[0] =
567 pdu->hdr->coap_hdr_tcp_t.header_data[0] | len;
568 token = pdu->hdr->coap_hdr_tcp_t.token;
569 pdu->length = len + COAP_TCP_HEADER_NO_FIELD;
572 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[0] =
573 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[0] | len;
574 token = pdu->hdr->coap_hdr_tcp_8bit_t.token;
575 pdu->length = len + COAP_TCP_HEADER_8_BIT;
578 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[0] =
579 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[0] | len;
580 token = pdu->hdr->coap_hdr_tcp_16bit_t.token;
581 pdu->length = len + COAP_TCP_HEADER_16_BIT;
584 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] =
585 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] | len;
586 token = pdu->hdr->coap_hdr_tcp_32bit_t.token;
587 pdu->length = len + COAP_TCP_HEADER_32_BIT;
591 debug("it has wrong type\n");
596 memcpy(token, data, len);
605 void coap_get_token(const coap_hdr_t *pdu_hdr, coap_transport_type transport,
606 unsigned char **token, unsigned int *token_length)
610 assert(token_length);
615 *token_length = pdu_hdr->coap_hdr_udp_t.token_length;
616 *token = (unsigned char *)pdu_hdr->coap_hdr_udp_t.token;
620 *token_length = (pdu_hdr->coap_hdr_tcp_t.header_data[0]) & 0x0f;
621 *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_t.token;
624 *token_length = (pdu_hdr->coap_hdr_tcp_8bit_t.header_data[0]) & 0x0f;
625 *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_8bit_t.token;
628 *token_length = (pdu_hdr->coap_hdr_tcp_16bit_t.header_data[0]) & 0x0f;
629 *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_16bit_t.token;
632 *token_length = (pdu_hdr->coap_hdr_tcp_32bit_t.header_data[0]) & 0x0f;
633 *token = (unsigned char *)pdu_hdr->coap_hdr_tcp_32bit_t.token;
637 debug("it has wrong type\n");
641 /** @FIXME de-duplicate code with coap_add_option_later */
642 size_t coap_add_option(coap_pdu_t *pdu, unsigned short type, unsigned int len,
643 const unsigned char *data, coap_transport_type transport)
651 if (type < pdu->max_delta)
653 warn("coap_add_option: options are not in correct order\n");
661 opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_t) + pdu->length;
664 opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_8bit_t) + pdu->length;
667 opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_16bit_t) + pdu->length;
670 opt = (unsigned char *) &(pdu->hdr->coap_hdr_tcp_32bit_t) + pdu->length;
674 opt = (unsigned char *) &(pdu->hdr->coap_hdr_udp_t) + pdu->length;
678 /* encode option and check length */
679 optsize = coap_opt_encode(opt, pdu->max_size - pdu->length, type - pdu->max_delta, data, len);
683 warn("coap_add_option: cannot add option\n");
689 pdu->max_delta = type;
690 pdu->length += optsize;
696 /** @FIXME de-duplicate code with coap_add_option */
698 coap_add_option_later(coap_pdu_t *pdu, unsigned short type, unsigned int len)
706 if (type < pdu->max_delta)
708 warn("coap_add_option: options are not in correct order\n");
712 opt = (unsigned char *) pdu->hdr + pdu->length;
714 /* encode option and check length */
715 optsize = coap_opt_encode(opt, pdu->max_size - pdu->length, type - pdu->max_delta, NULL, len);
719 warn("coap_add_option: cannot add option\n");
725 pdu->max_delta = type;
726 pdu->length += optsize;
729 return ((unsigned char*) opt) + optsize - len;
732 int coap_add_data(coap_pdu_t *pdu, unsigned int len, const unsigned char *data)
735 assert(pdu->data == NULL);
740 if (pdu->length + len + 1 > pdu->max_size)
742 warn("coap_add_data: cannot add: data too large for PDU\n");
743 assert(pdu->data == NULL);
747 pdu->data = (unsigned char *) pdu->hdr + pdu->length;
748 *pdu->data = COAP_PAYLOAD_START;
751 memcpy(pdu->data, data, len);
752 pdu->length += len + 1;
756 int coap_get_data(const coap_pdu_t *pdu, size_t *len, unsigned char **data)
764 *len = (unsigned char *) pdu->hdr + pdu->length - pdu->data;
768 { /* no data, clear everything */
773 return *data != NULL;
776 #ifndef SHORT_ERROR_RESPONSE
783 /* if you change anything here, make sure, that the longest string does not
784 * exceed COAP_ERROR_PHRASE_LENGTH. */
785 error_desc_t coap_error[] =
787 { COAP_RESPONSE_CODE(65), "2.01 Created" },
788 { COAP_RESPONSE_CODE(66), "2.02 Deleted" },
789 { COAP_RESPONSE_CODE(67), "2.03 Valid" },
790 { COAP_RESPONSE_CODE(68), "2.04 Changed" },
791 { COAP_RESPONSE_CODE(69), "2.05 Content" },
792 { COAP_RESPONSE_CODE(400), "Bad Request" },
793 { COAP_RESPONSE_CODE(401), "Unauthorized" },
794 { COAP_RESPONSE_CODE(402), "Bad Option" },
795 { COAP_RESPONSE_CODE(403), "Forbidden" },
796 { COAP_RESPONSE_CODE(404), "Not Found" },
797 { COAP_RESPONSE_CODE(405), "Method Not Allowed" },
798 { COAP_RESPONSE_CODE(408), "Request Entity Incomplete" },
799 { COAP_RESPONSE_CODE(413), "Request Entity Too Large" },
800 { COAP_RESPONSE_CODE(415), "Unsupported Media Type" },
801 { COAP_RESPONSE_CODE(500), "Internal Server Error" },
802 { COAP_RESPONSE_CODE(501), "Not Implemented" },
803 { COAP_RESPONSE_CODE(502), "Bad Gateway" },
804 { COAP_RESPONSE_CODE(503), "Service Unavailable" },
805 { COAP_RESPONSE_CODE(504), "Gateway Timeout" },
806 { COAP_RESPONSE_CODE(505), "Proxying Not Supported" },
807 { 0, NULL } /* end marker */
811 coap_response_phrase(unsigned char code)
814 for (i = 0; coap_error[i].code; ++i)
816 if (coap_error[i].code == code)
817 return coap_error[i].phrase;
824 * Advances *optp to next option if still in PDU. This function
825 * returns the number of bytes opt has been advanced or @c 0
828 static size_t next_option_safe(coap_opt_t **optp, size_t *length, coap_option_t* option)
830 //coap_option_t option;
836 optsize = coap_opt_parse(*optp, *length, option);
839 assert(optsize <= *length);
848 int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu,
849 coap_transport_type transport)
854 if (pdu->max_size < length)
856 debug("insufficient space to store parsed PDU\n");
857 printf("[COAP] insufficient space to store parsed PDU\n");
861 unsigned int headerSize = 0;
863 if (coap_udp == transport)
865 headerSize = sizeof(pdu->hdr->coap_hdr_udp_t);
870 headerSize = coap_get_tcp_header_length_for_transport(transport);
874 if (length < headerSize)
876 debug("discarded invalid PDU\n");
879 coap_opt_t *opt = NULL;
880 unsigned int tokenLength = 0;
887 for (size_t i = 0 ; i < headerSize ; i++)
889 pdu->hdr->coap_hdr_tcp_t.header_data[i] = data[i];
892 tokenLength = data[0] & 0x0f;
893 opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_t) + 1) + tokenLength;
896 for (size_t i = 0 ; i < headerSize ; i++)
898 pdu->hdr->coap_hdr_tcp_8bit_t.header_data[i] = data[i];
901 tokenLength = data[0] & 0x0f;
902 opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_8bit_t))
903 + tokenLength + COAP_TCP_HEADER_8_BIT;
906 for (size_t i = 0 ; i < headerSize ; i++)
908 pdu->hdr->coap_hdr_tcp_16bit_t.header_data[i] = data[i];
911 tokenLength = data[0] & 0x0f;
912 opt = (unsigned char *) (&(pdu->hdr->coap_hdr_tcp_16bit_t) + 1) + tokenLength;
915 for (size_t i = 0 ; i < headerSize ; i++)
917 pdu->hdr->coap_hdr_tcp_32bit_t.header_data[i] = data[i];
920 tokenLength = data[0] & 0x0f;
921 opt = ((unsigned char *) &(pdu->hdr->coap_hdr_tcp_32bit_t)) +
922 headerSize + tokenLength;
925 printf("it has wrong type\n");
928 pdu->length = length;
930 if (coap_udp == transport)
932 pdu->hdr->coap_hdr_udp_t.version = data[0] >> 6;
933 pdu->hdr->coap_hdr_udp_t.type = (data[0] >> 4) & 0x03;
934 pdu->hdr->coap_hdr_udp_t.token_length = data[0] & 0x0f;
935 pdu->hdr->coap_hdr_udp_t.code = data[1];
938 tokenLength = pdu->hdr->coap_hdr_udp_t.token_length;
941 if (pdu->hdr->coap_hdr_udp_t.code == 0)
943 if (length != headerSize || tokenLength)
945 debug("coap_pdu_parse: empty message is not empty\n");
950 if (length < headerSize + tokenLength || tokenLength > 8)
952 debug("coap_pdu_parse: invalid Token\n");
956 memcpy(&pdu->hdr->coap_hdr_udp_t.id, data + 2, 2);
958 /* Finally calculate beginning of data block and thereby check integrity
959 * of the PDU structure. */
961 /* append data (including the Token) to pdu structure */
962 memcpy(&(pdu->hdr->coap_hdr_udp_t) + 1, data + headerSize, length - headerSize);
964 /* skip header + token */
965 length -= (tokenLength + headerSize);
966 opt = (unsigned char *) (&(pdu->hdr->coap_hdr_udp_t) + 1) + tokenLength;
969 else // common for tcp header setting
973 if (length < headerSize + tokenLength || tokenLength > 8)
975 debug("coap_pdu_parse: invalid Token\n");
978 /* Finally calculate beginning of data block and thereby check integrity
979 * of the PDU structure. */
981 /* append data (including the Token) to pdu structure */
982 memcpy(((unsigned char *) pdu->hdr) + headerSize,
983 data + headerSize, length - headerSize);
985 /* skip header + token */
986 length -= (tokenLength + headerSize);
990 while (length && *opt != COAP_PAYLOAD_START)
992 coap_option_t option;
993 memset(&option, 0, sizeof(coap_option_t));
994 if (!next_option_safe(&opt, (size_t *) &length, &option))
996 debug("coap_pdu_parse: drop\n");
1001 /* end of packet or start marker */
1004 assert(*opt == COAP_PAYLOAD_START);
1010 debug("coap_pdu_parse: message ending in payload start marker\n");
1015 "set data to %p (pdu ends at %p)\n", (unsigned char *)opt,
1016 (unsigned char *)pdu->hdr + pdu->length);
1017 pdu->data = (unsigned char *) opt;
1018 //printf("[COAP] pdu - data : %s\n", pdu->data);