Enable self link in collections 47/22747/8
authorAbhishek Pandey <abhi.siso@samsung.com>
Thu, 12 Oct 2017 13:18:40 +0000 (18:48 +0530)
committerAbhishek Pandey <abhi.siso@samsung.com>
Wed, 18 Oct 2017 09:02:33 +0000 (14:32 +0530)
JIRA IOT-2742 https://jira.iotivity.org/browse/IOT-2742

- Enabled support for self link in collections.
- API OCLinksPayloadArrayCreate() modified to allow self links.
- New parameter (bool) in the API now allows to have a self link with
  "rel":["self", "item"], in links array as per OCF Core Spec.

Change-Id: I1f2e02dd33c993dc4b28fbc447b8d286c1f7f804
Signed-off-by: Abhishek Pandey <abhi.siso@samsung.com>
resource/csdk/stack/include/internal/occollection.h
resource/csdk/stack/include/ocpayload.h
resource/csdk/stack/src/occollection.c
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/test/stacktests.cpp
service/easy-setup/enrollee/src/resourcehandler.c

index 75a52ac..6369687 100644 (file)
@@ -35,6 +35,7 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
  * @param[in] devAddr Structure pointing to the address. (from OCEntityHandlerRequest)
  * @param[in] isOCFVer true if AcceptedVersion is OCF1.0 or higher
  *            otherwise false in case OIC1.1 (from OCEntityHandlerRequest)
+ * @param[in] insertSelfLink true if links array must contain a self link
  * @param[out] createdArraySize return value array size, Null is allowed if no need to know size
  * @note: The destroy of OCRepPayloadValue is not supported. Instead, use
  *        OCRepPayloadDestroy(...) to destroy RepPayload of the collection Resource
@@ -43,6 +44,7 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
  * @see OCLinksPayloadArrayCreate API doxygen for API usage
  */
 OCRepPayload** BuildCollectionLinksPayloadArray(const char* resourceUri,
-                    bool isOCFContentFormat, OCDevAddr* devAddr, size_t* createdArraySize);
+                    bool isOCFContentFormat, OCDevAddr* devAddr, bool insertSelfLink,
+                    size_t* createdArraySize);
 
 #endif //OC_COLLECTION_H
index bb9f182..e27b8bb 100644 (file)
@@ -315,10 +315,11 @@ bool OC_CALL OCByteStringCopy(OCByteString *dest, const OCByteString *source);
  * This function creates the payloadArray for links parameter of collection resource.
  * @param[in] resourceUri Resource uri (this should be a collection resource)
  * @param[in] ehRequest parameter received from Entity Handler for client request
+ * @param[in] insertSelfLink flag to specify whether links array can contain a self link
  * @param[out] createdArraySize return value array size, Null is allowed if no need to know size
  *
  * @note: API usage
- *   OCRepPayload **linkArr = OCLinksPayloadArrayCreate(uri, ehRequest, &ArraySize);
+ *   OCRepPayload **linkArr = OCLinksPayloadArrayCreate(uri, ehRequest, false, &ArraySize);
  *   For links parameter setting  (baseline interface response)
  *    OCRepPayloadSetPropObjectArrayAsOwner(payload, OC_RSRVD_LINKS, linkArr, {ArraySize, 0,0});
  *   For arrayPayload setting (linklist interface response)
@@ -330,7 +331,7 @@ bool OC_CALL OCByteStringCopy(OCByteString *dest, const OCByteString *source);
  * @return linksRepPayloadArray The *RepPayload Array pointer for links parameter of collection.
  **/
 OCRepPayload** OC_CALL OCLinksPayloadArrayCreate(const char *resourceUri,
-                       OCEntityHandlerRequest *ehRequest, size_t* createdArraySize);
+                       OCEntityHandlerRequest *ehRequest, bool insertSelfLink, size_t* createdArraySize);
 
 #ifdef __cplusplus
 }
index 24ccd40..7c68bc0 100644 (file)
@@ -138,7 +138,7 @@ static OCStackResult HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest
     size_t dim[MAX_REP_ARRAY_DEPTH] = {size, 0, 0};
     OCRepPayload **linkArr = NULL;
 
-    if (!(linkArr = OCLinksPayloadArrayCreate(collResource->uri, ehRequest, NULL)))
+    if (!(linkArr = OCLinksPayloadArrayCreate(collResource->uri, ehRequest, false, NULL)))
     {
         OIC_LOG_V(ERROR, TAG, "Failed getting LinksPayloadArray");
         ret = OC_STACK_ERROR;
@@ -449,7 +449,7 @@ exit:
 }
 
 OCRepPayload** BuildCollectionLinksPayloadArray(const char* resourceUri,
-    bool isOCFContentFormat, OCDevAddr* devAddr, size_t* createdArraySize)
+    bool isOCFContentFormat, OCDevAddr* devAddr, bool insertSelfLink, size_t* createdArraySize)
 {
     bool result = false;
     OCRepPayload** arrayPayload = NULL;
@@ -467,6 +467,12 @@ OCRepPayload** BuildCollectionLinksPayloadArray(const char* resourceUri,
         childCount++;
         childCountResource = childCountResource->next;
     } while (childCountResource);
+
+    if (insertSelfLink)
+    {
+        childCount++;
+    }
+
     arrayPayload = (OCRepPayload**)OICMalloc(sizeof(OCRepPayload*) * (childCount));
     VERIFY_PARAM_NON_NULL(TAG, arrayPayload, "Failed creating arrayPayload");
 
@@ -555,10 +561,29 @@ OCRepPayload** BuildCollectionLinksPayloadArray(const char* resourceUri,
             }
         }
 
-        childResource = childResource->next;
-        if (childResource)
+        if (iterResource != colResourceHandle)
+        {
+            childResource = childResource->next;
+            if (childResource)
+            {
+                iterResource = childResource->rsrcResource;
+            }
+            else if (insertSelfLink)
+            {
+                iterResource = colResourceHandle;
+            }
+        }
+        else // handling selfLink case
         {
-            iterResource = childResource->rsrcResource;
+            OIC_LOG(INFO, TAG, "adding rel for self link");
+            const char* relArray[2] = { "self", "item" };
+            size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 2, 0, 0 };
+            if (!OCRepPayloadSetStringArray(arrayPayload[i], OC_RSRVD_REL, relArray, dimensions))
+            {
+                OIC_LOG(ERROR, TAG, "Failed setting rel property");
+                result = false;
+                goto exit;
+            } 
         }
         result = true;
     }
index 8755dee..0c37982 100644 (file)
@@ -2257,7 +2257,7 @@ void OC_CALL OCEndpointPayloadDestroy(OCEndpointPayload* payload)
 }
 
 OCRepPayload** OC_CALL OCLinksPayloadArrayCreate(const char* resourceUri,
-                       OCEntityHandlerRequest *ehRequest, size_t* createdArraySize)
+                       OCEntityHandlerRequest *ehRequest, bool insertSelfLink, size_t* createdArraySize)
 {
     OIC_LOG(DEBUG, TAG, "OCLinksPayloadValueCreate");
     OCRepPayload** linksRepPayloadArray = NULL;
@@ -2268,8 +2268,8 @@ OCRepPayload** OC_CALL OCLinksPayloadArrayCreate(const char* resourceUri,
             (contentFormat == OC_FORMAT_VND_OCF_CBOR || contentFormat == OC_FORMAT_CBOR))
             return NULL;
 
-        if (linksRepPayloadArray = BuildCollectionLinksPayloadArray(resourceUri,
-            contentFormat, &ehRequest->devAddr, createdArraySize))
+        linksRepPayloadArray = BuildCollectionLinksPayloadArray(resourceUri, contentFormat, &ehRequest->devAddr,
+            insertSelfLink, createdArraySize);
 
         OIC_LOG_V(DEBUG, TAG, "return value of BuildCollectionLinksPayloadArray() = %s",
                  (linksRepPayloadArray != NULL) ? "true" : "false");
@@ -2292,15 +2292,15 @@ OCStackResult OC_CALL OCGetRequestPayloadVersion(OCEntityHandlerRequest *ehReque
         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", 
+            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;
     }
 
-    // accepting NULL input parameter in case version is not required  
+    // accepting NULL input parameter in case version is not required
     if (pAcceptVersion == NULL)
     {
         return OC_STACK_OK;
index 302b198..ad9aa68 100644 (file)
@@ -3021,8 +3021,8 @@ TEST(LinksPayloadArray, BuildCollectionLinksPayloadArray)
 
     //check for OIC1.1 logic
     size_t arraySize = 0;
-    linksRepPayloadArray = BuildCollectionLinksPayloadArray("/a/kitchen", false, 
-                                                            devAddr, &arraySize);
+    linksRepPayloadArray = BuildCollectionLinksPayloadArray("/a/kitchen", false,
+                                                            devAddr, false, &arraySize);
     ASSERT_TRUE(NULL != linksRepPayloadArray);
 
     collectionPayload = OCRepPayloadCreate();
@@ -3090,7 +3090,9 @@ TEST(LinksPayloadArray, BuildCollectionLinksPayloadArray)
     OCRepPayloadDestroy(collectionPayload);
 
     //check for OCF1.0 logic
-    linksRepPayloadArray = BuildCollectionLinksPayloadArray("/a/kitchen", true, devAddr, &arraySize);
+    linksRepPayloadArray = BuildCollectionLinksPayloadArray("/a/kitchen", true, devAddr, false,
+        &arraySize);
+
     ASSERT_TRUE(NULL != linksRepPayloadArray);
 
     collectionPayload = OCRepPayloadCreate();
index ad44e8f..fdddaf6 100644 (file)
@@ -1039,7 +1039,7 @@ OCRepPayload* constructResponseOfEasySetup(OCEntityHandlerRequest *ehRequest)
      {
         size_t arraySize;
         OCRepPayload **linkArr = OCLinksPayloadArrayCreate(OC_RSRVD_ES_URI_EASYSETUP, ehRequest,
-                &arraySize);
+            true, &arraySize);
 
 #ifdef ES_IGNORE_OCLinksPayloadArrayCreate_FAILIURE
         bool linkArrConstructed = true; // TODO: Remove this when