#include "pdu.h"
coap_opt_t *
-options_start(coap_pdu_t *pdu)
+options_start(coap_pdu_t *pdu, coap_transport_type transport)
{
-
- if (pdu && pdu->hdr
- && (pdu->hdr->token + pdu->hdr->token_length < (unsigned char *) pdu->hdr + pdu->length))
+ if (pdu && pdu->hdr)
{
-
- coap_opt_t *opt = pdu->hdr->token + pdu->hdr->token_length;
- return (*opt == COAP_PAYLOAD_START) ? NULL : opt;
-
+ if (coap_udp == transport && (pdu->hdr->coap_hdr_udp_t.token +
+ pdu->hdr->coap_hdr_udp_t.token_length
+ < (unsigned char *) pdu->hdr + pdu->length))
+ {
+ coap_opt_t *opt = pdu->hdr->coap_hdr_udp_t.token +
+ pdu->hdr->coap_hdr_udp_t.token_length;
+ return (*opt == COAP_PAYLOAD_START) ? NULL : opt;
+ }
+#ifdef WITH_TCP
+ else if(coap_tcp == transport && (pdu->hdr->coap_hdr_tcp_t.token +
+ pdu->hdr->coap_hdr_tcp_t.token_length
+ < (unsigned char *) pdu->hdr + pdu->length))
+ {
+ coap_opt_t *opt = pdu->hdr->coap_hdr_tcp_t.token +
+ pdu->hdr->coap_hdr_tcp_t.token_length;
+ return (*opt == COAP_PAYLOAD_START) ? NULL : opt;
+ }
+#endif
+ return NULL;
}
else
return NULL;
}
coap_opt_iterator_t *
-coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t filter)
+coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi,
+ const coap_opt_filter_t filter, coap_transport_type transport)
{
assert(pdu);
assert(pdu->hdr);
memset(oi, 0, sizeof(coap_opt_iterator_t));
- oi->next_option = (unsigned char *) pdu->hdr + sizeof(coap_hdr_t) + pdu->hdr->token_length;
- if ((unsigned char *) pdu->hdr + pdu->length <= oi->next_option)
+ unsigned int token_length;
+ unsigned int headerSize;
+
+ switch(transport)
{
- oi->bad = 1;
- return NULL;
+#ifdef WITH_TCP
+ case coap_tcp:
+ token_length = pdu->hdr->coap_hdr_tcp_t.token_length;
+ headerSize = COAP_TCP_HEADER_NO_FIELD;
+ break;
+ case coap_tcp_8bit:
+ token_length = pdu->hdr->coap_hdr_tcp_t.token_length;
+ headerSize = COAP_TCP_HEADER_8_BIT;
+ break;
+ case coap_tcp_16bit:
+ token_length = pdu->hdr->coap_hdr_tcp_t.token_length;
+ headerSize = COAP_TCP_HEADER_16_BIT;
+ break;
+ case coap_tcp_32bit:
+ token_length = pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] & 0x0f;
+ headerSize = COAP_TCP_HEADER_32_BIT;
+ break;
+#endif
+ default:
+ token_length = pdu->hdr->coap_hdr_udp_t.token_length;
+ headerSize = sizeof(pdu->hdr->coap_hdr_udp_t);
+ break;
+ }
+
+ oi->next_option = (unsigned char *) pdu->hdr + headerSize + token_length;
+
+ if (coap_udp == transport)
+ {
+ if ((unsigned char *) &(pdu->hdr->coap_hdr_udp_t) + pdu->length <= oi->next_option)
+ {
+ oi->bad = 1;
+ return NULL;
+ }
}
+#ifdef WITH_TCP
+ else
+ {
+ if ((unsigned char *) &(pdu->hdr->coap_hdr_tcp_t) + pdu->length <= oi->next_option)
+ {
+ oi->bad = 1;
+ return NULL;
+ }
+ }
+#endif
- assert((sizeof(coap_hdr_t) + pdu->hdr->token_length) <= pdu->length);
+ assert((headerSize + token_length) <= pdu->length);
- oi->length = pdu->length - (sizeof(coap_hdr_t) + pdu->hdr->token_length);
+ oi->length = pdu->length - (headerSize + token_length);
if (filter)
{
coap_option_filter_clear(f);
coap_option_setb(f, type);
- coap_option_iterator_init(pdu, oi, f);
+ coap_option_iterator_init(pdu, oi, f, coap_udp);
return coap_option_next(oi);
}