Add support for and handle presence of the coap ACCEPT option.
authorStephane Lejeune <stlejeun@cisco.com>
Thu, 10 Sep 2015 23:58:19 +0000 (01:58 +0200)
committerPatrick Lankswert <patrick.lankswert@intel.com>
Tue, 15 Sep 2015 15:26:05 +0000 (15:26 +0000)
This commit adds the CBOR accept option to all requests.
When a request comes in with an accept option, the option is evaluated
against the supported encoding formats. If the format is undefined or
when CBOR is requested, CBOR will be used to encod the payload.
When the response does not carry a payload, the accept option is
ignored and the response will proceed irrespective whether the accept
format was supported or not. This allowsi for example a device that
performs a delet operation proceed first working out which format is
supported by the server.

Change-Id: I7ae3430d11f1481a91413088a959f105b216ffea
Signed-off-by: Stephane Lejeune <stlejeun@cisco.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2492
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Hauke Mehrtens <hauke.mehrtens@lantiq.com>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.com>
12 files changed:
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/common/src/caremotehandler.c
resource/csdk/connectivity/inc/caprotocolmessage.h
resource/csdk/connectivity/src/caprotocolmessage.c
resource/csdk/stack/include/internal/ocobserve.h
resource/csdk/stack/include/internal/ocserverrequest.h
resource/csdk/stack/include/internal/ocstackinternal.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/src/ocobserve.c
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocserverrequest.c
resource/csdk/stack/src/ocstack.c

index 2a952e5..41431e0 100644 (file)
@@ -295,6 +295,7 @@ typedef enum
     CA_BAD_OPT = 402,                /**< Bad Option */
     CA_FORBIDDEN_REQ = 403,          /**< Forbidden Request */
     CA_NOT_FOUND = 404,              /**< Not found */
+    CA_NOT_ACCEPTABLE = 406,         /**< Not Acceptable */
     CA_REQUEST_ENTITY_INCOMPLETE = 408, /**< Request Entity Incomplete */
     CA_REQUEST_ENTITY_TOO_LARGE = 413,  /**< Request Entity Too Large */
     CA_INTERNAL_SERVER_ERROR = 500,  /**< Internal Server Error */
@@ -327,9 +328,16 @@ typedef enum
  */
 typedef enum
 {
-    CA_FORMAT_UNDEFINED,    /**< Undefined enoding format */
-    CA_FORMAT_UNSUPPORTED,  /**< Unsupported encoding format */
-    CA_FORMAT_CBOR          /**< CBOR encoding format */
+    CA_FORMAT_UNDEFINED = 0,            /**< Undefined enoding format */
+    CA_FORMAT_TEXT_PLAIN,
+    CA_FORMAT_APPLICATION_LINK_FORMAT,
+    CA_FORMAT_APPLICATION_XML,
+    CA_FORMAT_APPLICATION_OCTET_STREAM,
+    CA_FORMAT_APPLICATION_RDF_XML,
+    CA_FORMAT_APPLICATION_EXI,
+    CA_FORMAT_APPLICATION_JSON,
+    CA_FORMAT_APPLICATION_CBOR,
+    CA_FORMAT_UNSUPPORTED
 } CAPayloadFormat_t;
 
 /**
@@ -364,7 +372,8 @@ typedef struct
     uint8_t numOptions;         /**< Number of Header options */
     CAPayload_t payload;        /**< payload of the request  */
     size_t payloadSize;         /**< size in bytes of the payload */
-    CAPayloadFormat_t payloadFormat;         /**< format of the payload */
+    CAPayloadFormat_t payloadFormat;    /**< encoding format of the request payload */
+    CAPayloadFormat_t acceptFormat;     /**< accept format for the response payload */
     CAURI_t resourceUri;        /**< Resource URI information **/
     CARemoteId_t identity;      /**< endpoint identity */
 } CAInfo_t;
index edab3cc..8c159d4 100644 (file)
@@ -102,6 +102,7 @@ CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
         case CA_BAD_OPT:
         case CA_FORBIDDEN_REQ:
         case CA_NOT_FOUND:
+        case CA_NOT_ACCEPTABLE:
         case CA_REQUEST_ENTITY_INCOMPLETE:
         case CA_REQUEST_ENTITY_TOO_LARGE:
         case CA_INTERNAL_SERVER_ERROR:
@@ -285,6 +286,7 @@ CAResult_t CACloneInfo(const CAInfo_t *info, CAInfo_t *clone)
         clone->payloadSize = info->payloadSize;
     }
     clone->payloadFormat = info->payloadFormat;
+    clone->acceptFormat = info->acceptFormat;
 
     if (info->resourceUri)
     {
index ae3e1c2..e557f15 100644 (file)
@@ -231,6 +231,13 @@ uint16_t CAGetMessageIdFromPduBinaryData(const void *pdu, uint32_t size);
  */
 CAResponseResult_t CAGetCodeFromPduBinaryData(const void *pdu, uint32_t size);
 
+/**
+ * convert format from coap to OC.
+ * @param[in]   format              coap format code.
+ * @return format.
+ */
+CAPayloadFormat_t CAConvertFormat(uint8_t format);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 3551e5d..b42cfaa 100644 (file)
@@ -509,7 +509,7 @@ CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t *info, coap_list_t **
         coap_list_t* node = NULL;
         uint8_t buf[3] = {0};
         switch (info->payloadFormat) {
-            case CA_FORMAT_CBOR:
+            case CA_FORMAT_APPLICATION_CBOR:
                 node = CACreateNewOptionNode(
                         COAP_OPTION_CONTENT_FORMAT,
                         coap_encode_var_bytes(buf, (uint16_t)COAP_MEDIATYPE_APPLICATION_CBOR),
@@ -531,6 +531,33 @@ CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t *info, coap_list_t **
             return CA_STATUS_INVALID_PARAM;
         }
     }
+    if (CA_FORMAT_UNDEFINED != info->acceptFormat)
+    {
+        coap_list_t* node = NULL;
+        uint8_t buf[3] = {0};
+        switch (info->acceptFormat) {
+            case CA_FORMAT_APPLICATION_CBOR:
+                node = CACreateNewOptionNode(
+                        COAP_OPTION_ACCEPT,
+                        coap_encode_var_bytes(buf, (uint16_t)COAP_MEDIATYPE_APPLICATION_CBOR),
+                        (char *)buf);
+                break;
+            default:
+                OIC_LOG_V(ERROR, TAG, "format option:[%d] not supported", info->acceptFormat);
+        }
+        if (!node)
+        {
+            OIC_LOG(ERROR, TAG, "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, "format option not inserted in header");
+            return CA_STATUS_INVALID_PARAM;
+        }
+    }
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -622,7 +649,8 @@ uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter)
         if (COAP_OPTION_URI_PATH != opt_iter.type && COAP_OPTION_URI_QUERY != opt_iter.type
             && 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_CONTENT_FORMAT != opt_iter.type
+            && COAP_OPTION_ACCEPT != opt_iter.type)
         {
             count++;
         }
@@ -662,6 +690,7 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
     // set message id
     outInfo->messageId = pdu->hdr->id;
     outInfo->payloadFormat = CA_FORMAT_UNDEFINED;
+    outInfo->acceptFormat = CA_FORMAT_UNDEFINED;
 
     if (count > 0)
     {
@@ -771,15 +800,29 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
             }
             else if (COAP_OPTION_CONTENT_FORMAT == opt_iter.type)
             {
-                if (1 == COAP_OPT_LENGTH(option) && COAP_MEDIATYPE_APPLICATION_CBOR == buf[0])
+                if (1 == COAP_OPT_LENGTH(option))
                 {
-                    outInfo->payloadFormat = CA_FORMAT_CBOR;
+                    outInfo->payloadFormat = CAConvertFormat((uint8_t)buf[0]);
                 }
                 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[%d] has format [%d]", opt_iter.type, (uint8_t)buf[0]);
+            }
+            else if (COAP_OPTION_ACCEPT == opt_iter.type)
+            {
+                if (1 == COAP_OPT_LENGTH(option))
+                {
+                    outInfo->acceptFormat = CAConvertFormat((uint8_t)buf[0]);
+                }
+                else
+                {
+                    outInfo->acceptFormat = CA_FORMAT_UNSUPPORTED;
+                }
+                OIC_LOG_V(DEBUG, TAG, "option[%d] has an unsupported format [%d]",
+                        opt_iter.type, (uint8_t)buf[0]);
             }
             else
             {
@@ -1077,3 +1120,28 @@ CAResponseResult_t CAGetCodeFromPduBinaryData(const void *pdu, uint32_t size)
 
     return (CAResponseResult_t) CA_RESPONSE_CODE(hdr->code);
 }
+
+CAPayloadFormat_t CAConvertFormat(uint8_t format)
+{
+    switch (format)
+    {
+        case COAP_MEDIATYPE_TEXT_PLAIN:
+            return CA_FORMAT_TEXT_PLAIN;
+        case COAP_MEDIATYPE_APPLICATION_LINK_FORMAT:
+            return CA_FORMAT_APPLICATION_LINK_FORMAT;
+        case COAP_MEDIATYPE_APPLICATION_XML:
+            return CA_FORMAT_APPLICATION_XML;
+        case COAP_MEDIATYPE_APPLICATION_OCTET_STREAM:
+            return CA_FORMAT_APPLICATION_OCTET_STREAM;
+        case COAP_MEDIATYPE_APPLICATION_RDF_XML:
+            return CA_FORMAT_APPLICATION_RDF_XML;
+        case COAP_MEDIATYPE_APPLICATION_EXI:
+            return CA_FORMAT_APPLICATION_EXI;
+        case COAP_MEDIATYPE_APPLICATION_JSON:
+            return CA_FORMAT_APPLICATION_JSON;
+        case COAP_MEDIATYPE_APPLICATION_CBOR:
+            return CA_FORMAT_APPLICATION_CBOR;
+        default:
+            return CA_FORMAT_UNSUPPORTED;
+    }
+}
index 0a2eb3e..1a98969 100644 (file)
@@ -79,6 +79,10 @@ typedef struct ResourceObserver
 
     /** next node in this list.*/
     struct ResourceObserver *next;
+
+    /** requested payload encoding format. */
+    OCPayloadFormat acceptFormat;
+
 } ResourceObserver;
 
 #ifdef WITH_PRESENCE
@@ -162,6 +166,7 @@ OCStackResult AddObserver (const char         *resUri,
                            uint8_t            tokenLength,
                            OCResource         *resHandle,
                            OCQualityOfService qos,
+                           OCPayloadFormat    acceptFormat,
                            const OCDevAddr    *devAddr);
 
 /**
index d4bea55..ac495cc 100644 (file)
@@ -45,6 +45,9 @@ typedef struct OCServerRequest
     /** The REST method retrieved from received request PDU.*/
     OCMethod method;
 
+    /** Accept format retrieved from the received request PDU. */
+    OCPayloadFormat acceptFormat;
+
     /** resourceUrl will be filled in occoap using the path options in received request PDU.*/
     char resourceUrl[MAX_URI_LENGTH];
 
@@ -106,6 +109,9 @@ typedef struct OCServerRequest
     /** payload is retrieved from the payload of the received request PDU.*/
     uint8_t payload[1];
 
+    // WARNING: Do NOT add attributes after payload as they get overwritten
+    // when payload content gets copied over!
+
 } OCServerRequest;
 
 /**
@@ -199,6 +205,7 @@ OCServerResponse * GetServerResponseUsingHandle (const OCServerRequest * handle)
  * @param tokenLength                           Request token length.
  * @param resourceUrl                           URL of resource.
  * @param reqTotalSize                          Total size of the request.
+ * @param acceptFormat                          The format requested for the payload encoding.
  * @param devAddr                               Device Address.
  *
  * @return
@@ -212,6 +219,7 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
         uint8_t * payload, CAToken_t requestToken,
         uint8_t tokenLength,
         char * resourceUrl, size_t reqTotalSize,
+        OCPayloadFormat acceptFormat,
         const OCDevAddr *devAddr);
 
 /**
index a77aed6..a987613 100644 (file)
@@ -81,6 +81,9 @@ typedef struct
     /** The REST method retrieved from received request PDU.*/
     OCMethod method;
 
+    /** the requested payload format. */
+    OCPayloadFormat acceptFormat;
+
     /** resourceUrl will be filled in occoap using the path options in received request PDU.*/
     char resourceUrl[MAX_URI_LENGTH];
 
index 22ce6b1..b558fc3 100644 (file)
@@ -510,6 +510,16 @@ typedef enum
 } OCMethod;
 
 /**
+ *  Formats for payload encoding.
+ */
+typedef enum
+{
+    OC_FORMAT_CBOR,
+    OC_FORMAT_UNDEFINED,
+    OC_FORMAT_UNSUPPORTED,
+} OCPayloadFormat;
+
+/**
  * Host Mode of Operation.
  */
 typedef enum
@@ -1019,7 +1029,6 @@ typedef struct
     /** the payload from the request PDU.*/
     OCPayload *payload;
 
-
 } OCEntityHandlerRequest;
 
 
index 5f09f1e..72f1b96 100644 (file)
@@ -133,7 +133,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
                         0, resPtr->sequenceNum, qos, resourceObserver->query,
                         NULL, NULL,
                         resourceObserver->token, resourceObserver->tokenLength,
-                        resourceObserver->resUri, 0,
+                        resourceObserver->resUri, 0, resourceObserver->acceptFormat,
                         &resourceObserver->devAddr);
 
                 if(request)
@@ -178,7 +178,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
                         0, resPtr->sequenceNum, qos, resourceObserver->query,
                         NULL, NULL,
                         resourceObserver->token, resourceObserver->tokenLength,
-                        resourceObserver->resUri, 0,
+                        resourceObserver->resUri, 0, resourceObserver->acceptFormat,
                         &resourceObserver->devAddr);
 
                 if(result == OC_STACK_OK)
@@ -265,7 +265,7 @@ OCStackResult SendListObserverNotification (OCResource * resource,
                 result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET,
                         0, resource->sequenceNum, qos, observer->query,
                         NULL, NULL, observer->token, observer->tokenLength,
-                        observer->resUri, 0,
+                        observer->resUri, 0, observer->acceptFormat,
                         &observer->devAddr);
 
                 if(request)
@@ -361,6 +361,7 @@ OCStackResult AddObserver (const char         *resUri,
                            uint8_t            tokenLength,
                            OCResource         *resHandle,
                            OCQualityOfService qos,
+                           OCPayloadFormat    acceptFormat,
                            const OCDevAddr    *devAddr)
 {
     // Check if resource exists and is observable.
@@ -388,6 +389,7 @@ OCStackResult AddObserver (const char         *resUri,
         VERIFY_NON_NULL (obsNode->resUri);
 
         obsNode->qos = qos;
+        obsNode->acceptFormat = acceptFormat;
         if(query)
         {
             obsNode->query = OICStrdup(query);
index 2b0a174..b5da597 100644 (file)
@@ -766,7 +766,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         result = AddObserver ((const char*)(request->resourceUrl),
                 (const char *)(request->query),
                 ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
-                resource, request->qos,
+                resource, request->qos, request->acceptFormat,
                 &request->devAddr);
 
         if(result == OC_STACK_OK)
index 9c45034..82c3d05 100644 (file)
@@ -134,6 +134,27 @@ static void FindAndDeleteServerResponse(OCServerResponse * serverResponse)
     }
 }
 
+/**
+ * Ensure no accept header option is included when sending responses
+ *
+ * @param object CA remote endpoint.
+ * @param requestInfo CA request info.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+static OCStackResult OCSendResponse(const CAEndpoint_t *object, CAResponseInfo_t *responseInfo)
+{
+    // Do not include the accept header option
+    responseInfo->info.acceptFormat = CA_FORMAT_UNDEFINED;
+    CAResult_t result = CASendResponse(object, responseInfo);
+    if(CA_STATUS_OK != result)
+    {
+        OC_LOG_V(ERROR, TAG, "CASendResponse failed with CA error %u", result);
+        return CAResultToOCResult(result);
+    }
+    return OC_STACK_OK;
+}
+
 //-------------------------------------------------------------------------------------------------
 // Internal APIs
 //-------------------------------------------------------------------------------------------------
@@ -221,7 +242,8 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
         OCQualityOfService qos, char * query,
         OCHeaderOption * rcvdVendorSpecificHeaderOptions,
         uint8_t * payload, CAToken_t requestToken, uint8_t tokenLength,
-        char * resourceUrl, size_t reqTotalSize, const OCDevAddr *devAddr)
+        char * resourceUrl, size_t reqTotalSize, OCPayloadFormat acceptFormat,
+        const OCDevAddr *devAddr)
 {
     OCServerRequest * serverRequest = NULL;
 
@@ -239,6 +261,7 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
     serverRequest->observationOption = observationOption;
     serverRequest->observeResult = OC_STACK_ERROR;
     serverRequest->qos = qos;
+    serverRequest->acceptFormat = acceptFormat;
     serverRequest->ehResponseHandler = HandleSingleResponse;
     serverRequest->numResponses = 1;
 
@@ -512,6 +535,11 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
         responseInfo.info.options = NULL;
     }
 
+    responseInfo.isMulticast = false;
+    responseInfo.info.payload = NULL;
+    responseInfo.info.payloadSize = 0;
+    responseInfo.info.payloadFormat = CA_FORMAT_UNDEFINED;
+
     // Put the JSON prefix and suffix around the payload
     if(ehResponse->payload)
     {
@@ -524,24 +552,24 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
             responseInfo.isMulticast = false;
         }
 
-        OCStackResult result;
-        if((result = OCConvertPayload(ehResponse->payload, &responseInfo.info.payload,
-                    &responseInfo.info.payloadSize))
-                != OC_STACK_OK)
+        switch(serverRequest->acceptFormat)
         {
-            OC_LOG(ERROR, TAG, "Error converting payload");
-            OICFree(responseInfo.info.options);
-            return result;
+            case OC_FORMAT_UNDEFINED:
+                // No preference set by the client, so default to CBOR then
+            case OC_FORMAT_CBOR:
+                if((result = OCConvertPayload(ehResponse->payload, &responseInfo.info.payload,
+                                &responseInfo.info.payloadSize))
+                        != OC_STACK_OK)
+                {
+                    OC_LOG(ERROR, TAG, "Error converting payload");
+                    OICFree(responseInfo.info.options);
+                    return result;
+                }
+                responseInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR;
+                break;
+            default:
+                responseInfo.result = CA_NOT_ACCEPTABLE;
         }
-        /** @todo FIXME: this should really be set according to directives from OCConverPayload. */
-        responseInfo.info.payloadFormat = CA_FORMAT_CBOR;
-    }
-    else
-    {
-        responseInfo.isMulticast = false;
-        responseInfo.info.payload = NULL;
-        responseInfo.info.payloadSize = 0;
-        responseInfo.info.payloadFormat = CA_FORMAT_UNDEFINED;
     }
 
 #ifdef WITH_PRESENCE
@@ -562,9 +590,6 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
     int size = sizeof(CAConnTypes)/ sizeof(CATransportAdapter_t);
 
     CATransportAdapter_t adapter = responseEndpoint.adapter;
-    CAResult_t caResult = CA_STATUS_FAILED;
-    result = OC_STACK_OK;
-
     // Default adapter, try to send response out on all adapters.
     if (adapter == CA_DEFAULT_ADAPTER)
     {
@@ -584,39 +609,32 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
             );
     }
 
+    result = OC_STACK_OK;
+    OCStackResult tempResult = OC_STACK_OK;
+
     for(int i = 0; i < size; i++ )
     {
         responseEndpoint.adapter = (CATransportAdapter_t)(adapter & CAConnTypes[i]);
         if(responseEndpoint.adapter)
         {
-            //The result is set to OC_STACK_OK only if CASendResponse succeeds in sending the
+            //The result is set to OC_STACK_OK only if OCSendResponse succeeds in sending the
             //response on all the n/w interfaces else it is set to OC_STACK_ERROR
-            caResult = CASendResponse(&responseEndpoint, &responseInfo);
-            if(caResult != CA_STATUS_OK)
-            {
-                OC_LOG_V(ERROR, TAG, "CASendResponse failed with CA error %u", caResult);
-                result = CAResultToOCResult(caResult);
-            }
+            tempResult = OCSendResponse(&responseEndpoint, &responseInfo);
+        }
+        if(OC_STACK_OK != tempResult)
+        {
+            result = tempResult;
         }
     }
 #else
 
-    OC_LOG(INFO, TAG, "Calling CASendResponse with:");
+    OC_LOG(INFO, TAG, "Calling OCSendResponse with:");
     OC_LOG_V(INFO, TAG, "\tEndpoint address: %s", responseEndpoint.addr);
     OC_LOG_V(INFO, TAG, "\tEndpoint adapter: %s", responseEndpoint.adapter);
     OC_LOG_V(INFO, TAG, "\tResponse result : %s", responseInfo.result);
     OC_LOG_V(INFO, TAG, "\tResponse for uri: %s", responseInfo.info.resourceUri);
 
-    CAResult_t caResult = CASendResponse(&responseEndpoint, &responseInfo);
-    if(caResult != CA_STATUS_OK)
-    {
-        OC_LOG(ERROR, TAG, "CASendResponse failed");
-        result = CAResultToOCResult(caResult);
-    }
-    else
-    {
-        result = OC_STACK_OK;
-    }
+    result = OCSendResponse(&responseEndpoint, &responseInfo);
 #endif
 
     OICFree(responseInfo.info.payload);
index 93a9398..ae762af 100644 (file)
@@ -374,6 +374,16 @@ static OCResourceType *findResourceType(OCResourceType * resourceTypeList,
  */
 static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds);
 
+/**
+ * Ensure the accept header option is set appropriatly before sending the requests.
+ *
+ * @param object CA remote endpoint.
+ * @param requestInfo CA request info.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t *requestInfo);
+
 //-----------------------------------------------------------------------------
 // Internal functions
 //-----------------------------------------------------------------------------
@@ -428,6 +438,18 @@ void FixUpClientResponse(OCClientResponse *cr)
         ((cr->devAddr.adapter << CT_ADAPTER_SHIFT) | (cr->devAddr.flags & CT_MASK_FLAGS));
 }
 
+static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t *requestInfo)
+{
+    // OC stack prefer CBOR encoded payloads.
+    requestInfo->info.acceptFormat = CA_FORMAT_APPLICATION_CBOR;
+    CAResult_t result = CASendRequest(object, requestInfo);
+    if(CA_STATUS_OK != result)
+    {
+        OC_LOG_V(ERROR, TAG, "CASendRequest failed with CA error %u", result);
+        return CAResultToOCResult(result);
+    }
+    return OC_STACK_OK;
+}
 //-----------------------------------------------------------------------------
 // Internal API function
 //-----------------------------------------------------------------------------
@@ -1244,6 +1266,7 @@ OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16
     respInfo.info.tokenLength = tokenLength;
     respInfo.info.type = type;
     respInfo.info.resourceUri = OICStrdup (resourceUri);
+    respInfo.info.acceptFormat = CA_FORMAT_UNDEFINED;
 
     CAResult_t caResult = CASendResponse(endPoint, &respInfo);
 
@@ -1381,6 +1404,18 @@ void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque
     }
     memcpy(serverRequest.requestToken, requestInfo->info.token, requestInfo->info.tokenLength);
 
+    switch (requestInfo->info.acceptFormat)
+    {
+        case CA_FORMAT_APPLICATION_CBOR:
+            serverRequest.acceptFormat = OC_FORMAT_CBOR;
+            break;
+        case CA_FORMAT_UNDEFINED:
+            serverRequest.acceptFormat = OC_FORMAT_UNDEFINED;
+            break;
+        default:
+            serverRequest.acceptFormat = OC_FORMAT_UNSUPPORTED;
+    }
+
     if (requestInfo->info.type == CA_MSG_CONFIRM)
     {
         serverRequest.qos = OC_HIGH_QOS;
@@ -1463,13 +1498,13 @@ OCStackResult HandleStackRequests(OCServerProtocolRequest * protocolRequest)
     {
         OC_LOG(INFO, TAG, "This is a new Server Request");
         result = AddServerRequest(&request, protocolRequest->coapID,
-                protocolRequest->delayedResNeeded, 0,
-                protocolRequest->method, protocolRequest->numRcvdVendorSpecificHeaderOptions,
+                protocolRequest->delayedResNeeded, 0, protocolRequest->method,
+                protocolRequest->numRcvdVendorSpecificHeaderOptions,
                 protocolRequest->observationOption, protocolRequest->qos,
                 protocolRequest->query, protocolRequest->rcvdVendorSpecificHeaderOptions,
                 protocolRequest->payload, protocolRequest->requestToken,
-                protocolRequest->tokenLength,
-                protocolRequest->resourceUrl, protocolRequest->reqTotalSize,
+                protocolRequest->tokenLength, protocolRequest->resourceUrl,
+                protocolRequest->reqTotalSize, protocolRequest->acceptFormat,
                 &protocolRequest->devAddr);
         if (OC_STACK_OK != result)
         {
@@ -2184,7 +2219,7 @@ OCStackResult OCDoResource(OCDoHandle *handle,
             OC_LOG(ERROR, TAG, "Failed to create CBOR Payload");
             goto exit;
         }
-        requestInfo.info.payloadFormat = CA_FORMAT_CBOR;
+        requestInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR;
     }
     else
     {
@@ -2230,11 +2265,9 @@ OCStackResult OCDoResource(OCDoHandle *handle,
     resourceType = NULL;  // Client CB list entry now owns it
 
     // send request
-    caResult = CASendRequest(&endpoint, &requestInfo);
-    if (caResult != CA_STATUS_OK)
+    result = OCSendRequest(&endpoint, &requestInfo);
+    if (OC_STACK_OK != result)
     {
-        OC_LOG(ERROR, TAG, "CASendRequest");
-        result = OC_STACK_COMM_ERROR;
         goto exit;
     }
 
@@ -2291,7 +2324,6 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
      */
     OCStackResult ret = OC_STACK_OK;
     CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
-    CAResult_t caResult;
     CAInfo_t requestData = {.type = CA_MSG_CONFIRM};
     CARequestInfo_t requestInfo = {.method = CA_GET};
 
@@ -2340,13 +2372,7 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
             CopyDevAddrToEndpoint(clientCB->devAddr, &endpoint);
 
             // send request
-            caResult = CASendRequest(&endpoint, &requestInfo);
-            if (caResult != CA_STATUS_OK)
-            {
-                OC_LOG(ERROR, TAG, "CASendRequest error");
-                ret = OC_STACK_ERROR;
-            }
-            ret = CAResultToOCResult (caResult);
+            ret = OCSendRequest(&endpoint, &requestInfo);
             break;
 
 #ifdef WITH_PRESENCE
@@ -2465,7 +2491,6 @@ OCStackResult OCProcessPresence()
             continue;
         }
 
-        CAResult_t caResult = CA_STATUS_OK;
         CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
         CAInfo_t requestData = {.type = CA_MSG_CONFIRM};
         CARequestInfo_t requestInfo = {.method = CA_GET};
@@ -2481,11 +2506,9 @@ OCStackResult OCProcessPresence()
         requestInfo.method = CA_GET;
         requestInfo.info = requestData;
 
-        caResult = CASendRequest(&endpoint, &requestInfo);
-
-        if (caResult != CA_STATUS_OK)
+        result = OCSendRequest(&endpoint, &requestInfo);
+        if (OC_STACK_OK != result)
         {
-            OC_LOG(ERROR, TAG, "CASendRequest error");
             goto exit;
         }
 
@@ -2552,7 +2575,7 @@ OCStackResult OCStartPresence(const uint32_t ttl)
         }
 
         AddObserver(OC_RSRVD_PRESENCE_URI, NULL, 0, caToken, tokenLength,
-                (OCResource *)presenceResource.handle, OC_LOW_QOS, &devAddr);
+                (OCResource *)presenceResource.handle, OC_LOW_QOS, OC_FORMAT_UNDEFINED, &devAddr);
         CADestroyToken(caToken);
     }
 
@@ -3939,3 +3962,4 @@ OCStackResult CAResultToOCResult(CAResult_t caResult)
             return OC_STACK_ERROR;
     }
 }
+