aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkoushik.girijala <g.koushik@samsung.com>2018-10-22 15:31:16 +0530
committerNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>2018-11-14 06:33:38 +0000
commit2d036285d22b7e201fe00a5405d3fc0aefe5722a (patch)
treef531c3f01a0eca7bfd737fae5d3eef1f347cda3c
parent57a24fe32c2fc2a16e3d68fd24981db955ff214a (diff)
[IOT-3055]Fixed Handle collection resource payload
Fixed Handle collection resource payload for all interfaces And also fixed batch interface for normal respources Change-Id: I35c11597f2f55d1e3d40317209fe127cdd076d46 Signed-off-by: koushik.girijala <g.koushik@samsung.com>
-rw-r--r--resource/csdk/include/octypes.h21
-rw-r--r--resource/csdk/stack/include/ocpayload.h3
-rw-r--r--resource/csdk/stack/octbstack_product.def2
-rw-r--r--resource/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp3
-rw-r--r--resource/csdk/stack/src/occollection.c11
-rw-r--r--resource/csdk/stack/src/ocpayload.c8
-rw-r--r--resource/csdk/stack/src/ocpayloadconvert.c31
-rw-r--r--resource/csdk/stack/src/ocserverrequest.c3
-rw-r--r--resource/csdk/stack/src/ocstack.c38
-rw-r--r--resource/include/OCRepresentation.h5
-rw-r--r--resource/include/OCResourceResponse.h43
-rw-r--r--resource/src/OCRepresentation.cpp18
12 files changed, 157 insertions, 29 deletions
diff --git a/resource/csdk/include/octypes.h b/resource/csdk/include/octypes.h
index e2e49a6..f632d0f 100644
--- a/resource/csdk/include/octypes.h
+++ b/resource/csdk/include/octypes.h
@@ -1447,12 +1447,23 @@ typedef enum
PAYLOAD_TYPE_INTROSPECTION
} OCPayloadType;
-/** Enum to describe payload interface interface.*/
+/** Enum to describe payload representation for collection and non collection resources.*/
typedef enum
{
- PAYLOAD_NON_BATCH_INTERFACE,
- PAYLOAD_BATCH_INTERFACE
-} OCPayloadInterfaceType;
+ /** Used for collection resource when the payload to be created for representation
+ * with one or more resource representations should be created as an array of object/ objects
+ * 1. Collection resource with Link list and Batch interface etc.
+ */
+ PAYLOAD_REP_ARRAY,
+
+ /** Used for Non Collection resources when payload to be created for the representation with
+ * zero or one child representation should be created as an Object and the payload with more
+ * than one representation should be created as an Array of Objects.
+ * 1. Non Collection resource with Link list, Default interfaces etc.
+ * 2. Collection resource with Default interface.
+ */
+ PAYLOAD_REP_OBJECT_ARRAY
+} OCPayloadRepresentationType;
/**
* A generic struct representing a payload returned from a resource operation
@@ -1533,11 +1544,11 @@ typedef struct OCRepPayloadValue
typedef struct OCRepPayload
{
OCPayload base;
- OCPayloadInterfaceType ifType;
char* uri;
OCStringLL* types;
OCStringLL* interfaces;
OCRepPayloadValue* values;
+ OCPayloadRepresentationType repType;
struct OCRepPayload* next;
} OCRepPayload;
diff --git a/resource/csdk/stack/include/ocpayload.h b/resource/csdk/stack/include/ocpayload.h
index 8be4206..a2ca3fc 100644
--- a/resource/csdk/stack/include/ocpayload.h
+++ b/resource/csdk/stack/include/ocpayload.h
@@ -114,7 +114,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 OCRepPayloadSetPayloadRepType(OCRepPayload* payload,
+ OCPayloadRepresentationType type);
bool OC_CALL OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType);
bool OC_CALL OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface);
diff --git a/resource/csdk/stack/octbstack_product.def b/resource/csdk/stack/octbstack_product.def
index b840797..3116b76 100644
--- a/resource/csdk/stack/octbstack_product.def
+++ b/resource/csdk/stack/octbstack_product.def
@@ -120,7 +120,7 @@ OCRepPayloadSetPropStringAsOwner
OCRepPayloadSetStringArray
OCRepPayloadSetStringArrayAsOwner
OCRepPayloadSetUri
-OCRepPayloadSetInterfaceType
+OCRepPayloadSetPayloadRepType
OCResourcePayloadAddNewEndpoint
OCResourcePayloadAddStringLL
OCSecurityPayloadCreate
diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp b/resource/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp
index 3dd5f20..fb72ab9 100644
--- a/resource/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp
+++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp
@@ -198,6 +198,7 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
else if(query.find(OC_RSRVD_INTERFACE_LL) != std::string::npos)
{
OCRepPayloadSetUri(payload, gRoomResourceUri);
+ OCRepPayloadSetPayloadRepType(payload, PAYLOAD_REP_ARRAY);
OCRepPayload *tempPayload = OCRepPayloadCreate();
OCRepPayloadSetUri(tempPayload, gLightResourceUri);
@@ -211,7 +212,7 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
{
OCRepPayloadSetUri(payload, gRoomResourceUri);
- OCRepPayloadSetInterfaceType(payload, PAYLOAD_BATCH_INTERFACE);
+ OCRepPayloadSetPayloadRepType(payload, PAYLOAD_REP_ARRAY);
OCRepPayload *tempPayload = OCRepPayloadCreate();
OCRepPayloadSetUri(tempPayload, gLightResourceUri);
diff --git a/resource/csdk/stack/src/occollection.c b/resource/csdk/stack/src/occollection.c
index 0a512f1..081f10c 100644
--- a/resource/csdk/stack/src/occollection.c
+++ b/resource/csdk/stack/src/occollection.c
@@ -190,6 +190,15 @@ static OCStackResult HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest
ret = OC_STACK_OK;
}
exit:
+ if (0 == strcmp(ifQueryParam, OC_RSRVD_INTERFACE_LL))
+ {
+ OCRepPayloadSetPayloadRepType(colPayload, PAYLOAD_REP_ARRAY);
+ }
+ else
+ {
+ OCRepPayloadSetPayloadRepType(colPayload, PAYLOAD_REP_OBJECT_ARRAY);
+ }
+
if (ret == OC_STACK_OK)
{
ehResult = OC_EH_OK;
@@ -583,7 +592,7 @@ OCRepPayload** BuildCollectionLinksPayloadArray(const char* resourceUri,
OIC_LOG(ERROR, TAG, "Failed setting rel property");
result = false;
goto exit;
- }
+ }
}
result = true;
}
diff --git a/resource/csdk/stack/src/ocpayload.c b/resource/csdk/stack/src/ocpayload.c
index 6e34b56..6b0b3df 100644
--- a/resource/csdk/stack/src/ocpayload.c
+++ b/resource/csdk/stack/src/ocpayload.c
@@ -85,7 +85,7 @@ OCRepPayload* OC_CALL OCRepPayloadCreate(void)
return NULL;
}
- payload->ifType = PAYLOAD_NON_BATCH_INTERFACE;
+ payload->repType = PAYLOAD_REP_OBJECT_ARRAY;
payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
return payload;
@@ -496,14 +496,14 @@ bool OC_CALL OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
return payload->uri != NULL;
}
-bool OC_CALL OCRepPayloadSetInterfaceType(OCRepPayload* payload, OCPayloadInterfaceType type)
+bool OC_CALL OCRepPayloadSetPayloadRepType(OCRepPayload* payload, OCPayloadRepresentationType type)
{
if (!payload)
{
return false;
}
- payload->ifType = type;
+ payload->repType = type;
return true;
}
@@ -1634,7 +1634,7 @@ OCRepPayload* OC_CALL OCRepPayloadBatchClone(const OCRepPayload* repPayload)
}
clone->types = CloneOCStringLL(repPayload->types);
- clone->ifType = repPayload->ifType;
+ clone->repType = repPayload->repType;
clone->interfaces = CloneOCStringLL(repPayload->interfaces);
clone->values = OCRepPayloadValueClone(repPayload->values);
OCRepPayloadSetPropObjectAsOwner(newPayload, OC_RSRVD_REPRESENTATION, clone);
diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c
index ac06847..3f7eb3d 100644
--- a/resource/csdk/stack/src/ocpayloadconvert.c
+++ b/resource/csdk/stack/src/ocpayloadconvert.c
@@ -942,28 +942,36 @@ 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)
+ size_t objectCount = 0;
+ for (OCRepPayload *temp = payload; temp; temp = temp->next)
{
- isBatch = 1;
+ objectCount++;
}
- size_t arrayCount = 0;
- for (OCRepPayload *temp = payload; temp; temp = temp->next)
+ int isColResource = 0;
+ if (payload != NULL && (payload->repType == PAYLOAD_REP_ARRAY))
{
- arrayCount++;
+ isColResource = 1;
}
+
+ // As per OCF spec
+ // 1. Create an array of objects for collection resource payload when 0 <=objectCount <=1
+ // for ll and batch interfaces.
+ // 2. Create single object for non collection resource payload when 0 <= objectCount <= 1
+ // for non batch interfaces.
+ // 3. Create an array of objects for any kind of resource when objectCount > 1 and for any
+ // interfaces.
CborEncoder rootArray;
- if (arrayCount > 1 || isBatch)
+ if ((objectCount > 1) ||(objectCount <= 1 && isColResource))
{
- err |= cbor_encoder_create_array(&encoder, &rootArray, arrayCount);
+ err |= cbor_encoder_create_array(&encoder, &rootArray, objectCount);
VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed adding rep root map");
}
while (payload != NULL && (err == CborNoError))
{
CborEncoder rootMap;
- err |= cbor_encoder_create_map(((arrayCount == 1 && !isBatch)? &encoder: &rootArray),
+ err |= cbor_encoder_create_map(((objectCount == 1 && !isColResource)? &encoder: &rootArray),
&rootMap, CborIndefiniteLength);
VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed creating root map");
@@ -971,12 +979,13 @@ 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 && !isBatch) ? &encoder: &rootArray),
+ err |= cbor_encoder_close_container(((objectCount == 1 && !isColResource) ? &encoder: &rootArray),
&rootMap);
VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed closing root map");
payload = payload->next;
}
- if (arrayCount > 1 || isBatch)
+
+ if (objectCount > 1 || (objectCount <= 1 && isColResource))
{
err |= cbor_encoder_close_container(&encoder, &rootArray);
VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, err, "Failed closing root array");
diff --git a/resource/csdk/stack/src/ocserverrequest.c b/resource/csdk/stack/src/ocserverrequest.c
index d1224e6..6e3e85a 100644
--- a/resource/csdk/stack/src/ocserverrequest.c
+++ b/resource/csdk/stack/src/ocserverrequest.c
@@ -875,9 +875,10 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
OCRepPayload *newPayload = OCRepPayloadBatchClone((OCRepPayload *)ehResponse->payload);
+ OCRepPayloadSetPayloadRepType(newPayload, PAYLOAD_REP_ARRAY);
+
if(!serverResponse->payload)
{
- OCRepPayloadSetInterfaceType(newPayload, PAYLOAD_BATCH_INTERFACE);
serverResponse->payload = (OCPayload *)newPayload;
}
else
diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c
index e24bcfa..092e87b 100644
--- a/resource/csdk/stack/src/ocstack.c
+++ b/resource/csdk/stack/src/ocstack.c
@@ -3544,6 +3544,44 @@ OCStackResult OC_CALL OCDoRequest(OCDoHandle *handle,
}
requestInfo.info.payloadVersion = payloadVersion;
+ // for fixing collection resource POST/PUT requests
+ if (payload->type == PAYLOAD_TYPE_REPRESENTATION)
+ {
+ OCRepPayload *repPayload = (OCRepPayload *)payload;
+
+ // PAYLOAD_REP_ARRAY is set only for case of collection resource
+ // Here we are differentiating DEFAULT with LL and BATCH interface
+ // For DEFAULT interface repType will be PAYLOAD_REP_OBJECT_ARRAY
+ if (requestUri && repPayload->repType == PAYLOAD_REP_ARRAY)
+ {
+ char *interfaceName = NULL;
+ char *rtTypeName = NULL;
+ char *uriQuery = NULL;
+ char *uriWithoutQuery = NULL;
+ if (OC_STACK_OK == getQueryFromUri(requestUri, &uriQuery, &uriWithoutQuery))
+ {
+ if (OC_STACK_OK == ExtractFiltersFromQuery(uriQuery, &interfaceName,
+ &rtTypeName))
+ {
+ if (interfaceName &&
+ (0 == strcmp(OC_RSRVD_INTERFACE_DEFAULT, interfaceName)))
+ {
+ repPayload->repType = PAYLOAD_REP_OBJECT_ARRAY;
+ }
+ }
+ else if (NULL == uriQuery)
+ {
+ repPayload->repType = PAYLOAD_REP_OBJECT_ARRAY;
+ }
+ }
+
+ OICFree(interfaceName);
+ OICFree(rtTypeName);
+ OICFree(uriQuery);
+ OICFree(uriWithoutQuery);
+ }
+ }
+
if ((result =
OCConvertPayload(payload, CAToOCPayloadFormat(requestInfo.info.payloadFormat),
&requestInfo.info.payload, &requestInfo.info.payloadSize))
diff --git a/resource/include/OCRepresentation.h b/resource/include/OCRepresentation.h
index d7b079c..2f005a1 100644
--- a/resource/include/OCRepresentation.h
+++ b/resource/include/OCRepresentation.h
@@ -106,6 +106,10 @@ namespace OC
InterfaceType getInterfaceType() const;
+ void setIsCollectionResource(bool isColResource);
+
+ bool isCollectionResource() const;
+
void addChild(const OCRepresentation&);
void clearChildren();
@@ -480,6 +484,7 @@ namespace OC
std::vector<std::string> m_dataModelVersions;
InterfaceType m_interfaceType;
+ bool m_isCollectionResource;
};
std::ostream& operator <<(std::ostream& os, const OCRepresentation::AttributeItem& ai);
diff --git a/resource/include/OCResourceResponse.h b/resource/include/OCResourceResponse.h
index bbe5455..23838ed 100644
--- a/resource/include/OCResourceResponse.h
+++ b/resource/include/OCResourceResponse.h
@@ -52,7 +52,8 @@ namespace OC
m_representation{},
m_requestHandle{nullptr},
m_resourceHandle{nullptr},
- m_responseResult{}
+ m_responseResult{},
+ m_isCollectionResource{}
{
}
@@ -64,7 +65,8 @@ namespace OC
m_representation(std::move(o.m_representation)),
m_requestHandle(std::move(o.m_requestHandle)),
m_resourceHandle(std::move(o.m_resourceHandle)),
- m_responseResult(std::move(o.m_responseResult))
+ m_responseResult(std::move(o.m_responseResult)),
+ m_isCollectionResource(std::move(o.m_isCollectionResource))
{
}
OCResourceResponse& operator=(OCResourceResponse&& o)
@@ -76,6 +78,7 @@ namespace OC
m_requestHandle = std::move(o.m_requestHandle);
m_resourceHandle = std::move(o.m_resourceHandle);
m_responseResult = std::move(o.m_responseResult);
+ m_isCollectionResource = std::move(o.m_isCollectionResource);
}
#else
OCResourceResponse(OCResourceResponse&&) = default;
@@ -145,9 +148,33 @@ namespace OC
* @param rep reference to the resource's representation
* @param iface specifies the interface
*/
+ void setResourceRepresentation(OCRepresentation& rep, std::string iface,
+ bool isCollectionResource)
+ {
+ m_interface = iface;
+ m_representation = rep;
+ m_isCollectionResource = isCollectionResource;
+ }
+
+ /**
+ * API to set the entire resource attribute representation
+ * @param rep rvalue reference to the resource's representation
+ * @param iface specifies the interface
+ */
+ void setResourceRepresentation(OCRepresentation&& rep, std::string iface,
+ bool isCollectionResource) {
+ setResourceRepresentation(rep, iface, isCollectionResource);
+ }
+
+ /**
+ * API to set the entire resource attribute representation
+ * @param rep reference to the resource's representation
+ * @param iface specifies the interface
+ */
void setResourceRepresentation(OCRepresentation& rep, std::string iface) {
m_interface = iface;
m_representation = rep;
+ m_isCollectionResource = false;
}
/**
@@ -167,6 +194,7 @@ namespace OC
// Call the default
m_interface = DEFAULT_INTERFACE;
m_representation = rep;
+ m_isCollectionResource = false;
}
/**
@@ -185,6 +213,7 @@ namespace OC
OCRequestHandle m_requestHandle;
OCResourceHandle m_resourceHandle;
OCEntityHandlerResult m_responseResult;
+ bool m_isCollectionResource;
private:
friend class InProcServerWrapper;
@@ -207,6 +236,8 @@ namespace OC
first.setInterfaceType(InterfaceType::DefaultParent);
}
+ first.setIsCollectionResource(m_isCollectionResource);
+
inf.addRepresentation(first);
for(const OCRepresentation& rep : m_representation.getChildren())
@@ -250,6 +281,14 @@ namespace OC
}
/**
+ * Get the resource type collection/non-collection
+ */
+ bool isCollectionResource() const
+ {
+ return m_isCollectionResource;
+ }
+
+ /**
* This API retrieves the request handle
*
* @return OCRequestHandle value
diff --git a/resource/src/OCRepresentation.cpp b/resource/src/OCRepresentation.cpp
index 970a2fb..1d0d029 100644
--- a/resource/src/OCRepresentation.cpp
+++ b/resource/src/OCRepresentation.cpp
@@ -83,9 +83,13 @@ namespace OC
if (!root)
{
root = r.getPayload();
- if (r.getInterfaceType() == InterfaceType::BatchParent)
+ if (r.isCollectionResource())
{
- root->ifType = PAYLOAD_BATCH_INTERFACE;
+ root->repType = PAYLOAD_REP_ARRAY;
+ }
+ else
+ {
+ root->repType = PAYLOAD_REP_OBJECT_ARRAY;
}
}
else
@@ -403,6 +407,16 @@ namespace OC
return m_interfaceType;
}
+ void OCRepresentation::setIsCollectionResource(bool isColResource)
+ {
+ m_isCollectionResource = isColResource;
+ }
+
+ bool OCRepresentation::isCollectionResource() const
+ {
+ return m_isCollectionResource;
+ }
+
size_t calcArrayDepth(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
{
if (dimensions[0] == 0)