Parsing about a payload including resource information of multiple devices
authorJaehong Jo <jaehong.jo@samsung.com>
Fri, 8 Jul 2016 06:53:52 +0000 (15:53 +0900)
committerJon A. Cruz <jon@joncruz.org>
Thu, 14 Jul 2016 20:50:20 +0000 (20:50 +0000)
Assuming the siatuation that many servers published their resource information into resource directory(RD),
then the RD will send response including multiple device information for the discovery request by resouce type.
That means a response payload will be comprised of multiple device list including resource information.
But now, the resource client can parse only the first device's resource information..

There is the payload I tested as follow

[
    {    di=717111ce-31c1-47a0-81a1-3e39eca,
         links=[
                        {href=/q/resource_foo1, rt=core.foo, if=oic.if.baseline, p={bm=1}},
                        {href=/q/resource_foo2, rt=core.foo, if=oic.if.baseline, p={bm=1}}
                 ]
    },
    {    di=a7b77e75-e6d5-4158-af16-3a4dd95,
        links=[
                        {href=/q/resource_foo1, rt=core.foo, if=oic.if.baseline, p={bm=1}},
                        {href=/q/resource_foo2, rt=core.foo, if=oic.if.baseline, p={bm=1}}
                ]
    }
]

Change-Id: Ic1f58c473ab91a497508b2425a4ad07692120054
Signed-off-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9245
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jon@joncruz.org>
resource/csdk/stack/include/octypes.h
resource/csdk/stack/include/payload_logging.h
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/src/ocpayloadconvert.c
resource/csdk/stack/src/ocpayloadparse.c
resource/include/OCSerialization.h

index 43eb1aa..7ea3819 100644 (file)
@@ -1199,7 +1199,7 @@ typedef struct OCResourceCollectionPayload
     struct OCResourceCollectionPayload *next;
 } OCResourceCollectionPayload;
 
-typedef struct
+typedef struct OCDiscoveryPayload
 {
     OCPayload base;
 
@@ -1224,6 +1224,9 @@ typedef struct
     /** This structure holds the old /oic/res response. */
     OCResourcePayload *resources;
 
+    /** Holding address of the next DiscoveryPayload. */
+    struct OCDiscoveryPayload *next;
+
 } OCDiscoveryPayload;
 
 /**
index d04b9cd..0939955 100644 (file)
@@ -167,66 +167,65 @@ INLINE_API void OCPayloadLogRep(LogLevel level, OCRepPayload* payload)
 INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payload)
 {
     OIC_LOG(level, PL_TAG, "Payload Type: Discovery");
-    int i = 1;
 
-    if(!payload->resources)
-    {
-        OIC_LOG(level, PL_TAG, "\tNO Resources");
-        return;
-    }
-    OIC_LOG_V(level, PL_TAG, "\tSID: %s", payload->sid);
-    if (payload->baseURI)
-    {
-        OIC_LOG_V(level, PL_TAG, "\tBase URI:%s", payload->baseURI);
-    }
-    if (payload->name)
+    while(payload && payload->resources)
     {
-        OIC_LOG_V(level, PL_TAG, "\tNAME: %s", payload->name);
-    }
-    if (payload->uri)
-    {
-        OIC_LOG_V(level, PL_TAG, "\tURI: %s", payload->uri);
-    }
-    if (payload->type)
-    {
-        for (OCStringLL *strll = payload->type; strll; strll = strll->next)
+        OIC_LOG_V(level, PL_TAG, "\tSID: %s", payload->sid);
+        if (payload->baseURI)
         {
-            OIC_LOG_V(level, PL_TAG, "\tResource Type: %s", strll->value);
+            OIC_LOG_V(level, PL_TAG, "\tBase URI:%s", payload->baseURI);
         }
-    }
-    OIC_LOG(level, PL_TAG, "\tInterface:");
-    for (OCStringLL *itf = payload->iface; itf; itf = itf->next)
-    {
-        OIC_LOG_V(level, PL_TAG, "\t\t%s", itf->value);
-    }
-
-    OCResourcePayload* res = payload->resources;
-
-    while(res)
-    {
-        OIC_LOG_V(level, PL_TAG, "\tResource #%d", i);
-        OIC_LOG_V(level, PL_TAG, "\tURI:%s", res->uri);
-        OIC_LOG(level, PL_TAG, "\tResource Types:");
-        OCStringLL* strll =  res->types;
-        while(strll)
+        if (payload->name)
         {
-            OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value);
-            strll = strll->next;
+            OIC_LOG_V(level, PL_TAG, "\tNAME: %s", payload->name);
         }
-        OIC_LOG(level, PL_TAG, "\tInterfaces:");
-        strll =  res->interfaces;
-        while(strll)
+        if (payload->uri)
         {
-            OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value);
-            strll = strll->next;
+            OIC_LOG_V(level, PL_TAG, "\tURI: %s", payload->uri);
+        }
+        if (payload->type)
+        {
+            for (OCStringLL *strll = payload->type; strll; strll = strll->next)
+            {
+                OIC_LOG_V(level, PL_TAG, "\tResource Type: %s", strll->value);
+            }
+        }
+        OIC_LOG(level, PL_TAG, "\tInterface:");
+        for (OCStringLL *itf = payload->iface; itf; itf = itf->next)
+        {
+            OIC_LOG_V(level, PL_TAG, "\t\t%s", itf->value);
         }
 
-        OIC_LOG_V(level, PL_TAG, "\tBitmap: %u", res->bitmap);
-        OIC_LOG_V(level, PL_TAG, "\tSecure?: %s", res->secure ? "true" : "false");
-        OIC_LOG_V(level, PL_TAG, "\tPort: %u", res->port);
-        OIC_LOG(level, PL_TAG, "");
-        res = res->next;
-        ++i;
+        OCResourcePayload* res = payload->resources;
+
+        int i = 1;
+        while(res)
+        {
+            OIC_LOG_V(level, PL_TAG, "\tResource #%d", i);
+            OIC_LOG_V(level, PL_TAG, "\tURI:%s", res->uri);
+            OIC_LOG(level, PL_TAG, "\tResource Types:");
+            OCStringLL* strll =  res->types;
+            while(strll)
+            {
+                OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value);
+                strll = strll->next;
+            }
+            OIC_LOG(level, PL_TAG, "\tInterfaces:");
+            strll =  res->interfaces;
+            while(strll)
+            {
+                OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value);
+                strll = strll->next;
+            }
+
+            OIC_LOG_V(level, PL_TAG, "\tBitmap: %u", res->bitmap);
+            OIC_LOG_V(level, PL_TAG, "\tSecure?: %s", res->secure ? "true" : "false");
+            OIC_LOG_V(level, PL_TAG, "\tPort: %u", res->port);
+            OIC_LOG(level, PL_TAG, "");
+            res = res->next;
+            ++i;
+        }
+        payload = payload->next;
     }
 }
 
index 115179a..362224b 100644 (file)
@@ -1686,6 +1686,7 @@ void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
     OICFree(payload->name);
     OCFreeOCStringLL(payload->iface);
     OCDiscoveryResourceDestroy(payload->resources);
+    OCDiscoveryPayloadDestroy(payload->next);
     OICFree(payload);
 }
 
index 890b527..e1edc0d 100644 (file)
@@ -217,45 +217,48 @@ static int64_t OCStringLLJoin(CborEncoder *map, char *type, OCStringLL *val)
 }
 
 static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *outPayload,
-        size_t *size)
+                                         size_t *size)
 {
     CborEncoder encoder;
     int64_t err = CborNoError;
 
     cbor_encoder_init(&encoder, outPayload, *size, 0);
 
-    if (payload->resources)
-    {
-        /*
-        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
-                            },
-                            .
-                            .
-                            .
-                        ]
-            }
-        ]
-        */
-        // Open the main root array
-        CborEncoder rootArray;
-        size_t resourceCount =  OCDiscoveryPayloadGetResourceCount(payload);
-        err |= cbor_encoder_create_array(&encoder, &rootArray, 1);
-        VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery root array");
+    /*
+    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 |= cbor_encoder_create_array(&encoder, &rootArray, 1);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery root array");
 
+    while (payload && payload->resources)
+    {
         // Open the root map in the root array
         CborEncoder rootMap;
         err |= cbor_encoder_create_map(&rootArray, &rootMap, CborIndefiniteLength);
@@ -284,18 +287,19 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o
 
         // Insert baseURI if present
         err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_BASE_URI,
-                                            sizeof(OC_RSRVD_BASE_URI) - 1,
-                                            payload->baseURI);
+                                             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)
+        for (size_t i = 0; i < resourceCount; ++i)
         {
             CborEncoder linkMap;
             OCResourcePayload *resource = OCDiscoveryPayloadGetResource(payload, i);
@@ -315,31 +319,35 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o
             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");
+                VERIFY_CBOR_SUCCESS(TAG, err,
+                                    "Failed adding resourceType tag/value to links map");
             }
             // Interface Types
             if (resource->interfaces)
             {
                 err |= OCStringLLJoin(&linkMap, OC_RSRVD_INTERFACE, resource->interfaces);
-                VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interfaces tag/value to links map");
+                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);
+            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);
+            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);
+                                           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");
@@ -347,7 +355,7 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o
             if (resource->secure || payload->baseURI)
             {
                 err |= cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
-                        sizeof(OC_RSRVD_HOSTING_PORT) - 1);
+                                               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");
@@ -374,11 +382,14 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o
         // close root map inside the root array.
         err |= cbor_encoder_close_container(&rootArray, &rootMap);
         VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root map");
-        // Close the final root array.
-        err |= cbor_encoder_close_container(&encoder, &rootArray);
-        VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array");
+
+        payload = payload->next;
     }
 
+    // Close the final root array.
+    err |= cbor_encoder_close_container(&encoder, &rootArray);
+    VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array");
+
 exit:
     return checkError(err, &encoder, outPayload, size);
 }
index ef9dc8a..b53ef21 100644 (file)
@@ -185,7 +185,9 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
 {
     OCStackResult ret = OC_STACK_INVALID_PARAM;
     OCResourcePayload *resource = NULL;
-    OCDiscoveryPayload *out = NULL;
+    OCDiscoveryPayload *temp = NULL;
+    OCDiscoveryPayload *rootPayload = NULL;
+    OCDiscoveryPayload *curPayload = NULL;
     size_t len = 0;
     CborError err = CborNoError;
     *outPayload = NULL;
@@ -196,169 +198,185 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
     {
         // Root value is already inside the main root array
         CborValue rootMap;
-        ret = OC_STACK_NO_MEMORY;
-        out = OCDiscoveryPayloadCreate();
-        VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
 
         // Enter the main root map
         ret = OC_STACK_MALFORMED_RESPONSE;
         err = cbor_value_enter_container(rootValue, &rootMap);
         VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
-
-        // Look for DI
-        CborValue curVal;
-        if (!cbor_value_is_map(&rootMap))
+        while (cbor_value_is_map(&rootMap))
         {
-            OIC_LOG(ERROR, TAG, "Malformed packet!!");
-            goto exit;
-        }
-        err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
-        VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
-        if (cbor_value_is_valid(&curVal))
-        {
-            if (cbor_value_is_byte_string(&curVal))
+            ret = OC_STACK_NO_MEMORY;
+            temp = OCDiscoveryPayloadCreate();
+            VERIFY_PARAM_NON_NULL(TAG, temp, "Failed error initializing discovery payload");
+
+            // Look for DI
+            CborValue curVal;
+            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
+            VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
+            if (cbor_value_is_valid(&curVal))
             {
-                err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(out->sid), &len, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
+                if (cbor_value_is_byte_string(&curVal))
+                {
+                    err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(temp->sid), &len, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
+                }
+                else if (cbor_value_is_text_string(&curVal))
+                {
+                    err = cbor_value_dup_text_string(&curVal, &(temp->sid), &len, NULL);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
+                }
             }
-            else if (cbor_value_is_text_string(&curVal))
+
+            // BaseURI - Not a mandatory field
+            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
+            VERIFY_CBOR_SUCCESS(TAG, err, "to find uri tag");
+            if (cbor_value_is_valid(&curVal))
             {
-                err = cbor_value_dup_text_string(&curVal, &(out->sid), &len, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
+                err = cbor_value_dup_text_string(&curVal, &(temp->baseURI), &len, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
             }
-        }
 
-        // BaseURI - Not a mandatory field
-        err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
-        VERIFY_CBOR_SUCCESS(TAG, err, "to find uri tag");
-        if (cbor_value_is_valid(&curVal))
-        {
-            err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
-        }
-
-        // HREF - Not a mandatory field
-        err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
-        if (cbor_value_is_valid(&curVal))
-        {
-            err = cbor_value_dup_text_string(&curVal, &(out->uri), &len, NULL);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find uri value");
-        }
-
-        // RT - Not a mandatory field
-        err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
-        if (cbor_value_is_valid(&curVal))
-        {
-            err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &out->type);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
-        }
+            // HREF - Not a mandatory field
+            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
+            if (cbor_value_is_valid(&curVal))
+            {
+                err = cbor_value_dup_text_string(&curVal, &(temp->uri), &len, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find uri value");
+            }
 
-        // IF - Not a mandatory field
-        err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
-        if (cbor_value_is_valid(&curVal))
-        {
-            err =  OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &out->iface);
-        }
-        if (!out->iface)
-        {
-            if (!OCResourcePayloadAddStringLL(&out->iface, OC_RSRVD_INTERFACE_LL))
+            // RT - Not a mandatory field
+            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
+            if (cbor_value_is_valid(&curVal))
             {
-                err = CborErrorOutOfMemory;
+                err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->type);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
             }
-        }
 
-        // Name - Not a mandatory field
-        err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
-        if (cbor_value_is_valid(&curVal))
-        {
-            err = cbor_value_dup_text_string(&curVal, &out->name, &len, NULL);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
-        }
+            // IF - Not a mandatory field
+            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
+            if (cbor_value_is_valid(&curVal))
+            {
+                err =  OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->iface);
+            }
+            if (!temp->iface)
+            {
+                if (!OCResourcePayloadAddStringLL(&temp->iface, OC_RSRVD_INTERFACE_LL))
+                {
+                    err = CborErrorOutOfMemory;
+                }
+            }
 
-        // Look for Links which will have an array as the value
-        CborValue linkMap;
-        err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
-        VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
+            // Name - Not a mandatory field
+            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
+            if (cbor_value_is_valid(&curVal))
+            {
+                err = cbor_value_dup_text_string(&curVal, &temp->name, &len, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
+            }
 
-        // Enter the links array and start iterating through the array processing
-        // each resource which shows up as a map.
-        CborValue resourceMap;
-        err = cbor_value_enter_container(&linkMap, &resourceMap);
-        VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
+            // Look for Links which will have an array as the value
+            CborValue linkMap;
+            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
+            VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
 
-        while (cbor_value_is_map(&resourceMap))
-        {
-            resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
-            VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
+            // Enter the links array and start iterating through the array processing
+            // each resource which shows up as a map.
+            CborValue resourceMap;
+            err = cbor_value_enter_container(&linkMap, &resourceMap);
+            VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
 
-            // Uri
-            err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
-            err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
+            while (cbor_value_is_map(&resourceMap))
+            {
+                resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
+                VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
+
+                // Uri
+                err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
+                err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
+
+                // ResourceTypes
+                err =  OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
+
+                // Interface Types
+                err =  OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
+                if (CborNoError != err)
+                {
+                    if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
+                    {
+                        OIC_LOG(ERROR, TAG, "Failed to add string to StringLL");
+                        goto exit;
+                    }
+                }
 
-            // ResourceTypes
-            err =  OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
+                // Policy
+                CborValue policyMap;
+                err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
+
+                // Bitmap
+                err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
+                err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
+
+                // Secure Flag
+                err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find secure tag");
+                if (cbor_value_is_valid(&curVal))
+                {
+                    err = cbor_value_get_boolean(&curVal, &(resource->secure));
+                    VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
+                }
 
-            // Interface Types
-            err =  OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
-            if (CborNoError != err)
-            {
-                if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
+                // Port
+                err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find port tag");
+                if (cbor_value_is_valid(&curVal))
                 {
-                    OIC_LOG(ERROR, TAG, "Failed to add string to StringLL");
-                    goto exit;
+                    err = cbor_value_get_int(&curVal, (int *)&resource->port);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
                 }
-            }
 
-            // Policy
-            CborValue policyMap;
-            err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
+#ifdef TCP_ADAPTER
+                // TCP Port
+                err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TCP_PORT, &curVal);
+                if (cbor_value_is_valid(&curVal))
+                {
+                    err = cbor_value_get_int(&curVal, (int *)&resource->tcpPort);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp port value");
+                }
+#endif
 
-            // Bitmap
-            err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
-            err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
+                err = cbor_value_advance(&resourceMap);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
 
-            // Secure Flag
-            err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find secure tag");
-            if (cbor_value_is_valid(&curVal))
-            {
-                err = cbor_value_get_boolean(&curVal, &(resource->secure));
-                VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
+                OCDiscoveryPayloadAddNewResource(temp, resource);
             }
 
-            // Port
-            err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to find port tag");
-            if (cbor_value_is_valid(&curVal))
+            err = cbor_value_leave_container(&linkMap, &resourceMap);
+            VERIFY_CBOR_SUCCESS(TAG, err, "to leave resource map");
+
+            err = cbor_value_advance(&rootMap);
+            VERIFY_CBOR_SUCCESS(TAG, err, "to advance root map");
+
+            if(rootPayload == NULL)
             {
-                err = cbor_value_get_int(&curVal, (int *)&resource->port);
-                VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
+                rootPayload = temp;
+                curPayload = temp;
             }
-
-#ifdef TCP_ADAPTER
-            // TCP Port
-            err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TCP_PORT, &curVal);
-            if (cbor_value_is_valid(&curVal))
+            else
             {
-                err = cbor_value_get_int(&curVal, (int *)&resource->tcpPort);
-                VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp port value");
+                curPayload->next = temp;
+                curPayload = curPayload->next;
             }
-#endif
-
-            err = cbor_value_advance(&resourceMap);
-            VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
-
-            OCDiscoveryPayloadAddNewResource(out, resource);
         }
 
-        err = cbor_value_leave_container(rootValue, &resourceMap);
-        VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
+        err = cbor_value_leave_container(rootValue, &rootMap);
+        VERIFY_CBOR_SUCCESS(TAG, err, "to leave root map");
+
     }
     else
     {
@@ -366,14 +384,14 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
         goto exit;
     }
 
-    *outPayload = (OCPayload *)out;
+    *outPayload = (OCPayload *)rootPayload;
     OIC_LOG_PAYLOAD(DEBUG, *outPayload);
 
     return OC_STACK_OK;
 
 exit:
     OCDiscoveryResourceDestroy(resource);
-    OCDiscoveryPayloadDestroy(out);
+    OCDiscoveryPayloadDestroy(rootPayload);
     return ret;
 }
 
index aa154bc..f037213 100644 (file)
@@ -44,10 +44,10 @@ namespace OC
                     OCDevAddr& devAddr, OCDiscoveryPayload* payload)
                     : m_clientWrapper(cw), m_devAddr(devAddr)
             {
-                OCResourcePayload* res = payload->resources;
-                if (res)
+                while (payload)
                 {
-                    while(res)
+                    OCResourcePayload* res = payload->resources;
+                    while (res)
                     {
                         if (res->secure)
                         {
@@ -103,6 +103,7 @@ namespace OC
                         }
                         res = res->next;
                     }
+                    payload = payload->next;
                 }
             }