#define CA_OPTION_LOCATION_QUERY 20
/**
+* TODO: Move these COAP defines to CoAP lib once approved.
+*/
+#define COAP_OPTION_ACCEPT_VERSION 2049
+#define COAP_OPTION_CONTENT_VERSION 2053
+#define COAP_MEDIATYPE_APPLICATION_VND_OCF_CBOR 10000 // application/vnd.ocf+cbor
+
+#define CA_OPTION_ACCEPT_VERSION 2049
+#define CA_OPTION_CONTENT_VERSION 2053
+
+#define DEFAULT_ACCEPT_VERSION_VALUE 2048 // OCF version 1.0.0
+#define DEFAULT_CONTENT_VERSION_VALUE 2048 // OCF version 1.0.0
+
+/**
* Payload information from resource model.
*/
typedef uint8_t *CAPayload_t;
CA_FORMAT_APPLICATION_EXI,
CA_FORMAT_APPLICATION_JSON,
CA_FORMAT_APPLICATION_CBOR,
+ CA_FORMAT_APPLICATION_VND_OCF_CBOR,
CA_FORMAT_UNSUPPORTED
} CAPayloadFormat_t;
size_t payloadSize; /**< size in bytes of the payload */
CAPayloadFormat_t payloadFormat; /**< encoding format of the request payload */
CAPayloadFormat_t acceptFormat; /**< accept format for the response payload */
+ uint16_t payloadVersion; /**< version of the payload */
+ uint16_t acceptVersion; /**< expected version for the response payload */
CAURI_t resourceUri; /**< Resource URI information **/
CARemoteId_t identity; /**< endpoint identity */
CADataType_t dataType; /**< data type */
}
clone->payloadFormat = info->payloadFormat;
clone->acceptFormat = info->acceptFormat;
+ clone->payloadVersion = info->payloadVersion;
+ clone->acceptVersion = info->acceptVersion;
if (info->resourceUri)
{
CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t *info, coap_list_t **optlist);
/**
+ * Helper to parse content format and accept format header options
+ * and populate the supplied options list.
+ *
+ * @param[in] format content or accept format.
+ * @param[in] formatOption CoAP format header option.
+ * @param[in] versionOption CoAP version header option.
+ * @param[in] version value of version.
+ * @param[out] optlist options information.
+ * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h).
+ */
+
+CAResult_t CAParsePayloadFormatHeadOption(CAPayloadFormat_t format, uint16_t formatOption,
+ uint16_t versionOption, uint16_t version, coap_list_t **optlist);
+
+/**
* creates option node from key length and data.
* @param[in] key key for the that needs to be sent.
* @param[in] length length of the data that needs to be sent.
* @param[in] format coap format code.
* @return format.
*/
-CAPayloadFormat_t CAConvertFormat(uint8_t format);
+CAPayloadFormat_t CAConvertFormat(uint16_t format);
#ifdef WITH_TCP
/**
// insert one extra header with the payload format if applicable.
if (CA_FORMAT_UNDEFINED != info->payloadFormat)
{
- coap_list_t* node = NULL;
- uint8_t buf[CA_ENCODE_BUFFER_SIZE] = {0};
- switch (info->payloadFormat)
- {
- case CA_FORMAT_APPLICATION_CBOR:
- node = CACreateNewOptionNode(
- COAP_OPTION_CONTENT_FORMAT,
- coap_encode_var_bytes(buf, (unsigned short)COAP_MEDIATYPE_APPLICATION_CBOR),
- (char *)buf);
- break;
- default:
- OIC_LOG_V(ERROR, TAG, "Content format option:[%d] not supported", info->payloadFormat);
- }
- if (!node)
- {
- OIC_LOG(ERROR, TAG, "Content format option not created");
- return CA_STATUS_INVALID_PARAM;
- }
- int ret = coap_insert(optlist, node, CAOrderOpts);
- if (ret <= 0)
- {
- coap_delete(node);
- OIC_LOG(ERROR, TAG, "Content format option not inserted in header");
- return CA_STATUS_INVALID_PARAM;
- }
+ CAParsePayloadFormatHeadOption(info->payloadFormat, COAP_OPTION_CONTENT_FORMAT, COAP_OPTION_CONTENT_VERSION, info->payloadVersion, optlist);
}
+
if (CA_FORMAT_UNDEFINED != info->acceptFormat)
{
- coap_list_t* node = NULL;
- uint8_t buf[CA_ENCODE_BUFFER_SIZE] = {0};
- switch (info->acceptFormat)
+ CAParsePayloadFormatHeadOption(info->acceptFormat, COAP_OPTION_ACCEPT, info->acceptVersion, COAP_OPTION_ACCEPT_VERSION, optlist);
+ }
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAParsePayloadFormatHeadOption(CAPayloadFormat_t format, uint16_t formatOption,
+ uint16_t versionOption, uint16_t version, coap_list_t **optlist)
+{
+ coap_list_t* encodeNode = NULL;
+ coap_list_t* versionNode = NULL;
+ uint8_t encodeBuf[CA_ENCODE_BUFFER_SIZE] = { 0 };
+ uint8_t versionBuf[CA_ENCODE_BUFFER_SIZE] = { 0 };
+
+ switch (format)
+ {
+ case CA_FORMAT_APPLICATION_CBOR:
+ encodeNode = CACreateNewOptionNode(formatOption,
+ coap_encode_var_bytes(encodeBuf,
+ (unsigned short) COAP_MEDIATYPE_APPLICATION_CBOR), (char *) encodeBuf);
+ break;
+ case CA_FORMAT_APPLICATION_VND_OCF_CBOR:
+ encodeNode = CACreateNewOptionNode(formatOption,
+ coap_encode_var_bytes(encodeBuf,
+ (unsigned short) COAP_MEDIATYPE_APPLICATION_VND_OCF_CBOR),
+ (char *) encodeBuf);
+ // Include payload version information for this format.
+ versionNode = CACreateNewOptionNode(versionOption,
+ coap_encode_var_bytes(versionBuf, version), (char *) versionBuf);
+ break;
+ default:
+ OIC_LOG_V(ERROR, TAG, "Format option:[%d] not supported", format);
+ }
+ if (!encodeNode)
+ {
+ OIC_LOG(ERROR, TAG, "Format option not created");
+ return CA_STATUS_INVALID_PARAM;
+ }
+ int ret = coap_insert(optlist, encodeNode, CAOrderOpts);
+ if (0 >= ret)
+ {
+ coap_delete(encodeNode);
+ OIC_LOG(ERROR, TAG, "Format option not inserted in header");
+ if (CA_FORMAT_APPLICATION_VND_OCF_CBOR == format && versionNode)
{
- case CA_FORMAT_APPLICATION_CBOR:
- node = CACreateNewOptionNode(
- COAP_OPTION_ACCEPT,
- coap_encode_var_bytes(buf, (unsigned short)COAP_MEDIATYPE_APPLICATION_CBOR),
- (char *)buf);
- break;
- default:
- OIC_LOG_V(ERROR, TAG, "Accept format option:[%d] not supported", info->acceptFormat);
+ coap_delete(versionNode);
}
- if (!node)
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ if (CA_FORMAT_APPLICATION_VND_OCF_CBOR == format)
+ {
+ if (!versionNode)
{
- OIC_LOG(ERROR, TAG, "Accept format option not created");
+ OIC_LOG(ERROR, TAG, "Version option not created");
+ coap_delete(encodeNode);
return CA_STATUS_INVALID_PARAM;
}
- int ret = coap_insert(optlist, node, CAOrderOpts);
- if (ret <= 0)
+ else
{
- coap_delete(node);
- OIC_LOG(ERROR, TAG, "Accept format option not inserted in header");
- return CA_STATUS_INVALID_PARAM;
+ ret = coap_insert(optlist, versionNode, CAOrderOpts);
+ if (0 >= ret)
+ {
+ coap_delete(versionNode);
+ coap_delete(encodeNode);
+ OIC_LOG(ERROR, TAG, "Content version option not inserted in header");
+ return CA_STATUS_INVALID_PARAM;
+ }
}
}
-
return CA_STATUS_OK;
}
&& 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)
{
outInfo->payloadFormat = CAConvertFormat((uint8_t)buf[0]);
}
+ else if (2 == COAP_OPT_LENGTH(option))
+ {
+ outInfo->payloadFormat = CAConvertFormat(
+ coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option)));
+ }
else
{
outInfo->payloadFormat = CA_FORMAT_UNSUPPORTED;
- OIC_LOG_V(DEBUG, TAG, "option[%d] has an unsupported format [%d]",
- opt_iter.type, (uint8_t)buf[0]);
+ OIC_LOG_V(DEBUG, TAG, "option has an unsupported format");
+ }
+ }
+ else if (COAP_OPTION_CONTENT_VERSION == opt_iter.type)
+ {
+ if (2 == COAP_OPT_LENGTH(option))
+ {
+ outInfo->payloadVersion = coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option));
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, TAG, "unsupported content version");
+ outInfo->payloadVersion = DEFAULT_CONTENT_VERSION_VALUE;
+
+ }
+ }
+ else if (COAP_OPTION_ACCEPT_VERSION == opt_iter.type)
+ {
+ if (2 == COAP_OPT_LENGTH(option))
+ {
+ outInfo->acceptVersion = coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option));
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, TAG, "unsupported accept version");
+ outInfo->acceptVersion = DEFAULT_ACCEPT_VERSION_VALUE;
}
}
else if (COAP_OPTION_ACCEPT == opt_iter.type)
{
outInfo->acceptFormat = CAConvertFormat((uint8_t)buf[0]);
}
+ else if (2 == COAP_OPT_LENGTH(option))
+ {
+ outInfo->acceptFormat = CAConvertFormat(
+ coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option)));
+ }
else
{
outInfo->acceptFormat = CA_FORMAT_UNSUPPORTED;
+ OIC_LOG_V(DEBUG, TAG, "option has an unsupported accept format");
}
- OIC_LOG_V(DEBUG, TAG, "option[%d] has an unsupported format [%d]",
- opt_iter.type, (uint8_t)buf[0]);
}
else if (COAP_OPTION_URI_PORT == opt_iter.type ||
COAP_OPTION_URI_HOST == opt_iter.type ||
return (CAResponseResult_t) CA_RESPONSE_CODE(hdr->code);
}
-CAPayloadFormat_t CAConvertFormat(uint8_t format)
+CAPayloadFormat_t CAConvertFormat(uint16_t format)
{
switch (format)
{
return CA_FORMAT_APPLICATION_JSON;
case COAP_MEDIATYPE_APPLICATION_CBOR:
return CA_FORMAT_APPLICATION_CBOR;
+ case COAP_MEDIATYPE_APPLICATION_VND_OCF_CBOR:
+ return CA_FORMAT_APPLICATION_VND_OCF_CBOR;
default:
return CA_FORMAT_UNSUPPORTED;
}
std::string dataStr; // data could be binary... for testing we'll use str
};
-
-
/**
* Helper to validate the state of CoAP URI parsing.
*
coap_delete_list(options);
coap_delete_pdu(pdu);
}
+
+TEST(CAProtocolMessage, CAGetInfoFromPDU)
+{
+ CAEndpoint_t tempRep;
+ memset(&tempRep, 0, sizeof(CAEndpoint_t));
+ tempRep.flags = CA_DEFAULT_FLAGS;
+ tempRep.adapter = CA_ADAPTER_IP;
+ tempRep.port = 5683;
+
+ coap_pdu_t *pdu = NULL;
+ coap_list_t *options = NULL;
+ coap_transport_t transport = COAP_UDP;
+
+ CAInfo_t inData;
+ memset(&inData, 0, sizeof(CAInfo_t));
+ inData.token = (CAToken_t)"token";
+ inData.tokenLength = strlen(inData.token);
+ inData.type = CA_MSG_NONCONFIRM;
+ inData.payload = (CAPayload_t) "requestPayload";
+ inData.payloadSize = sizeof(inData.payload);;
+ inData.payloadFormat = CA_FORMAT_APPLICATION_VND_OCF_CBOR;
+ inData.acceptFormat = CA_FORMAT_APPLICATION_VND_OCF_CBOR;
+ inData.payloadVersion = 2048;
+ inData.acceptVersion = 2048;
+
+ pdu = CAGeneratePDU(CA_GET, &inData, &tempRep, &options, &transport);
+
+ uint32_t code = CA_NOT_FOUND;
+ CAInfo_t outData;
+ memset(&outData, 0, sizeof(CAInfo_t));
+
+ EXPECT_EQ(CA_STATUS_OK, CAGetInfoFromPDU(pdu, &tempRep, &code, &outData));
+ coap_delete_list(options);
+ coap_delete_pdu(pdu);
+}
/** Device specification version.*/
#define OC_SPEC_VERSION "core.1.1.0"
+/** Integer value of spec version.*/
+#define OC_SPEC_VERSION_VALUE 0
+
/** Device Data Model version.*/
#define OC_DATA_MODEL_VERSION "res.1.1.0,sh.1.1.0"
typedef enum
{
OC_FORMAT_CBOR,
+ OC_FORMAT_VND_OCF_CBOR,
OC_FORMAT_JSON,
OC_FORMAT_UNDEFINED,
OC_FORMAT_UNSUPPORTED,
(const char *)(request->query),
*obsID, request->requestToken, request->tokenLength,
(OCResource *)g_gateWayHandle, request->qos, OC_FORMAT_CBOR,
- &request->devAddr);
+ OC_SPEC_VERSION_VALUE, &request->devAddr);
OIC_LOG(DEBUG, TAG, "RMAddObserverToStack OUT");
return result;
}
/** requested payload encoding format. */
OCPayloadFormat acceptFormat;
+ /** requested payload content version. */
+ uint16_t acceptVersion;
+
} ResourceObserver;
#ifdef WITH_PRESENCE
* @param tokenLength Length of token.
* @param resHandle Resource handle.
* @param qos Quality of service of observation.
+ * @param acceptFormat Accept payload format.
+ * @param acceptVersion Accept payload version.
* @param devAddr Device address.
*
* @return ::OC_STACK_OK on success, some other value upon failure.
OCResource *resHandle,
OCQualityOfService qos,
OCPayloadFormat acceptFormat,
+ uint16_t acceptVersion,
const OCDevAddr *devAddr);
/**
/** Accept format retrieved from the received request PDU. */
OCPayloadFormat acceptFormat;
+ /** Accept version retrieved from the received request PDU. */
+ uint16_t acceptVersion;
+
/** resourceUrl will be filled in occoap using the path options in received request PDU.*/
char resourceUrl[MAX_URI_LENGTH];
* @param resourceUrl URL of resource.
* @param reqTotalSize Total size of the request.
* @param acceptFormat The format requested for the payload encoding.
+ * @param acceptVersion The content version requested for the payload encoding.
* @param devAddr Device Address.
*
* @return
uint8_t tokenLength,
char * resourceUrl, size_t reqTotalSize,
OCPayloadFormat acceptFormat,
+ uint16_t acceptVersion,
const OCDevAddr *devAddr);
/**
* @param entityHandlerRequest pointer to the OCEntityHandlerRequest struct that is created.
* @param request Request handle.
* @param method RESTful method.
+ * @param endpoint Device address of the requester.
* @param resource Resource handle.
* @param queryBuf Resource query of request.
- * @param bufReqPayload JSON payload of request.
+ * @param payloadType Type of payload.
+ * @param payload cbor value of the payload.
+ * @param payloadSize Size of payload.
* @param numVendorOptions Number of vendor options.
* @param vendorOptions Vendor options.
* @param observeAction Observe action flag.
* @param observeID Observe ID.
+ * @param messageID Message ID.
*
* @return
* OCStackResult
/** the requested payload format. */
OCPayloadFormat acceptFormat;
+ /** the requested payload format. */
+ uint16_t acceptVersion;
+
/** resourceUrl will be filled in occoap using the path options in received request PDU.*/
char resourceUrl[MAX_URI_LENGTH];
return "OC_STACK_NO_OBSERVERS";
case OC_STACK_UNAUTHORIZED_REQ:
return "OC_STACK_UNAUTHORIZED_REQ";
+ case OC_STACK_NOT_ACCEPTABLE:
+ return "OC_STACK_NOT_ACCEPTABLE";
#ifdef WITH_PRESENCE
case OC_STACK_PRESENCE_STOPPED:
return "OC_STACK_PRESENCE_STOPPED";
{
OIC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
+ if (OC_STACK_NOT_ACCEPTABLE == clientResponse->result)
+ {
+ // Re-initiate discovery with OIC format. This is applicable for the case that
+ // a OCF 1.x client speaks to a OIC 1.1 server.
+ InitDiscovery(OC_LOW_QOS, 1);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
std::string connectionType = getConnectivityType (clientResponse->connType);
OIC_LOG_V(INFO, TAG, "Discovered on %s", connectionType.c_str());
OIC_LOG_V(INFO, TAG,
return ret;
}
-int InitDiscovery(OCQualityOfService qos)
+int InitDiscovery(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions)
{
OCStackResult ret;
OCCallbackData cbData;
cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
cbData.cd = NULL;
- ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
- (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
- &cbData, NULL, 0);
+ if (withVendorSpecificHeaderOptions)
+ {
+ OCHeaderOption options[MAX_HEADER_OPTIONS];
+ memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
+ size_t numOptions = 0;
+
+ uint8_t option0[] = {0};
+ uint16_t optionID = 2049;
+ size_t optionDataSize = sizeof(option0);
+ OCSetHeaderOption(options, &numOptions, optionID, option0, optionDataSize);
+
+ uint8_t option1[] = {0};
+ optionID = 2053;
+ optionDataSize = sizeof(option1);
+ OCSetHeaderOption(options, &numOptions, optionID, option1, optionDataSize);
+
+ ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+ &cbData, options, 2);
+ }
+ else
+ {
+ ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+ &cbData, NULL, 0);
+ }
if (ret != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "OCStack resource error");
}
else
{
- InitDiscovery(OC_LOW_QOS);
+ InitDiscovery(OC_LOW_QOS, 0);
}
// Break from loop with Ctrl+C
int InitGetRequest(OCQualityOfService qos);
int InitDeviceDiscovery(OCQualityOfService qos);
int InitPlatformDiscovery(OCQualityOfService qos);
-int InitDiscovery(OCQualityOfService qos);
+int InitDiscovery(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions);
int InitGetRequestWithCoap(OCDiscoveryPayload* dis, bool isUdp);
int InitIntrospection(OCDiscoveryPayload* dis);
observer->query, NULL, NULL,
observer->token, observer->tokenLength,
observer->resUri, 0, observer->acceptFormat,
- &observer->devAddr);
+ observer->acceptVersion, &observer->devAddr);
if (request)
{
NULL, NULL,
resourceObserver->token, resourceObserver->tokenLength,
resourceObserver->resUri, 0, resourceObserver->acceptFormat,
- &resourceObserver->devAddr);
+ resourceObserver->acceptVersion, &resourceObserver->devAddr);
if (result == OC_STACK_OK)
{
0, resource->sequenceNum, qos, observer->query,
NULL, NULL, observer->token, observer->tokenLength,
observer->resUri, 0, observer->acceptFormat,
- &observer->devAddr);
+ observer->acceptVersion, &observer->devAddr);
if (request)
{
OCResource *resHandle,
OCQualityOfService qos,
OCPayloadFormat acceptFormat,
+ uint16_t acceptVersion,
const OCDevAddr *devAddr)
{
// Check if resource exists and is observable.
obsNode->qos = qos;
obsNode->acceptFormat = acceptFormat;
+ obsNode->acceptVersion = acceptVersion;
if (query)
{
obsNode->query = OICStrdup(query);
(const char *)(request->query),
ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
resource, request->qos, request->acceptFormat,
- &request->devAddr);
+ request->acceptVersion, &request->devAddr);
if(result == OC_STACK_OK)
{
OCHeaderOption * rcvdVendorSpecificHeaderOptions,
uint8_t * payload, CAToken_t requestToken, uint8_t tokenLength,
char * resourceUrl, size_t reqTotalSize, OCPayloadFormat acceptFormat,
- const OCDevAddr *devAddr)
+ uint16_t acceptVersion, const OCDevAddr *devAddr)
{
if (!request)
{
serverRequest->observeResult = OC_STACK_ERROR;
serverRequest->qos = qos;
serverRequest->acceptFormat = acceptFormat;
+ serverRequest->acceptVersion = acceptVersion;
serverRequest->ehResponseHandler = HandleSingleResponse;
serverRequest->numResponses = 1;
case OC_FORMAT_UNDEFINED:
// No preference set by the client, so default to CBOR then
case OC_FORMAT_CBOR:
+ case OC_FORMAT_VND_OCF_CBOR:
if((result = OCConvertPayload(ehResponse->payload, &responseInfo.info.payload,
&responseInfo.info.payloadSize))
!= OC_STACK_OK)
// Add CONTENT_FORMAT OPT if payload exist
if (responseInfo.info.payloadSize > 0)
{
- responseInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR;
+ if (OC_FORMAT_VND_OCF_CBOR == serverRequest->acceptFormat)
+ {
+ responseInfo.info.payloadFormat = CA_FORMAT_APPLICATION_VND_OCF_CBOR;
+ if (!serverRequest->acceptVersion)
+ {
+ serverRequest->acceptVersion = DEFAULT_ACCEPT_VERSION_VALUE;
+ }
+ // Add CONTENT_VERSION OPT for this format.
+ responseInfo.info.payloadVersion = serverRequest->acceptVersion;
+ }
+ else
+ {
+ responseInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR;
+ }
}
break;
default:
}
#endif
- // OC stack prefer CBOR encoded payloads.
- requestInfo->info.acceptFormat = CA_FORMAT_APPLICATION_CBOR;
+ uint16_t acceptVersion = OC_SPEC_VERSION_VALUE;
+ // From OCF onwards, check settings of version option.
+ if (DEFAULT_ACCEPT_VERSION_VALUE <= acceptVersion)
+ {
+ if (requestInfo->info.numOptions > 0 && requestInfo->info.options)
+ {
+ for (uint8_t i = 0; i < requestInfo->info.numOptions; i++)
+ {
+ if (COAP_OPTION_ACCEPT_VERSION == requestInfo->info.options[i].protocolID)
+ {
+ acceptVersion = requestInfo->info.options[i].optionData[0];
+ break;
+ }
+ else if (COAP_OPTION_CONTENT_VERSION == requestInfo->info.options[i].protocolID)
+ {
+ acceptVersion = requestInfo->info.options[i].optionData[0];
+ break;
+ }
+ }
+ }
+ }
+
+ if (DEFAULT_CONTENT_VERSION_VALUE <= acceptVersion)
+ {
+ requestInfo->info.acceptFormat = CA_FORMAT_APPLICATION_VND_OCF_CBOR;
+ requestInfo->info.acceptVersion = acceptVersion;
+ }
+ else
+ {
+ requestInfo->info.acceptFormat = CA_FORMAT_APPLICATION_CBOR;
+ }
+
CAResult_t result = CASendRequest(object, requestInfo);
if(CA_STATUS_OK != result)
{
// app that at least the request was received at the server?
}
}
- else if(responseInfo->result == CA_RETRANSMIT_TIMEOUT)
+ else if (CA_RETRANSMIT_TIMEOUT == responseInfo->result
+ || CA_NOT_ACCEPTABLE == responseInfo->result)
{
- OIC_LOG(INFO, TAG, "Receiving A Timeout for this token");
- OIC_LOG(INFO, TAG, "Calling into application address space");
+ 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
+ {
+ OIC_LOG(INFO, TAG, "Server doesn't support the requested payload format");
+ OIC_LOG(INFO, TAG, "Calling into application address space");
+ }
OCClientResponse *response = NULL;
protocolRequest->payload, protocolRequest->requestToken,
protocolRequest->tokenLength, protocolRequest->resourceUrl,
protocolRequest->reqTotalSize, protocolRequest->acceptFormat,
- &protocolRequest->devAddr);
+ protocolRequest->acceptVersion, &protocolRequest->devAddr);
if (OC_STACK_OK != result)
{
OIC_LOG(ERROR, TAG, "Error adding server request");
case CA_FORMAT_APPLICATION_CBOR:
serverRequest.acceptFormat = OC_FORMAT_CBOR;
break;
+ case CA_FORMAT_APPLICATION_VND_OCF_CBOR:
+ serverRequest.acceptFormat = OC_FORMAT_VND_OCF_CBOR;
+ break;
case CA_FORMAT_UNDEFINED:
serverRequest.acceptFormat = OC_FORMAT_UNDEFINED;
break;
CopyDevAddrToEndpoint(devAddr, &endpoint);
- if(payload)
+ if (payload)
{
if((result =
OCConvertPayload(payload, &requestInfo.info.payload, &requestInfo.info.payloadSize))
OIC_LOG(ERROR, TAG, "Failed to create CBOR Payload");
goto exit;
}
- requestInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR;
+
+ uint16_t payloadVersion = OC_SPEC_VERSION_VALUE;
+ // From OCF onwards, check version option settings
+ if (DEFAULT_CONTENT_VERSION_VALUE <= payloadVersion)
+ {
+ if (numOptions > 0 && options)
+ {
+ for (uint8_t i = 0; i < numOptions; i++)
+ {
+ if (COAP_OPTION_CONTENT_VERSION == options[i].optionID)
+ {
+ payloadVersion = options[i].optionData[0];
+ break;
+ }
+ else if (COAP_OPTION_ACCEPT_VERSION == options[i].optionID)
+ {
+ payloadVersion = options[i].optionData[0];
+ break;
+ }
+ }
+ }
+ }
+
+ if (DEFAULT_CONTENT_VERSION_VALUE <= payloadVersion)
+ {
+ requestInfo.info.payloadFormat = CA_FORMAT_APPLICATION_VND_OCF_CBOR;
+ requestInfo.info.payloadVersion = payloadVersion;
+ }
+ else
+ {
+ requestInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR;
+ }
}
else
{
}
AddObserver(OC_RSRVD_PRESENCE_URI, NULL, 0, caToken, tokenLength,
- (OCResource *)presenceResource.handle, OC_LOW_QOS, OC_FORMAT_UNDEFINED, &devAddr);
+ (OCResource *) presenceResource.handle, OC_LOW_QOS, OC_FORMAT_UNDEFINED,
+ OC_SPEC_VERSION_VALUE, &devAddr);
CADestroyToken(caToken);
}