Change OCGetContentFormat into public API 75/21675/4
authoruzchoi <uzchoi@samsung.com>
Mon, 31 Jul 2017 07:45:08 +0000 (16:45 +0900)
committerZiran Sun <ziran.sun@samsung.com>
Tue, 17 Oct 2017 17:48:35 +0000 (17:48 +0000)
OCIsOCFConentFormat API was internal API to provide bool return
according to media content format(cbor, vnd.ocf+cbor).
However, it can be used to app developer when they handle the
collection resource request with linked-list interface due to
backward compatibility requirement.
This change make the bool return into type enum value on
OCPayloadFormat and Accept version.
Corresponding code is also changed.

Change-Id: I6c780d9ad9e4b68da4b5d431ff294931bcde787e
Signed-off-by: uzchoi <uzchoi@samsung.com>
resource/csdk/stack/include/internal/ocstackinternal.h
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/src/occollection.c
resource/csdk/stack/src/ocpayload.c

index dd43c63..06e4664 100644 (file)
@@ -390,9 +390,6 @@ OCEndpointPayload* CreateEndpointPayloadList(const OCResource *resource,
 */
 void OC_CALL OCEndpointPayloadDestroy(OCEndpointPayload* payload);
 
-// Check on Accept Version option.
-bool OCRequestIsOCFContentFormat(OCEntityHandlerRequest *ehRequest, bool* isOCFContentFormat);
-
 #ifdef __cplusplus
 }
 #endif // __cplusplus
index bb088ed..7e17b51 100644 (file)
@@ -903,6 +903,18 @@ OCStackResult OC_CALL OCSelectCipherSuite(uint16_t cipher, OCTransportAdapter ad
  */
 OCStackResult OC_CALL OCGetIpv6AddrScope(const char *addr, OCTransportFlags *scope);
 
+/**
+* Return the Content Format from Entity Handler Request.
+*
+* @param[in] ehRequest          client request on entity handler
+* @param[out] pContentFormat    media content format enum OCPayloadFormat
+* @param[out] pAcceptVersion    accept version (e.g: 2048 for "1.0.0", NULL input is accepted)
+*
+* @return ::OC_STACK_OK if successful.
+*/
+OCStackResult OC_CALL OCGetRequestPayloadVersion(OCEntityHandlerRequest *ehRequest,
+                                  OCPayloadFormat* pContentFormat, uint16_t* pAcceptVersion);
+
 #ifdef __cplusplus
 }
 #endif // __cplusplus
index 62640f1..24ccd40 100644 (file)
@@ -134,7 +134,7 @@ static OCStackResult HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest
     uint8_t size = GetNumOfResourcesInCollection(collResource);
     OCRepPayload *colPayload = NULL;
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
-    OCStackResult ret = OC_STACK_OK;
+    OCStackResult ret = OC_STACK_ERROR;
     size_t dim[MAX_REP_ARRAY_DEPTH] = {size, 0, 0};
     OCRepPayload **linkArr = NULL;
 
@@ -151,10 +151,10 @@ static OCStackResult HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest
         goto exit;
     }
 
-    bool isOCFContentFormat = true;
-    OCRequestIsOCFContentFormat(ehRequest, &isOCFContentFormat);
+    OCPayloadFormat contentFormat = OC_FORMAT_UNDEFINED;
+    OCGetRequestPayloadVersion(ehRequest, &contentFormat, NULL);
     // from the OCF1.0 linklist specification, ll has array of links
-    if ((0 == strcmp(ifQueryParam, OC_RSRVD_INTERFACE_LL) && isOCFContentFormat))
+    if ((0 == strcmp(ifQueryParam, OC_RSRVD_INTERFACE_LL)) && (contentFormat == OC_FORMAT_VND_OCF_CBOR))
     {
         for (int n = 0; n < (int)size - 1; n++)
         {
@@ -162,9 +162,10 @@ static OCStackResult HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest
         }
         colPayload = linkArr[0];
         OICFree(linkArr);
+        ret = OC_STACK_OK;
         goto exit;
     }
-    else
+    else if ((contentFormat == OC_FORMAT_VND_OCF_CBOR || contentFormat == OC_FORMAT_CBOR))
     {
         colPayload = OCRepPayloadCreate();
         VERIFY_PARAM_NON_NULL(TAG, linkArr, "Failed creating LinksPayloadArray");
@@ -187,6 +188,7 @@ static OCStackResult HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest
             AddRTSBaselinePayload(linkArr, size, &colPayload);
         }
         OCRepPayloadSetPropObjectArrayAsOwner(colPayload, OC_RSRVD_LINKS, linkArr, dim);
+        ret = OC_STACK_OK;
     }
 exit:
     if (ret == OC_STACK_OK)
index 0f64205..8755dee 100644 (file)
@@ -34,6 +34,7 @@
 #include "logger.h"
 #include "ocendpoint.h"
 #include "cacommon.h"
+#include "ocstack.h"
 
 #define TAG "OIC_RI_PAYLOAD"
 #define CSV_SEPARATOR ','
@@ -2262,16 +2263,13 @@ OCRepPayload** OC_CALL OCLinksPayloadArrayCreate(const char* resourceUri,
     OCRepPayload** linksRepPayloadArray = NULL;
     if ((resourceUri != NULL) && (ehRequest != NULL))
     {
-        bool isOCFContentFormat = false;
-        if (!OCRequestIsOCFContentFormat(ehRequest, &isOCFContentFormat))
-        {
+        OCPayloadFormat contentFormat = OC_FORMAT_UNDEFINED;
+        if ((OC_STACK_OK != OCGetRequestPayloadVersion(ehRequest, &contentFormat, NULL)) &&
+            (contentFormat == OC_FORMAT_VND_OCF_CBOR || contentFormat == OC_FORMAT_CBOR))
             return NULL;
-        }
 
-        linksRepPayloadArray = BuildCollectionLinksPayloadArray(resourceUri,
-                                                                isOCFContentFormat,
-                                                                &ehRequest->devAddr,
-                                                                createdArraySize);
+        if (linksRepPayloadArray = BuildCollectionLinksPayloadArray(resourceUri,
+            contentFormat, &ehRequest->devAddr, createdArraySize))
 
         OIC_LOG_V(DEBUG, TAG, "return value of BuildCollectionLinksPayloadArray() = %s",
                  (linksRepPayloadArray != NULL) ? "true" : "false");
@@ -2279,28 +2277,51 @@ OCRepPayload** OC_CALL OCLinksPayloadArrayCreate(const char* resourceUri,
     return linksRepPayloadArray;
 }
 
-// Check on Content Version option whether request has vnd.ocf+cbor format instead of cbor
-bool OCRequestIsOCFContentFormat(OCEntityHandlerRequest *ehRequest, bool* isOCFContentFormat)
+OCStackResult OC_CALL OCGetRequestPayloadVersion(OCEntityHandlerRequest *ehRequest,
+                                  OCPayloadFormat* pContentFormat, uint16_t* pAcceptVersion)
 {
-    if ((ehRequest == NULL)||(isOCFContentFormat == NULL))
-        return false;
+    if ((ehRequest == NULL)||(pContentFormat == NULL))
+        return OC_STACK_ERROR;
 
     OCServerRequest* serverRequest = (OCServerRequest*) ehRequest->requestHandle;
-
-    if (OC_FORMAT_VND_OCF_CBOR == serverRequest->acceptFormat)
-    {
-        *isOCFContentFormat = true;
-        OIC_LOG_V(INFO, TAG, "Content format is application/vnd.ocf+cbor");
+    switch (serverRequest->acceptFormat)
+    {
+        case OC_FORMAT_CBOR:
+        case OC_FORMAT_VND_OCF_CBOR:
+        case OC_FORMAT_JSON:
+        case OC_FORMAT_UNDEFINED:
+        case OC_FORMAT_UNSUPPORTED:
+            *pContentFormat = serverRequest->acceptFormat;
+            OIC_LOG_V(INFO, TAG, 
+                      "Content format is %d, application/cbor = 0, application/vnd.ocf+cbor = 1", 
+                      (int) *pContentFormat);
+            break;
+        default:
+            return OC_STACK_INVALID_OPTION;
     }
-    else if (OC_FORMAT_CBOR == serverRequest->acceptFormat)
+
+    // accepting NULL input parameter in case version is not required  
+    if (pAcceptVersion == NULL)
     {
-        *isOCFContentFormat = false;
-        OIC_LOG_V(INFO, TAG, "Content format is application/cbor");
+        return OC_STACK_OK;
     }
-    else
+
+    uint8_t vOptionData[MAX_HEADER_OPTION_DATA_LENGTH];
+    size_t vOptionDataSize = sizeof(vOptionData);
+    uint16_t actualDataSize = 0;
+
+    OCGetHeaderOption(ehRequest->rcvdVendorSpecificHeaderOptions,
+                      ehRequest->numRcvdVendorSpecificHeaderOptions,
+                      COAP_OPTION_ACCEPT_VERSION, vOptionData, vOptionDataSize, &actualDataSize);
+
+    // Check if "OCF-Accept-Content-Format-Version" is present,
+    // and size of its value is as expected (2 bytes).
+    if (actualDataSize != 2)
     {
-        OIC_LOG_V(ERROR, TAG, "Content format is neither application/vnd.ocf+cbor nor /cbor");
-        return false;
+        return OC_STACK_INVALID_OPTION;
     }
-    return true;
+
+    *pAcceptVersion = vOptionData[0] * 256 + vOptionData[1];
+
+    return OC_STACK_OK;
 }