[IOT-3055] Fix to handle single element of batch 07/26007/12
authorkoushik.girijala <g.koushik@samsung.com>
Wed, 27 Jun 2018 09:52:27 +0000 (15:22 +0530)
committerAshok Babu Channa <ashok.channa@samsung.com>
Tue, 18 Sep 2018 06:27:39 +0000 (06:27 +0000)
Response for collection with batch interface should be an array and not
object, This change will fix the case when the collection resource have
to send only one element in response, instead of sending it as array of
one element it sends as single object
As per OCF 2.0 spec , for single element case the response should be an
array even for single element

Change-Id: I29a2bafd1d163c4754cc3edcb77c15661399cbeb
Signed-off-by: koushik.girijala <g.koushik@samsung.com>
resource/csdk/include/octypes.h
resource/csdk/stack/include/ocpayload.h
resource/csdk/stack/octbstack_product.def
resource/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/src/ocpayloadconvert.c
resource/csdk/stack/src/ocserverrequest.c
resource/include/OCRepresentation.h
resource/src/OCRepresentation.cpp

index 89280de..e2e49a6 100644 (file)
@@ -1447,6 +1447,13 @@ typedef enum
     PAYLOAD_TYPE_INTROSPECTION
 } OCPayloadType;
 
+/** Enum to describe payload interface interface.*/
+typedef enum
+{
+    PAYLOAD_NON_BATCH_INTERFACE,
+    PAYLOAD_BATCH_INTERFACE
+} OCPayloadInterfaceType;
+
 /**
  * A generic struct representing a payload returned from a resource operation
  *
@@ -1526,6 +1533,7 @@ typedef struct OCRepPayloadValue
 typedef struct OCRepPayload
 {
     OCPayload base;
+    OCPayloadInterfaceType ifType;
     char* uri;
     OCStringLL* types;
     OCStringLL* interfaces;
index 7bf1c14..f4a42d2 100644 (file)
@@ -110,6 +110,8 @@ void OC_CALL OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child);
 
 bool OC_CALL OCRepPayloadSetUri(OCRepPayload* payload, const char* uri);
 
+bool OC_CALL OCRepPayloadSetInterfaceType(OCRepPayload* payload, OCPayloadInterfaceType type);
+
 bool OC_CALL OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType);
 bool OC_CALL OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface);
 
index 56021c5..b840797 100644 (file)
@@ -120,6 +120,7 @@ OCRepPayloadSetPropStringAsOwner
 OCRepPayloadSetStringArray
 OCRepPayloadSetStringArrayAsOwner
 OCRepPayloadSetUri
+OCRepPayloadSetInterfaceType
 OCResourcePayloadAddNewEndpoint
 OCResourcePayloadAddStringLL
 OCSecurityPayloadCreate
index 4b939a0..3dd5f20 100644 (file)
@@ -211,6 +211,7 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
             {
 
                 OCRepPayloadSetUri(payload, gRoomResourceUri);
+                OCRepPayloadSetInterfaceType(payload, PAYLOAD_BATCH_INTERFACE);
 
                 OCRepPayload *tempPayload = OCRepPayloadCreate();
                 OCRepPayloadSetUri(tempPayload, gLightResourceUri);
index a0c3b05..6e34b56 100644 (file)
@@ -85,6 +85,7 @@ OCRepPayload* OC_CALL OCRepPayloadCreate(void)
         return NULL;
     }
 
+    payload->ifType = PAYLOAD_NON_BATCH_INTERFACE;
     payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
 
     return payload;
@@ -495,6 +496,17 @@ bool OC_CALL OCRepPayloadSetUri(OCRepPayload* payload, const char*  uri)
     return payload->uri != NULL;
 }
 
+bool OC_CALL OCRepPayloadSetInterfaceType(OCRepPayload* payload, OCPayloadInterfaceType type)
+{
+    if (!payload)
+    {
+        return false;
+    }
+
+    payload->ifType = type;
+    return true;
+}
+
 bool OC_CALL OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
 {
     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
@@ -1622,6 +1634,7 @@ OCRepPayload* OC_CALL OCRepPayloadBatchClone(const OCRepPayload* repPayload)
     }
 
     clone->types  = CloneOCStringLL(repPayload->types);
+    clone->ifType = repPayload->ifType;
     clone->interfaces  = CloneOCStringLL(repPayload->interfaces);
     clone->values = OCRepPayloadValueClone(repPayload->values);
     OCRepPayloadSetPropObjectAsOwner(newPayload, OC_RSRVD_REPRESENTATION, clone);
index 11891b2..ac06847 100644 (file)
@@ -942,13 +942,19 @@ static int64_t OCConvertRepPayload(OCRepPayload *payload, uint8_t *outPayload, s
 
     cbor_encoder_init(&encoder, outPayload, *size, 0);
 
+    int isBatch = 0;
+    if (payload != NULL && payload->ifType == PAYLOAD_BATCH_INTERFACE)
+    {
+        isBatch = 1;
+    }
+
     size_t arrayCount = 0;
     for (OCRepPayload *temp = payload; temp; temp = temp->next)
     {
         arrayCount++;
     }
     CborEncoder rootArray;
-    if (arrayCount > 1)
+    if (arrayCount > 1 || isBatch)
     {
         err |= cbor_encoder_create_array(&encoder, &rootArray, arrayCount);
         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed adding rep root map");
@@ -957,7 +963,7 @@ static int64_t OCConvertRepPayload(OCRepPayload *payload, uint8_t *outPayload, s
     while (payload != NULL && (err == CborNoError))
     {
         CborEncoder rootMap;
-        err |= cbor_encoder_create_map(((arrayCount == 1)? &encoder: &rootArray),
+        err |= cbor_encoder_create_map(((arrayCount == 1 && !isBatch)? &encoder: &rootArray),
                                             &rootMap, CborIndefiniteLength);
         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed creating root map");
 
@@ -965,12 +971,12 @@ static int64_t OCConvertRepPayload(OCRepPayload *payload, uint8_t *outPayload, s
         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed setting rep payload");
 
         // Close main array
-        err |= cbor_encoder_close_container(((arrayCount == 1) ? &encoder: &rootArray),
+        err |= cbor_encoder_close_container(((arrayCount == 1 && !isBatch) ? &encoder: &rootArray),
                 &rootMap);
         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed closing root map");
         payload = payload->next;
     }
-    if (arrayCount > 1)
+    if (arrayCount > 1 || isBatch)
     {
         err |= cbor_encoder_close_container(&encoder, &rootArray);
         VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed closing root array");
index 65bf85a..d1224e6 100644 (file)
@@ -877,6 +877,7 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
 
         if(!serverResponse->payload)
         {
+            OCRepPayloadSetInterfaceType(newPayload, PAYLOAD_BATCH_INTERFACE);
             serverResponse->payload = (OCPayload *)newPayload;
         }
         else
index 561bea4..d7b079c 100644 (file)
@@ -102,6 +102,10 @@ namespace OC
 
             OCRepPayload* getPayload() const;
 
+            void setInterfaceType(const InterfaceType&);
+
+            InterfaceType getInterfaceType() const;
+
             void addChild(const OCRepresentation&);
 
             void clearChildren();
@@ -448,10 +452,6 @@ namespace OC
             // based on the interface type configured in ResourceResponse.
             // This allows ResourceResponse to set it, so that the save function
             // doesn't serialize things that it isn't supposed to serialize.
-            void setInterfaceType(InterfaceType ift)
-            {
-                m_interfaceType = ift;
-            }
 
             // class used to wrap the 'prop' feature of the save/load
             class Prop
index 83f205d..6aa4869 100644 (file)
@@ -83,6 +83,10 @@ namespace OC
             if (!root)
             {
                 root = r.getPayload();
+                if (r.getInterfaceType() == InterfaceType::BatchParent)
+                {
+                    root->ifType = PAYLOAD_BATCH_INTERFACE;
+                }
             }
             else
             {
@@ -389,6 +393,16 @@ namespace OC
         return root;
     }
 
+    void OCRepresentation::setInterfaceType(const InterfaceType& ift)
+    {
+        m_interfaceType = ift;
+    }
+
+    InterfaceType OCRepresentation::getInterfaceType() const
+    {
+        return m_interfaceType;
+    }
+
     size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
     {
         if (dimensions[0] == 0)