public static final int IF_NONE_MATCH_OPTION_ID = 5;
public static final int LOCATION_PATH_OPTION_ID = 8;
public static final int LOCATION_QUERY_OPTION_ID = 20;
+ public static final int ACCEPT_OPTION_ID = 17;
private int mOptionId;
private String mOptionData;
&& optionId != IF_MATCH_OPTION_ID
&& optionId != IF_NONE_MATCH_OPTION_ID
&& optionId != LOCATION_PATH_OPTION_ID
- && optionId != LOCATION_QUERY_OPTION_ID) {
+ && optionId != LOCATION_QUERY_OPTION_ID
+ && optionId != ACCEPT_OPTION_ID) {
throw new InvalidParameterException("Option ID range is invalid");
}
&& COAP_OPTION_BLOCK1 != opt_iter.type && COAP_OPTION_BLOCK2 != opt_iter.type
&& COAP_OPTION_SIZE1 != opt_iter.type && COAP_OPTION_SIZE2 != opt_iter.type
&& COAP_OPTION_CONTENT_FORMAT != opt_iter.type
- && COAP_OPTION_ACCEPT != opt_iter.type
&& COAP_OPTION_CONTENT_VERSION != opt_iter.type
- && COAP_OPTION_ACCEPT_VERSION != opt_iter.type
&& COAP_OPTION_URI_HOST != opt_iter.type && COAP_OPTION_URI_PORT != opt_iter.type
&& COAP_OPTION_ETAG != opt_iter.type && COAP_OPTION_MAXAGE != opt_iter.type
&& COAP_OPTION_PROXY_SCHEME != opt_iter.type)
}
}
- else if (COAP_OPTION_ACCEPT_VERSION == opt_iter.type)
- {
- if (2 == COAP_OPT_LENGTH(option))
- {
- unsigned int decodedVersion = coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option));
- assert(decodedVersion <= UINT16_MAX);
- outInfo->acceptVersion = (uint16_t)decodedVersion;
- }
- else
- {
- OIC_LOG(DEBUG, TAG, "unsupported accept version");
- outInfo->acceptVersion = DEFAULT_VERSION_VALUE;
- }
- }
- else if (COAP_OPTION_ACCEPT == opt_iter.type)
- {
- if (1 == COAP_OPT_LENGTH(option))
- {
- outInfo->acceptFormat = CAConvertFormat((uint8_t)buf[0]);
- }
- else if (2 == COAP_OPT_LENGTH(option))
- {
- unsigned int decodedFormat = coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option));
- assert(decodedFormat <= UINT16_MAX);
- outInfo->acceptFormat = CAConvertFormat((uint16_t)decodedFormat);
- }
- else
- {
- outInfo->acceptFormat = CA_FORMAT_UNSUPPORTED;
- OIC_LOG(DEBUG, TAG, "option has an unsupported accept format");
- }
- }
else if (COAP_OPTION_URI_PORT == opt_iter.type ||
COAP_OPTION_URI_HOST == opt_iter.type ||
COAP_OPTION_ETAG == opt_iter.type ||
{
isProxyRequest = true;
}
+ else if (COAP_OPTION_ACCEPT_VERSION == opt_iter.type)
+ {
+ if (2 == COAP_OPT_LENGTH(option))
+ {
+ unsigned int decodedVersion = coap_decode_var_bytes(COAP_OPT_VALUE(option),
+ COAP_OPT_LENGTH(option));
+ assert(decodedVersion <= UINT16_MAX);
+ outInfo->acceptVersion = (uint16_t) decodedVersion;
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "unsupported accept version");
+ outInfo->acceptVersion = DEFAULT_VERSION_VALUE;
+ }
+ }
+ else if (COAP_OPTION_ACCEPT == opt_iter.type)
+ {
+ if (1 == COAP_OPT_LENGTH(option))
+ {
+ outInfo->acceptFormat = CAConvertFormat((uint8_t) buf[0]);
+ }
+ else if (2 == COAP_OPT_LENGTH(option))
+ {
+ unsigned int decodedFormat = coap_decode_var_bytes(COAP_OPT_VALUE(option),
+ COAP_OPT_LENGTH(option));
+ assert(decodedFormat <= UINT16_MAX);
+ outInfo->acceptFormat = CAConvertFormat((uint16_t) decodedFormat);
+ }
+ else
+ {
+ outInfo->acceptFormat = CA_FORMAT_UNSUPPORTED;
+ OIC_LOG(DEBUG, TAG, "option has an unsupported accept format");
+ }
+ }
if (idx < count)
{
if (bufLength <= sizeof(outInfo->options[0].optionData))
#include "ocpayload.h"
#include "payload_logging.h"
#include "common.h"
+#include "cacommon.h"
#ifdef ROUTING_GATEWAY
/**
{
memset(options, 0, sizeof(OCHeaderOption)* MAX_HEADER_OPTIONS);
size_t numOptions = 0;
- uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- uint16_t optionID = 2048;
+ uint8_t option0[] = { 16, 39 };
+ uint16_t optionID = COAP_OPTION_ACCEPT;
size_t optionDataSize = sizeof(option0);
OCSetHeaderOption(options,
&numOptions,
option0,
optionDataSize);
- uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
- optionID = 3000;
+ uint8_t option1[] = { 0, 8 };
+ optionID = COAP_OPTION_ACCEPT_VERSION;
optionDataSize = sizeof(option1);
OCSetHeaderOption(options,
&numOptions,
#include "ocserver.h"
#include "common.h"
#include "oic_string.h"
+#include "cacommon.h"
#define VERIFY_SUCCESS(op) \
{ \
MAX_HEADER_OPTION_DATA_LENGTH);
}
}
+ // Check on Accept Version option.
+ uint8_t vOptionData[MAX_HEADER_OPTION_DATA_LENGTH];
+ size_t vOptionDataSize = sizeof(vOptionData);
+ uint16_t actualDataSize = 0;
+ OCGetHeaderOption(entityHandlerRequest->rcvdVendorSpecificHeaderOptions,
+ entityHandlerRequest->numRcvdVendorSpecificHeaderOptions,
+ COAP_OPTION_ACCEPT_VERSION, vOptionData, vOptionDataSize, &actualDataSize);
+ if (actualDataSize)
+ {
+ OIC_LOG_V(INFO, TAG, "accept version option exists");
+ OIC_LOG_BUFFER(INFO, TAG, vOptionData, MAX_HEADER_OPTION_DATA_LENGTH);
+ }
+ uint16_t acceptVersion = vOptionData[0]*256 + vOptionData[1];
+ if (OC_SPEC_VERSION_VALUE == acceptVersion)
+ {
+ OIC_LOG_V(INFO, TAG, "accept version equals to default OC_SPEC_VERSION_VALUE.");
+ }
OCHeaderOption* sendOptions = response.sendVendorSpecificHeaderOptions;
size_t numOptions = response.numSendVendorSpecificHeaderOptions;
// Check if the option header has already existed before adding it in.
uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH];
size_t optionDataSize = sizeof(optionData);
- uint16_t actualDataSize = 0;
OCGetHeaderOption(response.sendVendorSpecificHeaderOptions,
response.numSendVendorSpecificHeaderOptions,
2248,
* @param responseInfo CA response info.
*/
static void HandleCAResponses(const CAEndpoint_t* endPoint,
- const CAResponseInfo_t* responseInfo);
+ const CAResponseInfo_t* responseInfo);
/**
* This function will be called back by CA layer when a request is received.
* @param requestInfo CA request info.
*/
static void HandleCARequests(const CAEndpoint_t* endPoint,
- const CARequestInfo_t* requestInfo);
+ const CARequestInfo_t* requestInfo);
/**
* Extract query from a URI.
static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds);
/**
+ * Set Header Option.
+ * @param caHdrOpt Pointer to existing options
+ * @param numOptions Number of existing options.
+ * @param optionID COAP option ID.
+ * @param optionData Option data value.
+ * @param optionDataLength Size of Option data value.
+
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+static OCStackResult SetHeaderOption(CAHeaderOption_t *caHdrOpt, size_t numOptions,
+ uint16_t optionID, void* optionData, size_t optionDataLength);
+
+/**
* Ensure the accept header option is set appropriatly before sending the requests and routing
* header option is updated with destination.
*
}
#endif
+ // TODO: We might need to remove acceptFormat and acceptVersion fields in requestinfo->info
+ // at a later stage to avoid duplication.
uint16_t acceptVersion = OC_SPEC_VERSION_VALUE;
CAPayloadFormat_t acceptFormat = CA_FORMAT_APPLICATION_VND_OCF_CBOR;
// Check settings of version option and content format.
{
if (CA_RETRANSMIT_TIMEOUT == responseInfo->result)
{
+ OIC_LOG(INFO, TAG, "Receiving A Timeout for this token");
OIC_LOG(INFO, TAG, "Calling into application address space");
}
else
}
else
{
- requestInfo.info.numOptions = numOptions;
- if(requestInfo.info.numOptions)
+ // Check if accept format and accept version have been set.
+ uint16_t acceptVersion = OC_SPEC_VERSION_VALUE;
+ uint16_t acceptFormat = COAP_MEDIATYPE_APPLICATION_VND_OCF_CBOR;
+ bool IsAcceptVersionSet = false;
+ bool IsAcceptFormatSet = false;
+ // Check settings of version option and content format.
+ if (numOptions > 0 && options)
{
- requestInfo.info.options =
- (CAHeaderOption_t*) OICCalloc(numOptions, sizeof(CAHeaderOption_t));
- if (NULL == requestInfo.info.options)
+ for (uint8_t i = 0; i < numOptions; i++)
{
- OIC_LOG(ERROR, TAG, "Calloc failed");
- result = OC_STACK_NO_MEMORY;
- goto exit;
+ if (COAP_OPTION_ACCEPT_VERSION == options[i].optionID)
+ {
+ acceptVersion = *(uint16_t*) options[i].optionData;
+ IsAcceptVersionSet = true;
+ }
+ else if (COAP_OPTION_ACCEPT == options[i].optionID)
+ {
+ if (1 == options[i].optionLength)
+ {
+ acceptFormat = CAConvertFormat(*(uint8_t*)options[i].optionData);
+ IsAcceptFormatSet = true;
+ }
+ else if (2 == options[i].optionLength)
+ {
+ acceptFormat = CAConvertFormat(*(uint16_t*)options[i].optionData);
+ IsAcceptFormatSet = true;
+ }
+ else
+ {
+ acceptFormat = CA_FORMAT_UNSUPPORTED;
+ IsAcceptFormatSet = true;
+ OIC_LOG_V(DEBUG, TAG, "option has an unsupported format");
+ }
+ }
}
- memcpy(requestInfo.info.options, (CAHeaderOption_t*)options,
- numOptions * sizeof(CAHeaderOption_t));
+ }
+
+ if (!IsAcceptVersionSet && !IsAcceptFormatSet)
+ {
+ requestInfo.info.numOptions = numOptions + 2;
+ }
+ else if ((IsAcceptFormatSet &&
+ CA_FORMAT_APPLICATION_VND_OCF_CBOR == acceptFormat &&
+ !IsAcceptVersionSet) || (IsAcceptVersionSet && !IsAcceptFormatSet))
+ {
+ requestInfo.info.numOptions = numOptions + 1;
+ }
+ else
+ {
+ requestInfo.info.numOptions = numOptions;
+ }
+
+ requestInfo.info.options = (CAHeaderOption_t*) OICCalloc(requestInfo.info.numOptions,
+ sizeof(CAHeaderOption_t));
+ if (NULL == requestInfo.info.options)
+ {
+ OIC_LOG(ERROR, TAG, "Calloc failed");
+ result = OC_STACK_NO_MEMORY;
+ goto exit;
+ }
+ memcpy(requestInfo.info.options, (CAHeaderOption_t*) options,
+ numOptions * sizeof(CAHeaderOption_t));
+
+ if (!IsAcceptVersionSet && !IsAcceptFormatSet)
+ {
+ // Append accept format and accept version to the options.
+ SetHeaderOption(requestInfo.info.options, numOptions, CA_OPTION_ACCEPT, &acceptFormat,
+ sizeof(uint16_t));
+ SetHeaderOption(requestInfo.info.options, numOptions + 1, CA_OPTION_ACCEPT_VERSION,
+ &acceptVersion, sizeof(uint16_t));
+ }
+ else if (IsAcceptFormatSet && CA_FORMAT_APPLICATION_VND_OCF_CBOR == acceptFormat
+ && !IsAcceptVersionSet)
+ {
+ // Append accept version to the options.
+ SetHeaderOption(requestInfo.info.options, numOptions, CA_OPTION_ACCEPT_VERSION,
+ &acceptVersion, sizeof(uint16_t));
+ }
+ else if (IsAcceptVersionSet && OC_SPEC_VERSION_VALUE <= acceptVersion && !IsAcceptFormatSet)
+ {
+ // Append accept format to the options.
+ SetHeaderOption(requestInfo.info.options, numOptions, CA_OPTION_ACCEPT, &acceptFormat,
+ sizeof(uint16_t));
}
}
return NULL;
}
+static OCStackResult SetHeaderOption(CAHeaderOption_t *caHdrOpt, size_t numOptions,
+ uint16_t optionID, void* optionData, size_t optionDataLength)
+{
+ if (!caHdrOpt)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (!optionData)
+ {
+ OIC_LOG (INFO, TAG, "optionData are NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ caHdrOpt[numOptions].protocolID = CA_COAP_ID;
+ caHdrOpt[numOptions].optionID = optionID;
+ caHdrOpt[numOptions].optionLength =
+ (optionDataLength < MAX_HEADER_OPTION_DATA_LENGTH) ?
+ (uint16_t) optionDataLength : MAX_HEADER_OPTION_DATA_LENGTH;
+ memcpy(caHdrOpt[numOptions].optionData, (const void*) optionData,
+ caHdrOpt[numOptions].optionLength);
+
+ return OC_STACK_OK;
+}
+
OCStackResult OCSetHeaderOption(OCHeaderOption* ocHdrOpt, size_t* numOptions, uint16_t optionID,
void* optionData, size_t optionDataLength)
{
{
if (optionDataLength >= ocHdrOpt->optionLength)
{
- memcpy(optionData, ocHdrOpt->optionData, ocHdrOpt->optionLength);
- *receivedDataLength = ocHdrOpt->optionLength;
+ memcpy(optionData, ocHdrOpt[i].optionData, ocHdrOpt[i].optionLength);
+ *receivedDataLength = ocHdrOpt[i].optionLength;
return OC_STACK_OK;
}
else
* NOTE: HeaderOptionID is an unsigned integer value which MUST be within
* range of 2048 to 3000 inclusive of lower and upper bound
* except for If-Match with empty(num : 1), If-None-Match(num : 5),
- * Location-Path(num : 8), Location-Query(num : 20) option.
+ * Location-Path(num : 8), Location-Query(num : 20), Accept(num : 17) option.
* HeaderOptions instance creation fails if above condition is not satisfied.
*/
const uint16_t MIN_HEADER_OPTIONID = 2048;
const uint16_t IF_NONE_MATCH_OPTION_ID = 5;
const uint16_t LOCATION_PATH_OPTION_ID = 8;
const uint16_t LOCATION_QUERY_OPTION_ID = 20;
+ const uint16_t ACCEPT_OPTION_ID = 17;
class OCHeaderOption
{
&& optionID != IF_MATCH_OPTION_ID
&& optionID != IF_NONE_MATCH_OPTION_ID
&& optionID != LOCATION_PATH_OPTION_ID
- && optionID != LOCATION_QUERY_OPTION_ID)
+ && optionID != LOCATION_QUERY_OPTION_ID
+ && optionID != ACCEPT_OPTION_ID)
{
throw OCException(OC::Exception::OPTION_ID_RANGE_INVALID);
}
if (HeaderOption::IF_MATCH_OPTION_ID != i
&& HeaderOption::IF_NONE_MATCH_OPTION_ID != i
&& HeaderOption::LOCATION_PATH_OPTION_ID != i
- && HeaderOption::LOCATION_QUERY_OPTION_ID != i)
+ && HeaderOption::LOCATION_QUERY_OPTION_ID != i
+ && HeaderOption::ACCEPT_OPTION_ID != i)
{
ASSERT_THROW(
HeaderOption::OCHeaderOption(i,""),