replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocpayloadconvert.c
old mode 100644 (file)
new mode 100755 (executable)
index 40c8399..daa9003
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+#ifdef ARDUINO
+#define __STDC_LIMIT_MACROS
+#endif
+
 #include "ocpayloadcbor.h"
+#include "platform_features.h"
 #include <stdlib.h>
 #include "oic_malloc.h"
+#include "oic_string.h"
 #include "logger.h"
 #include "ocpayload.h"
 #include "ocrandom.h"
 #include "ocresourcehandler.h"
 #include "cbor.h"
 
-#define TAG PCF("OCPayloadConvert")
+#define TAG "OIC_RI_PAYLOADCONVERT"
+
+// Arbitrarily chosen size that seems to contain the majority of packages
+#define INIT_SIZE (255)
+
+// Discovery Links Map Length.
+#define LINKS_MAP_LEN 4
+
+// Functions all return either a CborError, or a negative version of the OC_STACK return values
+static int64_t OCConvertPayloadHelper(OCPayload *payload, uint8_t *outPayload, size_t *size);
+static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *outPayload,
+        size_t *size);
+static int64_t OCConvertRepPayload(OCRepPayload *payload, uint8_t *outPayload, size_t *size);
+static int64_t OCConvertRepMap(CborEncoder *map, const OCRepPayload *payload);
+#ifdef WITH_PRESENCE
+static int64_t OCConvertPresencePayload(OCPresencePayload *payload, uint8_t *outPayload,
+        size_t *size);
+#endif
+static int64_t OCConvertSecurityPayload(OCSecurityPayload *payload, uint8_t *outPayload,
+        size_t *size);
+static int64_t OCConvertSingleRepPayload(CborEncoder *parent, const OCRepPayload *payload);
+static int64_t OCConvertArray(CborEncoder *parent, const OCRepPayloadValueArray *valArray);
+
+static int64_t AddTextStringToMap(CborEncoder *map, const char *key, size_t keylen,
+        const char *value);
+static int64_t ConditionalAddTextStringToMap(CborEncoder *map, const char *key, size_t keylen,
+        const char *value);
 
-static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
-        size_t* size);
-static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
-        size_t* size);
-static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
-        size_t* size);
-static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size);
-static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload, uint8_t** outPayload,
-        size_t* size);
-static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
-        size_t* size);
+OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size)
+{
+    // TinyCbor Version 47a78569c0 or better on master is required for the re-allocation
+    // strategy to work.  If you receive the following assertion error, please do a git-pull
+    // from the extlibs/tinycbor/tinycbor directory
+    #define CborNeedsUpdating  (((unsigned int)CborErrorOutOfMemory) < ((unsigned int)CborErrorDataTooLarge))
+    OC_STATIC_ASSERT(!CborNeedsUpdating, "tinycbor needs to be updated to at least 47a78569c0");
+    #undef CborNeedsUpdating
+
+    OCStackResult ret = OC_STACK_INVALID_PARAM;
+    int64_t err;
+    uint8_t *out = NULL;
+    size_t curSize = INIT_SIZE;
+
+    VERIFY_PARAM_NON_NULL(TAG, payload, "Input param, payload is NULL");
+    VERIFY_PARAM_NON_NULL(TAG, outPayload, "OutPayload parameter is NULL");
+    VERIFY_PARAM_NON_NULL(TAG, size, "size parameter is NULL");
+
+    OIC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);
+    if (PAYLOAD_TYPE_SECURITY == payload->type)
+    {
+        size_t securityPayloadSize = ((OCSecurityPayload *)payload)->payloadSize;
+        if (securityPayloadSize > 0)
+        {
+            out = (uint8_t *)OICCalloc(1, ((OCSecurityPayload *)payload)->payloadSize);
+            VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate security payload");
+        }
+    }
+    if (out == NULL)
+    {
+        out = (uint8_t *)OICCalloc(1, curSize);
+        VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate payload");
+    }
+    err = OCConvertPayloadHelper(payload, out, &curSize);
+    ret = OC_STACK_NO_MEMORY;
 
-bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
-        const char* value);
+    if (err == CborErrorOutOfMemory)
+    {
+        // reallocate "out" and try again!
+        uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
+        VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
+        memset(out2, 0, curSize);
+        out = out2;
+        err = OCConvertPayloadHelper(payload, out, &curSize);
+        while (err == CborErrorOutOfMemory)
+        {
+            uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
+            VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
+            memset(out2, 0, curSize);
+            out = out2;
+            err = OCConvertPayloadHelper(payload, out, &curSize);
+        }
+    }
 
-bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
-        const char* value);
+    if (err == CborNoError)
+    {
+        if (curSize < INIT_SIZE && PAYLOAD_TYPE_SECURITY != payload->type)
+        {
+            uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
+            VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
+            out = out2;
+        }
 
+        *size = curSize;
+        *outPayload = out;
+        OIC_LOG_V(DEBUG, TAG, "Payload Size: %zd Payload : ", *size);
+        OIC_LOG_BUFFER(DEBUG, TAG, *outPayload, *size);
+        return OC_STACK_OK;
+    }
 
-OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size)
+    //TODO: Proper conversion from CborError to OCStackResult.
+    ret = (OCStackResult)-err;
+
+exit:
+    OICFree(out);
+    return ret;
+}
+
+static int64_t OCConvertPayloadHelper(OCPayload* payload, uint8_t* outPayload, size_t* size)
 {
-    OC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);
     switch(payload->type)
     {
         case PAYLOAD_TYPE_DISCOVERY:
             return OCConvertDiscoveryPayload((OCDiscoveryPayload*)payload, outPayload, size);
-        case PAYLOAD_TYPE_DEVICE:
-            return OCConvertDevicePayload((OCDevicePayload*)payload, outPayload, size);
-        case PAYLOAD_TYPE_PLATFORM:
-            return OCConvertPlatformPayload((OCPlatformPayload*)payload, outPayload, size);
         case PAYLOAD_TYPE_REPRESENTATION:
             return OCConvertRepPayload((OCRepPayload*)payload, outPayload, size);
+#ifdef WITH_PRESENCE
         case PAYLOAD_TYPE_PRESENCE:
             return OCConvertPresencePayload((OCPresencePayload*)payload, outPayload, size);
+#endif
         case PAYLOAD_TYPE_SECURITY:
             return OCConvertSecurityPayload((OCSecurityPayload*)payload, outPayload, size);
         default:
-            OC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
-            return OC_STACK_NOTIMPL;
+            OIC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
+            return CborErrorUnknownType;
     }
 }
 
-static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
-        size_t* size)
+static int64_t checkError(int64_t err, CborEncoder* encoder, uint8_t* outPayload, size_t* size)
 {
-    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
-    *size = MAX_REQUEST_LENGTH;
-
-    if(!*outPayload)
+    if (err == CborErrorOutOfMemory)
     {
-        return OC_STACK_NO_MEMORY;
+        *size += cbor_encoder_get_extra_bytes_needed(encoder);
+        return err;
     }
-
-    CborEncoder encoder;
-    bool err = false;
-
-    cbor_encoder_init(&encoder, *outPayload, *size, 0);
-
-    CborEncoder rootArray;
-    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
-    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_SECURITY);
-
-    CborEncoder map;
-
-    err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
-
-    if(payload->securityData)
+    else if (err != CborNoError)
     {
-        err = err || AddTextStringToMap(&map, OC_RSRVD_REPRESENTATION,
-                sizeof(OC_RSRVD_REPRESENTATION) - 1,
-                payload->securityData);
+        OIC_LOG_V(ERROR, TAG, "Convert Payload failed : %s", cbor_error_string(err));
+        return err;
     }
-
-    err = err || cbor_encoder_close_container(&rootArray, &map);
-
-    err = err || cbor_encoder_close_container(&encoder, &rootArray);
-
-    if(err)
+    else
     {
-        OC_LOG_V(ERROR, TAG, "Convert Security Payload failed", err);
-        OICFree(*outPayload);
-        return OC_STACK_ERROR;
+        *size = cbor_encoder_get_buffer_size(encoder, outPayload);
+        return err;
     }
+}
 
-    *size = encoder.ptr - *outPayload;
-    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
-
-    if(!tempPayload)
-    {
-        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
-        OICFree(*outPayload);
-        return OC_STACK_ERROR;
-    }
+static int64_t OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t* outPayload,
+        size_t* size)
+{
+    memcpy(outPayload, payload->securityData, payload->payloadSize);
+    *size = payload->payloadSize;
 
-    *outPayload = tempPayload;
-    return OC_STACK_OK;
+    return CborNoError;
 }
 
-static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
-        size_t* size)
+static int64_t OCStringLLJoin(CborEncoder *map, char *type, OCStringLL *val)
 {
-    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
-    *size = MAX_REQUEST_LENGTH;
+    uint16_t count = 0;
+    int64_t err = CborNoError;
 
-    if(!*outPayload)
+    for (OCStringLL *temp = val; temp; temp = temp->next)
     {
-        return OC_STACK_NO_MEMORY;
+        ++count;
+    }
+    if (count > 0)
+    {
+        CborEncoder array;
+        err |= cbor_encode_text_string(map, type, strlen(type));
+        err |= cbor_encoder_create_array(map, &array, count);
+        while (val)
+        {
+            err |= cbor_encode_text_string(&array, val->value, strlen(val->value));
+            val = val->next;
+        }
+        err |= cbor_encoder_close_container(map, &array);
     }
 
-    CborEncoder encoder = {};
-    bool err = false;
-    size_t resourceCount =  OCDiscoveryPayloadGetResourceCount(payload);
+    return err;
+}
 
-    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *outPayload,
+                                         size_t *size)
+{
+    CborEncoder encoder;
+    int64_t err = CborNoError;
+
+    cbor_encoder_init(&encoder, outPayload, *size, 0);
+
+    /*
+    The format for the payload is "modelled" as JSON.
+
+    [                                                  // rootArray
+        {                                              // rootMap
+            "di" : UUID,                               // device ID
+            "rt": ["oic.wk.res"]
+            "n":"MyDevice"
+            "if":"oic.if.ll oic.if.baseline"
+            "di": "0685B960-736F-46F7-BEC0-9E6CBD61ADC1",
+            links :[                                   // linksArray contains maps of resources
+                        {
+                            href, rt, if, policy       // Resource 1
+                        },
+                        {
+                            href, rt, if, policy       // Resource 2
+                        },
+                        .
+                        .
+                        .
+                    ]
+        }
+        {                                              // rootMap
+            ...
+        }
+    ]
+    */
 
+    // Open the main root array
     CborEncoder rootArray;
-    err = err || cbor_encoder_create_array(&encoder, &rootArray, 1 + resourceCount);
-    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DISCOVERY);
+    err |= cbor_encoder_create_array(&encoder, &rootArray, 1);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery root array");
 
-    for(size_t i = 0; i < resourceCount; ++i)
+    while (payload && payload->resources)
     {
-        CborEncoder map;
-        OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
-
-        if(!resource)
+        // Open the root map in the root array
+        CborEncoder rootMap;
+        err |= cbor_encoder_create_map(&rootArray, &rootMap, CborIndefiniteLength);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery map");
+
+        // Insert Name
+        err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_NAME,
+                sizeof(OC_RSRVD_DEVICE_NAME) - 1, payload->name);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting name");
+
+        // Insert Device ID into the root map
+        err |= AddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1,
+                payload->sid);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting device id");
+
+        // Insert Resource Type
+        err |= OCStringLLJoin(&rootMap, OC_RSRVD_RESOURCE_TYPE, payload->type);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting RT");
+
+        // Insert interfaces
+        if (payload->iface)
         {
-            OICFree(*outPayload);
-            return OC_STACK_INVALID_PARAM;
+            err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->iface);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types tag/value");
         }
 
-        err = err || cbor_encoder_create_map(&rootArray, &map, 3);
-        // Uri
-        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF,
-                sizeof(OC_RSRVD_HREF) - 1,
-                resource->uri);
-
-        // Server ID
-        err = err || cbor_encode_text_string(&map, OC_RSRVD_SERVER_INSTANCE_ID,
-                sizeof(OC_RSRVD_SERVER_INSTANCE_ID) - 1);
-        err = err || cbor_encode_byte_string(&map, resource->sid, UUID_SIZE);
-        // Prop Tag
+        // Insert baseURI if present
+        err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_BASE_URI,
+                                             sizeof(OC_RSRVD_BASE_URI) - 1,
+                                             payload->baseURI);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting baseURI");
+
+        // Insert Links into the root map.
+        CborEncoder linkArray;
+        err |= cbor_encode_text_string(&rootMap, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) - 1);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array tag");
+        size_t resourceCount =  OCDiscoveryPayloadGetResourceCount(payload);
+        err |= cbor_encoder_create_array(&rootMap, &linkArray, resourceCount);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array");
+
+        for (size_t i = 0; i < resourceCount; ++i)
         {
-            CborEncoder propMap;
-            err = err || cbor_encode_text_string(&map, OC_RSRVD_PROPERTY,
-                    sizeof(OC_RSRVD_PROPERTY) -1 );
-            err = err || cbor_encoder_create_map(&map, &propMap, 3);
+            CborEncoder linkMap;
+            OCResourcePayload *resource = OCDiscoveryPayloadGetResource(payload, i);
+            VERIFY_PARAM_NON_NULL(TAG, resource, "Failed retrieving resource");
 
-            // Resource Type
-            {
-                CborEncoder rtArray;
-                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE,
-                    sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
-                err = err || cbor_encoder_create_array(&propMap, &rtArray, CborIndefiniteLength);
+            // resource map inside the links array.
+            err |= cbor_encoder_create_map(&linkArray, &linkMap, LINKS_MAP_LEN);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map");
 
-                OCStringLL* rtPtr = resource->types;
-                while(rtPtr)
-                {
-                    err = err || cbor_encode_text_string(&rtArray, rtPtr->value,
-                            strlen(rtPtr->value));
-                    rtPtr = rtPtr->next;
-                }
+            // Below are insertions of the resource properties into the map.
+            // Uri
+            err |= AddTextStringToMap(&linkMap, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
+                    resource->uri);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding uri to links map");
 
-                err = err || cbor_encoder_close_container(&propMap, &rtArray);
+            // Resource Type
+            if (resource->types)
+            {
+                err |= OCStringLLJoin(&linkMap, OC_RSRVD_RESOURCE_TYPE, resource->types);
+                VERIFY_CBOR_SUCCESS(TAG, err,
+                                    "Failed adding resourceType tag/value to links map");
             }
-
             // Interface Types
+            if (resource->interfaces)
             {
-                CborEncoder ifArray;
-                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE,
-                        sizeof(OC_RSRVD_INTERFACE) - 1);
-                err = err || cbor_encoder_create_array(&propMap, &ifArray, CborIndefiniteLength);
-                OCStringLL* ifPtr = resource->interfaces;
-
-                while(ifPtr)
-                {
-                    err = err || cbor_encode_text_string(&ifArray, ifPtr->value,
-                        strlen(ifPtr->value));
-                    ifPtr= ifPtr->next;
-                }
-
-                err = err || cbor_encoder_close_container(&propMap, &ifArray);
+                err |= OCStringLLJoin(&linkMap, OC_RSRVD_INTERFACE, resource->interfaces);
+                VERIFY_CBOR_SUCCESS(TAG, err,
+                                    "Failed adding interfaces tag/value to links map");
             }
+
             // Policy
+            CborEncoder policyMap;
+            err |= cbor_encode_text_string(&linkMap, OC_RSRVD_POLICY,
+                                           sizeof(OC_RSRVD_POLICY) - 1);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy tag to links map");
+            err |= cbor_encoder_create_map(&linkMap, &policyMap, CborIndefiniteLength);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy map to links map");
+
+            // Bitmap
+            err |=  cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
+                                            sizeof(OC_RSRVD_BITMAP) - 1);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap tag to policy map");
+            err |= cbor_encode_uint(&policyMap, resource->bitmap);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap value to policy map");
+
+            // Secure
+            err |= cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
+                                           sizeof(OC_RSRVD_SECURE) - 1);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure tag to policy map");
+            err |= cbor_encode_boolean(&policyMap, resource->secure);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure value to policy map");
+
+            if (resource->secure || payload->baseURI)
             {
-                CborEncoder policyMap;
-                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_POLICY,
-                        sizeof(OC_RSRVD_POLICY) - 1);
-                err = err || cbor_encoder_create_map(&propMap, &policyMap, CborIndefiniteLength);
+                err |= cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
+                                               sizeof(OC_RSRVD_HOSTING_PORT) - 1);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port tag");
+                err |= cbor_encode_uint(&policyMap, resource->port);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port value");
+            }
 
-                // Bitmap
-                err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
-                        sizeof(OC_RSRVD_BITMAP) - 1);
-                err = err || cbor_encode_uint(&policyMap, resource->bitmap);
+#ifdef TCP_ADAPTER
+#ifdef __WITH_TLS__
+            // tls
+            if (resource->secure)
+            {
+                err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TLS_PORT,
+                                               sizeof(OC_RSRVD_TLS_PORT) - 1);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp secure port tag");
+                err |= cbor_encode_uint(&policyMap, resource->tcpPort);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp secure port value");
+            }
 
-                if(resource->secure)
-                {
-                    err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
-                            sizeof(OC_RSRVD_SECURE) - 1);
-                    err = err || cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE);
+            // tcp
+            else
+#endif
+            {
+                err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TCP_PORT,
+                                               sizeof(OC_RSRVD_TCP_PORT) - 1);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port tag");
+                err |= cbor_encode_uint(&policyMap, resource->tcpPort);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port value");
+            }
+#endif
 
-                    if(resource->port != 0)
-                    {
-                        err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
-                                sizeof(OC_RSRVD_HOSTING_PORT) - 1);
-                        err = err || cbor_encode_uint(&policyMap, resource->port);
-                    }
-                }
+            err |= cbor_encoder_close_container(&linkMap, &policyMap);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing policy map");
 
-                err = err || cbor_encoder_close_container(&propMap, &policyMap);
-            }
-            // Close
-            err = err || cbor_encoder_close_container(&map, &propMap);
+            // Finsihed encoding a resource, close the map.
+            err |= cbor_encoder_close_container(&linkArray, &linkMap);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link map");
         }
-        // Close Item
-        err = err || cbor_encoder_close_container(&rootArray, &map);
-    }
-    // Close main array
-    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+        // Close links array inside the root map.
+        err |= cbor_encoder_close_container(&rootMap, &linkArray);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link array");
+        // close root map inside the root array.
+        err |= cbor_encoder_close_container(&rootArray, &rootMap);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root map");
 
-    if(err)
-    {
-        OC_LOG_V(ERROR, TAG, "Convert Discovery Payload failed with : %d", err);
-        return OC_STACK_ERROR;
+        payload = payload->next;
     }
 
-    *size = encoder.ptr - *outPayload;
-    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+    // Close the final root array.
+    err |= cbor_encoder_close_container(&encoder, &rootArray);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array");
 
-    if(!tempPayload)
-    {
-        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
-        OICFree(*outPayload);
-        return OC_STACK_ERROR;
-    }
-
-    *outPayload = tempPayload;
-    return OC_STACK_OK;
+exit:
+    return checkError(err, &encoder, outPayload, size);
 }
 
-static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
-        size_t* size)
+static int64_t OCConvertArrayItem(CborEncoder *array, const OCRepPayloadValueArray *valArray,
+        size_t index)
 {
-    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
-    *size = MAX_REQUEST_LENGTH;
-
-    if(!*outPayload)
-    {
-        return OC_STACK_NO_MEMORY;
-    }
-
-    CborEncoder encoder = {};
-    bool err = false;
-
-    cbor_encoder_init(&encoder, *outPayload, *size, 0);
-    CborEncoder rootArray;
-    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
-    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DEVICE);
-
-    {
-        CborEncoder map;
-        err = err || cbor_encoder_create_map(&rootArray, &map, 2);
-
-        // uri
-        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
-                payload->uri);
-
-        // Rep Map
-        {
-            CborEncoder repMap;
-            err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
-                    sizeof(OC_RSRVD_REPRESENTATION) - 1);
-            err = err || cbor_encoder_create_map(&map, &repMap, 4);
-
-            // Device ID
-            err = err || cbor_encode_text_string(&repMap, OC_RSRVD_DEVICE_ID,
-                    sizeof(OC_RSRVD_DEVICE_ID) - 1);
-            err = err || cbor_encode_byte_string(&repMap, payload->sid, UUID_SIZE);
-
-            // Device Name
-            err = err || AddTextStringToMap(&repMap, OC_RSRVD_DEVICE_NAME,
-                    sizeof(OC_RSRVD_DEVICE_NAME) - 1,
-                    payload->deviceName);
-
-            // Device Spec Version
-            err = err || AddTextStringToMap(&repMap, OC_RSRVD_SPEC_VERSION,
-                    sizeof(OC_RSRVD_SPEC_VERSION) - 1,
-                    payload->specVersion);
-
-            // Device data Model Version
-            err = err || AddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION,
-                    sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1,
-                    payload->dataModelVersion);
-
-            err = err || cbor_encoder_close_container(&map, &repMap);
-        }
-
-        // Close Map
-        err = err || cbor_encoder_close_container(&rootArray, &map);
-    }
-
-    // Close main array
-    err = err || cbor_encoder_close_container(&encoder, &rootArray);
-
-    if(err)
+    int64_t err = CborNoError;
+    switch (valArray->type)
     {
-        OC_LOG_V(ERROR, TAG, "Convert Device Payload failed with : %d", err);
-        return OC_STACK_ERROR;
-    }
-
-    *size = encoder.ptr - *outPayload;
-    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
-
-    if(!tempPayload)
-    {
-        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
-        OICFree(*outPayload);
-        return OC_STACK_ERROR;
+        case OCREP_PROP_NULL:
+            OIC_LOG(ERROR, TAG, "ConvertArray Invalid NULL");
+            err = CborUnknownError;
+            break;
+        case OCREP_PROP_INT:
+            if (valArray->iArray != 0)
+            {
+                err |= cbor_encode_int(array, valArray->iArray[index]);
+            }
+            break;
+        case OCREP_PROP_DOUBLE:
+            if (valArray->dArray != 0)
+            {
+                err |= cbor_encode_double(array, valArray->dArray[index]);
+            }
+            break;
+        case OCREP_PROP_BOOL:
+            if (valArray->bArray != 0)
+            {
+                err |= cbor_encode_boolean(array, valArray->bArray[index]);
+            }
+            break;
+        case OCREP_PROP_STRING:
+            if (valArray->strArray != 0)
+            {
+                err |= (!valArray->strArray[index]) ? cbor_encode_null(array) : cbor_encode_text_string(array,
+                    valArray->strArray[index], strlen(valArray->strArray[index]));
+            }
+            break;
+        case OCREP_PROP_BYTE_STRING:
+            err |= (!valArray->ocByteStrArray[index].len) ? cbor_encode_null(array) : cbor_encode_byte_string(array,
+                valArray->ocByteStrArray[index].bytes, valArray->ocByteStrArray[index].len);
+            break;
+        case OCREP_PROP_OBJECT:
+            if (valArray->objArray != 0)
+            {
+                err |= (!valArray->objArray[index]) ? cbor_encode_null(array): OCConvertRepMap(array,
+                        valArray->objArray[index]);
+            }
+            break;
+        case OCREP_PROP_ARRAY:
+            OIC_LOG(ERROR, TAG, "ConvertArray Invalid child array");
+            err = CborUnknownError;
+            break;
     }
 
-    *outPayload = tempPayload;
-    return OC_STACK_OK;
+    return err;
 }
 
-static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
-        size_t* size)
+static int64_t OCConvertArray(CborEncoder *parent, const OCRepPayloadValueArray *valArray)
 {
-    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
-    *size = MAX_REQUEST_LENGTH;
-
-    if(!*outPayload)
+    int64_t err = CborNoError;
+    CborEncoder array;
+    err |= cbor_encoder_create_array(parent, &array, valArray->dimensions[0]);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating rep array");
+    // empty array
+    if (valArray->dimensions[0] == 0)
     {
-        return OC_STACK_NO_MEMORY;
+        err |= OCConvertArrayItem(&array, valArray, 0);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep array value");
     }
-
-    CborEncoder encoder = {};
-    bool err = false;
-
-    cbor_encoder_init(&encoder, *outPayload, *size, 0);
-    CborEncoder rootArray;
-    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
-    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PLATFORM);
+    else
     {
-        CborEncoder map;
-        err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
-
-        // uri
-        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
-                payload->uri);
-
-        // Rep Map
+        for (size_t i = 0; i < valArray->dimensions[0]; ++i)
         {
-            CborEncoder repMap;
-            err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
-                    sizeof(OC_RSRVD_REPRESENTATION) - 1);
-            err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
-
-            // Platform ID
-            err = err || AddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_ID,
-                    sizeof(OC_RSRVD_PLATFORM_ID) - 1,
-                    payload->info.platformID);
-
-            // MFG Name
-            err = err || AddTextStringToMap(&repMap, OC_RSRVD_MFG_NAME,
-                    sizeof(OC_RSRVD_MFG_NAME) - 1,
-                    payload->info.manufacturerName);
-
-            // MFG Url
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_URL,
-                    sizeof(OC_RSRVD_MFG_URL) - 1,
-                    payload->info.manufacturerUrl);
-
-            // Model Num
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MODEL_NUM,
-                    sizeof(OC_RSRVD_MODEL_NUM) - 1,
-                    payload->info.modelNumber);
-
-            // Date of Mfg
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_DATE,
-                    sizeof(OC_RSRVD_MFG_DATE) - 1,
-                    payload->info.dateOfManufacture);
-
-            // Platform Version
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_VERSION,
-                    sizeof(OC_RSRVD_PLATFORM_VERSION) - 1,
-                    payload->info.platformVersion);
-
-            // OS Version
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_OS_VERSION,
-                    sizeof(OC_RSRVD_OS_VERSION) - 1,
-                    payload->info.operatingSystemVersion);
-
-            // Hardware Version
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_HARDWARE_VERSION,
-                    sizeof(OC_RSRVD_HARDWARE_VERSION) - 1,
-                    payload->info.hardwareVersion);
-
-            // Firmware Version
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_FIRMWARE_VERSION,
-                    sizeof(OC_RSRVD_FIRMWARE_VERSION) - 1,
-                    payload->info.firmwareVersion);
-
-            // Support URL
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SUPPORT_URL,
-                    sizeof(OC_RSRVD_SUPPORT_URL) - 1,
-                    payload->info.supportUrl);
-
-            // System Time
-            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SYSTEM_TIME,
-                    sizeof(OC_RSRVD_SYSTEM_TIME) - 1,
-                    payload->info.systemTime);
-            err = err || cbor_encoder_close_container(&map, &repMap);
-        }
-
-        // Close Map
-        err = err || cbor_encoder_close_container(&rootArray, &map);
-    }
-
-    // Close main array
-    err = err || cbor_encoder_close_container(&encoder, &rootArray);
-
-    if(err)
-    {
-        OC_LOG_V(ERROR, TAG, "Convert Platform Payload failed with : %d", err);
-        return OC_STACK_ERROR;
-    }
-
-    *size = encoder.ptr - *outPayload;
-    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+            if (0 != valArray->dimensions[1])
+            {
+                CborEncoder array2;
+                err |= cbor_encoder_create_array(&array, &array2, valArray->dimensions[1]);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating rep array2");
 
-    if(!tempPayload)
-    {
-        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
-        OICFree(*outPayload);
-        return OC_STACK_ERROR;
+                for (size_t j = 0; j < valArray->dimensions[1]; ++j)
+                {
+                    if (0 != valArray->dimensions[2])
+                    {
+                        CborEncoder array3;
+                        err |= cbor_encoder_create_array(&array2, &array3, valArray->dimensions[2]);
+                        VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating rep array3");
+
+                        for(size_t k = 0; k < valArray->dimensions[2]; ++k)
+                        {
+                            err |= OCConvertArrayItem(&array3, valArray,
+                                j * valArray->dimensions[2] +
+                                i * valArray->dimensions[2] * valArray->dimensions[1] +
+                                k);
+                            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep array3 value");
+                        }
+                        err |= cbor_encoder_close_container(&array2, &array3);
+                        VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing rep array3");
+                    }
+                    else
+                    {
+                        err |= OCConvertArrayItem(&array2, valArray, i * valArray->dimensions[1] + j);
+                        VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep array2 value");
+                    }
+                }
+                err |= cbor_encoder_close_container(&array, &array2);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing rep array2");
+            }
+            else
+            {
+                err |= OCConvertArrayItem(&array, valArray, i);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep array value");
+            }
+        }
     }
+    err |= cbor_encoder_close_container(parent, &array);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing rep array");
 
-    *outPayload = tempPayload;
-
-    return OC_STACK_OK;
+exit:
+    return err;
 }
 
-static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload);
-
-static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray)
+static int64_t OCConvertRepMap(CborEncoder *map, const OCRepPayload *payload)
 {
-    CborEncoder array;
-    bool err = false;
+    int64_t err = CborNoError;
+    CborEncoder repMap;
+    err |= cbor_encoder_create_map(map, &repMap, CborIndefiniteLength);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating rep map");
+    err |= OCConvertSingleRepPayload(&repMap, payload);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed converting single rep payload");
+    err |= cbor_encoder_close_container(map, &repMap);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing rep map");
+exit:
+    return err;
+}
 
-    err = err || cbor_encoder_create_array(parent, &array, CborIndefiniteLength);
-    err = err || cbor_encode_uint(&array, valArray->type);
-    for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++i)
+static int64_t OCConvertSingleRepPayload(CborEncoder *repMap, const OCRepPayload *payload)
+{
+    int64_t err = CborNoError;
+    OCRepPayloadValue *value = payload->values;
+    while (value)
     {
-        err = err || cbor_encode_uint(&array, valArray->dimensions[i]);
-    }
-
-    size_t dimTotal = calcDimTotal(valArray->dimensions);
+        err |= cbor_encode_text_string(repMap, value->name, strlen(value->name));
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tag name");
 
-    for(size_t i = 0; i < dimTotal; ++i)
-    {
-        switch(valArray->type)
+        switch (value->type)
         {
             case OCREP_PROP_NULL:
-                OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid NULL"));
-                err = CborUnknownError;
+                err |= cbor_encode_null(repMap);
                 break;
             case OCREP_PROP_INT:
-                err = err || cbor_encode_int(&array, valArray->iArray[i]);
+                err |= cbor_encode_int(repMap, value->i);
                 break;
             case OCREP_PROP_DOUBLE:
-                err = err || cbor_encode_double(&array, valArray->dArray[i]);
+                err |= cbor_encode_double(repMap, value->d);
                 break;
             case OCREP_PROP_BOOL:
-                err = err || cbor_encode_boolean(&array, valArray->bArray[i]);
+                err |= cbor_encode_boolean(repMap, value->b);
                 break;
             case OCREP_PROP_STRING:
-                err = err || cbor_encode_text_string(&array, valArray->strArray[i],
-                        strlen(valArray->strArray[i]));
+                err |= cbor_encode_text_string(repMap, value->str, strlen(value->str));
+                break;
+            case OCREP_PROP_BYTE_STRING:
+                err |= cbor_encode_byte_string(repMap, value->ocByteStr.bytes, value->ocByteStr.len);
                 break;
             case OCREP_PROP_OBJECT:
-                err = OCConvertSingleRepPayload(&array, valArray->objArray[i]);
+                err |= OCConvertRepMap(repMap, value->obj);
                 break;
             case OCREP_PROP_ARRAY:
-                OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid child array"));
-                err = CborUnknownError;
+                err |= OCConvertArray(repMap, &value->arr);
+                break;
+            default:
+                OIC_LOG_V(ERROR, TAG, "Invalid Prop type: %d", value->type);
                 break;
         }
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding single rep value");
+        value = value->next;
     }
 
-    err = err || cbor_encoder_close_container(parent, &array);
+exit:
     return err;
 }
 
-static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload)
+static int64_t OCConvertRepPayload(OCRepPayload *payload, uint8_t *outPayload, size_t *size)
 {
-    bool err = false;
-    CborEncoder map;
-    err = err || cbor_encoder_create_map(parent, &map, CborIndefiniteLength);
+    CborEncoder encoder;
+    int64_t err = CborNoError;
 
-    // Uri
-    err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF,
-            sizeof(OC_RSRVD_HREF) - 1,
-            payload->uri);
+    cbor_encoder_init(&encoder, outPayload, *size, 0);
 
-    // Prop Map
-    // resource types, interfaces
-    if(payload->types || payload->interfaces)
+    size_t arrayCount = 0;
+    for (OCRepPayload *temp = payload; temp; temp = temp->next)
     {
-        OC_LOG_V(INFO, TAG, "Payload has types or interfaces");
-        err = err || cbor_encode_text_string(&map,
-                OC_RSRVD_PROPERTY,
-                sizeof(OC_RSRVD_PROPERTY) - 1);
-        CborEncoder propMap;
-        err = err || cbor_encoder_create_map(&map, &propMap, 2);
-
-        CborEncoder curArray;
-        if(payload->types)
-        {
-            err = err || cbor_encode_text_string(&propMap,
-                    OC_RSRVD_RESOURCE_TYPE,
-                    sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
-            err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
-            OCStringLL* val = payload->types;
-            while(val)
-            {
-                err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
-                val = val->next;
-            }
-            err = err || cbor_encoder_close_container(&propMap, &curArray);
-        }
-        if(payload->interfaces)
-        {
-            err = err || cbor_encode_text_string(&propMap,
-                    OC_RSRVD_INTERFACE,
-                    sizeof(OC_RSRVD_INTERFACE) - 1);
-            err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
-            OCStringLL* val = payload->interfaces;
-            while(val)
-            {
-                err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
-                val = val->next;
-            }
-            err = err || cbor_encoder_close_container(&propMap, &curArray);
-        }
-        err = err || cbor_encoder_close_container(&map, &propMap);
+        arrayCount++;
     }
-
-    // Rep Map
+    CborEncoder rootArray;
+    if (arrayCount > 1)
     {
-        CborEncoder repMap;
-        err = err || cbor_encode_text_string(&map,
-                OC_RSRVD_REPRESENTATION,
-                sizeof(OC_RSRVD_REPRESENTATION) - 1);
-        err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
-        OCRepPayloadValue* value = payload->values;
-        while(value)
-        {
-            err = err || cbor_encode_text_string(&repMap,
-                    value->name,
-                    strlen(value->name));
-            switch(value->type)
-            {
-                case OCREP_PROP_NULL:
-                    err = err || cbor_encode_null(&repMap);
-                    break;
-                case OCREP_PROP_INT:
-                    err = err || cbor_encode_int(&repMap,
-                            value->i);
-                    break;
-                case OCREP_PROP_DOUBLE:
-                    err = err || cbor_encode_double(&repMap,
-                            value->d);
-                    break;
-                case OCREP_PROP_BOOL:
-                    err = err || cbor_encode_boolean(&repMap,
-                            value->b);
-                    break;
-                case OCREP_PROP_STRING:
-                    err = err || cbor_encode_text_string(&repMap,
-                            value->str, strlen(value->str));
-                    break;
-                case OCREP_PROP_OBJECT:
-                    err = err || OCConvertSingleRepPayload(&repMap, value->obj);
-                    break;
-                case OCREP_PROP_ARRAY:
-                    err = err || OCConvertArray(&repMap, &value->arr);
-                    break;
-                default:
-                    OC_LOG_V(ERROR, TAG, "Invalid Prop type: %d",
-                            value->type);
-                    break;
-            }
-            value = value->next;
-        }
-
-        err = err || cbor_encoder_close_container(&map, &repMap);
+        err |= cbor_encoder_create_array(&encoder, &rootArray, arrayCount);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep root map");
     }
 
-    // Close Map
-    err = err || cbor_encoder_close_container(parent, &map);
-
-    return err;
-}
-
-static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size)
-{
-    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
-    *size = MAX_REQUEST_LENGTH;
-
-    if(!*outPayload)
+    while (payload != NULL && (err == CborNoError))
     {
-        return OC_STACK_NO_MEMORY;
-    }
+        CborEncoder rootMap;
+        err |= cbor_encoder_create_map(((arrayCount == 1)? &encoder: &rootArray),
+                                            &rootMap, CborIndefiniteLength);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating root map");
 
-    CborEncoder encoder = {};
-    bool err = false;
+        // Only in case of collection href is included.
+        if (arrayCount > 1 && payload->uri && strlen(payload->uri) > 0)
+        {
+            OIC_LOG(INFO, TAG, "Payload has uri");
+            err |= cbor_encode_text_string(&rootMap, OC_RSRVD_HREF, strlen(OC_RSRVD_HREF));
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep href tag");
+            err |= cbor_encode_text_string(&rootMap, payload->uri, strlen(payload->uri));
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep href value");
+        }
+        if (payload->types)
+        {
+            OIC_LOG(INFO, TAG, "Payload has types");
+            err |= OCStringLLJoin(&rootMap, OC_RSRVD_RESOURCE_TYPE, payload->types);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource type.");
+        }
+        if (payload->interfaces)
+        {
+            OIC_LOG(INFO, TAG, "Payload has interfaces");
+            err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->interfaces);
+            VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding platform interface type.");
+        }
 
-    cbor_encoder_init(&encoder, *outPayload, *size, 0);
-    CborEncoder rootArray;
-    err = err || cbor_encoder_create_array(&encoder, &rootArray, CborIndefiniteLength);
-    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_REPRESENTATION);
+        err |= OCConvertSingleRepPayload(&rootMap, payload);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting rep payload");
 
-    while(payload != NULL && !err)
-    {
-        err = err || OCConvertSingleRepPayload(&rootArray, payload);
+        // Close main array
+        err |= cbor_encoder_close_container(((arrayCount == 1) ? &encoder: &rootArray),
+                &rootMap);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root map");
         payload = payload->next;
     }
-
-    // Close main array
-    err = err || cbor_encoder_close_container(&encoder, &rootArray);
-
-    if(err)
+    if (arrayCount > 1)
     {
-        OC_LOG_V(ERROR, TAG, "Convert Rep Payload failed with : %d", err);
-        return OC_STACK_ERROR;
+        err |= cbor_encoder_close_container(&encoder, &rootArray);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array");
     }
 
-    *size = encoder.ptr - *outPayload;
-    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
-
-    if(!tempPayload)
-    {
-        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
-        OICFree(*outPayload);
-        return OC_STACK_ERROR;
-    }
-
-    *outPayload = tempPayload;
-
-    return OC_STACK_OK;
+exit:
+    return checkError(err, &encoder, outPayload, size);
 }
 
-static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload,
-        uint8_t** outPayload, size_t* size)
+#ifdef WITH_PRESENCE
+static int64_t OCConvertPresencePayload(OCPresencePayload *payload, uint8_t *outPayload,
+        size_t *size)
 {
-    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
-    *size = MAX_REQUEST_LENGTH;
-
-    if(!*outPayload)
-    {
-        return OC_STACK_NO_MEMORY;
-    }
-
-    CborEncoder encoder = {};
-    bool err = false;
-
-    cbor_encoder_init(&encoder, *outPayload, *size, 0);
-    CborEncoder rootArray;
-
-    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
-    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PRESENCE);
-
+    int64_t err = CborNoError;
+    CborEncoder encoder;
 
+    cbor_encoder_init(&encoder, outPayload, *size, 0);
     CborEncoder map;
-    err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+    err |= cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating presence map");
 
     // Sequence Number
-    err = err || cbor_encode_text_string(&map,
-            OC_RSRVD_NONCE,
-            sizeof(OC_RSRVD_NONCE) - 1);
-    err = err || cbor_encode_uint(&map, payload->sequenceNumber);
+    err |= cbor_encode_text_string(&map, OC_RSRVD_NONCE, sizeof(OC_RSRVD_NONCE) - 1);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding nonce tag to presence map");
+    err |= cbor_encode_uint(&map, payload->sequenceNumber);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding nonce value to presence map");
 
     // Max Age
-    err = err || cbor_encode_text_string(&map,
-            OC_RSRVD_TTL,
-            sizeof(OC_RSRVD_TTL) - 1);
-    err = err || cbor_encode_uint(&map, payload->maxAge);
+    err |= cbor_encode_text_string(&map, OC_RSRVD_TTL, sizeof(OC_RSRVD_TTL) - 1);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding ttl tag to presence map");
+    err |= cbor_encode_uint(&map, payload->maxAge);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding ttl value to presence map");
 
     // Trigger
-    const char* triggerStr = convertTriggerEnumToString(payload->trigger);
-    err = err || AddTextStringToMap(&map, OC_RSRVD_TRIGGER, sizeof(OC_RSRVD_TRIGGER) - 1,
-            triggerStr);
+    err |= cbor_encode_text_string(&map, OC_RSRVD_TRIGGER, sizeof(OC_RSRVD_TRIGGER) - 1);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding trigger tag to presence map");
+    err |= cbor_encode_simple_value(&map, payload->trigger);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding trigger value to presence map");
 
     // Resource type name
-    if(payload->trigger != OC_PRESENCE_TRIGGER_DELETE)
+    if (payload->trigger != OC_PRESENCE_TRIGGER_DELETE)
     {
-        err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_RESOURCE_TYPE,
+        err |= ConditionalAddTextStringToMap(&map, OC_RSRVD_RESOURCE_TYPE,
                 sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->resourceType);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource type to presence map");
     }
 
     // Close Map
-    err = err || cbor_encoder_close_container(&rootArray, &map);
-    err = err || cbor_encoder_close_container(&encoder, &rootArray);
-
-    if(err)
-    {
-        OC_LOG_V(ERROR, TAG, "Convert Presence Payload failed with : %d", err);
-        return OC_STACK_ERROR;
-    }
-
-    *size = encoder.ptr - *outPayload;
-    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+    err |= cbor_encoder_close_container(&encoder, &map);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing presence map");
 
-    if(!tempPayload)
-    {
-        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
-        OICFree(*outPayload);
-        return OC_STACK_ERROR;
-    }
-
-    *outPayload = tempPayload;
-
-    return OC_STACK_OK;
+exit:
+    return checkError(err, &encoder, outPayload, size);
 }
+#endif // WITH_PRESENCE
 
-bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+static int64_t AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
         const char* value)
 {
-    return cbor_encode_text_string(map, key, keylen) ||
-           cbor_encode_text_string(map, value, strlen(value));
+    int64_t err = cbor_encode_text_string(map, key, keylen);
+    if (CborNoError != err)
+    {
+        return err;
+    }
+    return cbor_encode_text_string(map, value, strlen(value));
 }
 
-bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
         const char* value)
 {
-    return value ? AddTextStringToMap(map, key, keylen, value) : false;
+    return value ? AddTextStringToMap(map, key, keylen, value) : 0;
 }