From c77eae61f8232159e9d1e0e23b46f6cfb2ea4b5e Mon Sep 17 00:00:00 2001 From: "jihwan.seo" Date: Wed, 23 Sep 2015 16:59:36 +0900 Subject: [PATCH] [JIRA IOT-738] fixed to calculate message length for option message length in Header is wrong for long option number and value for CoAP over TCP Change-Id: I72452c07e2b5ffe43749cae5c3a4bae6d7c2f3f2 Signed-off-by: jihwan.seo Reviewed-on: https://gerrit.iotivity.org/gerrit/2985 Tested-by: jenkins-iotivity Reviewed-by: Patrick Lankswert --- resource/csdk/connectivity/inc/caprotocolmessage.h | 2 + resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c | 47 ++++++++++++++++++++++ resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h | 13 ++++++ resource/csdk/connectivity/src/caprotocolmessage.c | 31 +++++++++++--- 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/resource/csdk/connectivity/inc/caprotocolmessage.h b/resource/csdk/connectivity/inc/caprotocolmessage.h index c80d87b..1da4209 100644 --- a/resource/csdk/connectivity/inc/caprotocolmessage.h +++ b/resource/csdk/connectivity/inc/caprotocolmessage.h @@ -48,6 +48,8 @@ typedef uint32_t code_t; #define HAVE_TIME_H 1 #endif +static const uint8_t PAYLOAD_MARKER = 1; + /** * generates pdu structure from the given information. * @param[in] code code of the pdu packet. diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c index 857fba5..b5dd712 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c @@ -421,6 +421,53 @@ unsigned int coap_get_tcp_header_length_for_transport(coap_transport_type transp return length; } +size_t coap_get_opt_header_length(unsigned short key, size_t length) +{ + size_t headerLength = 0; + + unsigned short optDeltaLength = 0; + if (COAP_OPTION_FIELD_8_BIT >= key) + { + optDeltaLength = 0; + } + else if (COAP_OPTION_FIELD_8_BIT < key && COAP_OPTION_FIELD_16_BIT >= key) + { + optDeltaLength = 1; + } + else if (COAP_OPTION_FIELD_16_BIT < key && COAP_OPTION_FIELD_32_BIT >= key) + { + optDeltaLength = 2; + } + else + { + printf("Error : Reserved for the Payload marker for Delta"); + return 0; + } + + size_t optLength = 0; + if (COAP_OPTION_FIELD_8_BIT >= length) + { + optLength = 0; + } + else if (COAP_OPTION_FIELD_8_BIT < length && COAP_OPTION_FIELD_16_BIT >= length) + { + optLength = 1; + } + else if (COAP_OPTION_FIELD_16_BIT < length && COAP_OPTION_FIELD_32_BIT >= length) + { + optLength = 2; + } + else + { + printf("Error : Reserved for the Payload marker for length"); + return 0; + } + + headerLength = length + optDeltaLength + optLength + 1; + + return headerLength; +} + #endif void coap_add_code(const coap_pdu_t *pdu, coap_transport_type transport, unsigned int code) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h index 77dd6f6..b8cc1ea 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h @@ -178,6 +178,10 @@ typedef int coap_tid_t; #define COAP_TCP_LENGTH_FIELD_NUM_16_BIT 14 #define COAP_TCP_LENGTH_FIELD_NUM_32_BIT 15 +#define COAP_OPTION_FIELD_8_BIT 12 +#define COAP_OPTION_FIELD_16_BIT 256 +#define COAP_OPTION_FIELD_32_BIT 65536 + typedef enum { coap_udp = 0, @@ -462,6 +466,15 @@ unsigned int coap_get_tcp_header_length(unsigned char *data); * @return header length. */ unsigned int coap_get_tcp_header_length_for_transport(coap_transport_type transport); + +/** + * Get option length. + * + * @param key delta of option + * @param length length of option + * @return total option length + */ +size_t coap_get_opt_header_length(unsigned short key, size_t length); #endif /** diff --git a/resource/csdk/connectivity/src/caprotocolmessage.c b/resource/csdk/connectivity/src/caprotocolmessage.c index e3fbe3c..67dbdba 100644 --- a/resource/csdk/connectivity/src/caprotocolmessage.c +++ b/resource/csdk/connectivity/src/caprotocolmessage.c @@ -295,23 +295,42 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, const CAInfo_t *info, coap_transport_type transport; unsigned int length = COAP_MAX_PDU_SIZE; #ifdef TCP_ADAPTER - unsigned int headerLength = 0; + unsigned int msgLength = 0; if (CA_ADAPTER_TCP == endpoint->adapter) { if (options) { + unsigned short prevOptNumber = 0; for (coap_list_t *opt = options; opt; opt = opt->next) { - headerLength += COAP_OPTION_LENGTH(*(coap_option *) opt->data) + 1; + unsigned short curOptNumber = COAP_OPTION_KEY(*(coap_option *) opt->data); + if (prevOptNumber > curOptNumber) + { + OIC_LOG(ERROR, TAG, "option list is wrong"); + return NULL; + } + + size_t optValueLen = COAP_OPTION_LENGTH(*(coap_option *) opt->data); + size_t optLength = coap_get_opt_header_length(curOptNumber - prevOptNumber, optValueLen); + if (0 == optLength) + { + OIC_LOG(ERROR, TAG, "Reserved for the Payload marker for the option"); + return NULL; + } + msgLength += optLength; + prevOptNumber = curOptNumber; + OIC_LOG_V(DEBUG, TAG, "curOptNumber[%d], prevOptNumber[%d], optValueLen[%d], " + "optLength[%d], msgLength[%d]", + curOptNumber, prevOptNumber, optValueLen, optLength, msgLength); } } if (info->payloadSize > 0) { - headerLength = headerLength + info->payloadSize + 1; + msgLength = msgLength + info->payloadSize + PAYLOAD_MARKER; } - transport = coap_get_tcp_header_type_from_size(headerLength); - length = headerLength + coap_get_tcp_header_length_for_transport(transport) + transport = coap_get_tcp_header_type_from_size(msgLength); + length = msgLength + coap_get_tcp_header_length_for_transport(transport) + info->tokenLength; } else @@ -334,7 +353,7 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, const CAInfo_t *info, #ifdef TCP_ADAPTER if (CA_ADAPTER_TCP == endpoint->adapter) { - coap_add_length(pdu, transport, headerLength); + coap_add_length(pdu, transport, msgLength); } else #endif -- 2.7.4