/oic/res response based on the collection response structure
authorHabib Virji <habib.virji@samsung.com>
Fri, 18 Sep 2015 22:15:25 +0000 (23:15 +0100)
committerPatrick Lankswert <patrick.lankswert@intel.com>
Tue, 29 Sep 2015 05:53:21 +0000 (05:53 +0000)
This is based on the new strucutre of the /oic/res as currently being defined
by Ravi. This is useful for the resource directory as it needs to include
multiple links maps inside links array.

It differs with the current /oic/res response as it includes links array with
multiple links map object.

The strucutre of the payload appears in this format:
Array
  TagsObject
    di
    baseURI
    bitmap
    ins
  LinksArray
    LinkMapObject
      href
      rt
      itf
      ins

Change-Id: Ifc61a70ede1fc44e9b2321604907d99961eea13b
Signed-off-by: Habib Virji <habib.virji@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2701
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.com>
23 files changed:
resource/csdk/SConscript
resource/csdk/stack/include/ocpayload.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/include/payload_logging.h
resource/csdk/stack/include/rdpayload.h [new file with mode: 0644]
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/src/ocpayloadconvert.c
resource/csdk/stack/src/ocpayloadparse.c
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/src/rdpayload.c [new file with mode: 0644]
resource/include/OCSerialization.h
service/resource-directory/SConscript
service/resource-directory/include/rd_client.h
service/resource-directory/include/rd_server.h
service/resource-directory/include/rd_types.h [deleted file]
service/resource-directory/samples/SConscript
service/resource-directory/samples/rd_main.c
service/resource-directory/src/internal/rd_storage.c
service/resource-directory/src/internal/rd_storage.h
service/resource-directory/src/rd_client.c
service/resource-directory/src/rd_payload.c [deleted file]
service/resource-directory/src/rd_server.c

index edc083f..94c3eda 100644 (file)
@@ -101,11 +101,6 @@ if env.get('SECURED') == '1':
 if env.get('LOGGING'):
        liboctbstack_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
-if env.get('WITH_RD') == '1':
-       liboctbstack_env.PrependUnique(CPPPATH = ['../../service/resource-directory/include'])
-       liboctbstack_env.AppendUnique(CPPDEFINES = ['-DWITH_RD'])
-       liboctbstack_env.AppendUnique(LIBS = ['resource_directory'])
-
 liboctbstack_env.Append(LIBS = ['c_common'])
 
 if liboctbstack_env.get('ROUTING') in ['GW', 'EP']:
@@ -129,7 +124,8 @@ liboctbstack_src = [
        OCTBSTACK_SRC + 'occollection.c',
        OCTBSTACK_SRC + 'oicgroup.c',
        'logger/src/logger.c',
-       'ocrandom/src/ocrandom.c'
+       'ocrandom/src/ocrandom.c',
+       OCTBSTACK_SRC + "rdpayload.c"
        ]
 
 liboctbstack_src.extend(env['cbor_files'])
index e90558c..6fae1f5 100755 (executable)
 #include <inttypes.h>
 #include "octypes.h"
 
-#ifdef WITH_RD
-#include "rd_payload.h"
-#endif
-
 #ifdef __cplusplus
 extern "C"
 {
@@ -143,9 +139,12 @@ OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
         OCPresenceTrigger trigger, const char* resourceType);
 void OCPresencePayloadDestroy(OCPresencePayload* payload);
 
+// Helper API
+OCStringLL* CloneOCStringLL (OCStringLL* ll);
+void OCFreeOCStringLL(OCStringLL* ll);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif
-
index 6269687..9e67e78 100644 (file)
@@ -275,6 +275,44 @@ extern "C" {
 /** Max identity size. */
 #define MAX_IDENTITY_SIZE (32)
 
+/** Resource Directory */
+
+/** Resource Directory URI used to Discover RD and Publish resources.*/
+#define OC_RSRVD_RD_URI                  "/oic/rd"
+
+/** To represent resource type with rd.*/
+#define OC_RSRVD_RESOURCE_TYPE_RD        "oic.wk.rd"
+
+/** RD Discovery bias factor type. */
+#define OC_RSRVD_RD_DISCOVERY_SEL        "sel"
+
+/** Base URI. */
+#define OC_RSRVD_BASE_URI                "baseURI"
+
+/** Unique value per collection/link. */
+#define OC_RSRVD_INS                     "ins"
+
+/** Allowable resource types in the links. */
+#define OC_RSRVD_RTS                     "rts"
+
+/** Default relationship. */
+#define OC_RSRVD_DREL                    "drel"
+
+/** Defines relationship between links. */
+#define OC_RSRVD_REL                     "rel"
+
+/** Defines title. */
+#define OC_RSRVD_TITLE                   "title"
+
+/** Defines URI. */
+#define OC_RSRVD_URI                     "uri"
+
+/** Defines media type. */
+#define OC_RSRVD_MEDIA_TYPE              "mt"
+
+/** To represent resource type with Publish RD.*/
+#define OC_RSRVD_RESOURCE_TYPE_RDPUBLISH "oic.wk.rdPub"
+
 /**
  * These enums (OCTransportAdapter and OCTransportFlags) must
  * be kept synchronized with OCConnectivityType (below) as well as
@@ -966,12 +1004,122 @@ typedef struct OCResourcePayload
     struct OCResourcePayload* next;
 } OCResourcePayload;
 
+/**
+ * Structure holding Links Payload. It is a sub-structure used in
+ * OCResourceCollectionPayload.
+ */
+typedef struct OCLinksPayload
+{
+    /** This is the target relative URI. */
+    char *href;
+    /** Resource Type - A standard OIC specified or vendor defined resource
+     * type of the resource referenced by the target URI. */
+    OCStringLL *rt;
+    /** Interface - The interfaces supported by the resource referenced by the target URI. */
+    OCStringLL *itf;
+    /** The relation of the target URI referenced by the link to the context URI;
+     * The default value is null. */
+    char *rel;
+    /** Specifies if the resource referenced by the target URIis observable or not. */
+    bool obs;
+    /** A title for the link relation. Can be used by the UI to provide a context. */
+    char *title;
+    /** This is used to override the context URI e.g. override the URI of the containing collection. */
+    char *uri;
+    /** The instance identifier for this web link in an array of web links - used in links. */
+    union
+    {
+        /** An ordinal number that is not repeated - must be unique in the collection context. */
+        uint8_t ins;
+        /** Any unique string including a URI. */
+        char *uniqueStr;
+        /** Use UUID for universal uniqueness - used in /oic/res to identify the device. */
+        OCIdentity uniqueUUID;
+    };
+    /** A hint of the media type of the representation of the resource referenced by the target URI. */
+    OCStringLL *mt;
+    /** Holding address of the next resource. */
+    struct OCLinksPayload *next;
+} OCLinksPayload;
+
+/** Structure holding tags value of the links payload. */
+typedef struct
+{
+    /** Name of tags. */
+    OCDeviceInfo n;
+    /** Device identifier. */
+    OCIdentity di;
+    /** The base URI where the resources are hold. */
+    char *baseURI;
+    /** Bitmap holds observable, discoverable, secure option flag.*/
+    uint8_t bitmap;
+    /** Port set in case, the secure flag is set above. */
+    uint16_t port;
+    /** Id for each set of links i.e. tag. */
+    union
+    {
+        /** An ordinal number that is not repeated - must be unique in the collection context. */
+        uint8_t ins;
+        /** Any unique string including a URI. */
+        char *uniqueStr;
+        /** Use UUID for universal uniqueness - used in /oic/res to identify the device. */
+        OCIdentity uniqueUUID;
+    };
+    /** Defines the list of allowable resource types (for Target and anchors) in links included
+     * in the collection; new links being created can only be from this list. */
+    char *rts;
+    /** When specified this is the default relationship to use when an OIC Link does not specify
+     * an explicit relationship with *rel* parameter. */
+    char *drel;
+    /** Time to keep holding resource.*/
+    uint32_t ttl;
+} OCTagsPayload;
+
+/** Resource collection payload. */
+typedef struct OCResourceCollectionPayload
+{
+    /** Collection tags payload.*/
+    OCTagsPayload *tags;
+    /** Array of links payload. */
+    OCLinksPayload *setLinks;
+    /** Holding address of the next resource. */
+    struct OCResourceCollectionPayload *next;
+} OCResourceCollectionPayload;
+
 typedef struct
 {
     OCPayload base;
-    OCResourcePayload* resources;
+    /** This structure holds the old /oic/res response. */
+    OCResourcePayload *resources;
+    /** This structure holds the collection response for the /oic/res. */
+    OCResourceCollectionPayload *collectionResources;
 } OCDiscoveryPayload;
 
+/**
+ * Structure holding discovery payload.
+ */
+typedef struct
+{
+    /** Device Name. */
+    OCDeviceInfo n;
+    /** Device Identity. */
+    OCIdentity di;
+    /** Value holding the bias factor of the RD. */
+    uint8_t sel;
+} OCRDDiscoveryPayload;
+
+/**
+ * RD Payload that will be transmitted over the wire.
+ */
+typedef struct
+{
+    OCPayload base;
+    /** Pointer to the discovery response payload.*/
+    OCRDDiscoveryPayload *rdDiscovery;
+    /** Pointer to the publish payload.*/
+    OCResourceCollectionPayload *rdPublish;
+} OCRDPayload;
+
 typedef struct
 {
     OCPayload base;
index 0253180..1269779 100644 (file)
@@ -26,6 +26,8 @@
 #include <dlog.h>
 #endif
 
+#include "rdpayload.h"
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -232,6 +234,29 @@ static inline void OCPayloadLogSecurity(LogLevel level, OCSecurityPayload* paylo
     OC_LOG_V(level, PL_TAG, "\tSecurity Data: %s", payload->securityData);
 }
 
+static inline void OCRDPayloadLog(const LogLevel level, const OCRDPayload *payload)
+{
+    if (!payload)
+    {
+        return;
+    }
+
+    if (payload->rdDiscovery)
+    {
+        OC_LOG(level, PL_TAG, "RD Discovery");
+        OC_LOG_V(level, PL_TAG, "  Device Name : %s", payload->rdDiscovery->n.deviceName);
+        OC_LOG_V(level, PL_TAG, "  Device Identity : %s", payload->rdDiscovery->di.id);
+        OC_LOG_V(level, PL_TAG, "  Bias: %d", payload->rdDiscovery->sel);
+    }
+    if (payload->rdPublish)
+    {
+        OC_LOG(level, PL_TAG, "RD Publish");
+        OCResourceCollectionPayload *rdPublish = payload->rdPublish;
+        OCTagsLog(level, rdPublish->tags);
+        OCLinksLog(level, rdPublish->setLinks);
+    }
+}
+
 static inline void OCPayloadLog(LogLevel level, OCPayload* payload)
 {
     if(!payload)
@@ -259,11 +284,9 @@ static inline void OCPayloadLog(LogLevel level, OCPayload* payload)
         case PAYLOAD_TYPE_SECURITY:
             OCPayloadLogSecurity(level, (OCSecurityPayload*)payload);
             break;
-#ifdef WITH_RD
         case PAYLOAD_TYPE_RD:
-            OCRDPayloadLog(level, PL_TAG, (OCRDPayload*)payload);
+            OCRDPayloadLog(level, (OCRDPayload*)payload);
             break;
-#endif
         default:
             OC_LOG_V(level, PL_TAG, "Unknown Payload Type: %d", payload->type);
             break;
diff --git a/resource/csdk/stack/include/rdpayload.h b/resource/csdk/stack/include/rdpayload.h
new file mode 100644 (file)
index 0000000..1781263
--- /dev/null
@@ -0,0 +1,240 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _RDPAYLOAD_H_
+#define _RDPAYLOAD_H_
+
+#include <cbor.h>
+#include "octypes.h"
+#include "logger.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/**
+ * Converts RD payload from structure to CBOR format. It creates the outPayload
+ * which is then transmitted over the wire.
+ *
+ * @param rdPayload Contains structure holding values of OCRDPayload.
+ * @param outPayload The payload in the CBOR format converting OCRDPayload
+ * structure.
+ * @param size Length of the payload.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in creating CBOR.
+ */
+int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size);
+
+/**
+ * Converts tags structure to the tags cbor payload.
+ *
+ * @param tags Allocated Tag structure
+ * @param setMap The cbor map where result will be stored.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in creating CBOR.
+ */
+OCStackResult OCTagsPayloadToCbor(OCTagsPayload *tags, CborEncoder *setMap);
+
+/**
+ * Converts links structure to cbor map structure
+ *
+ * @param links Allocated links structure.
+ * @param setMap The cbor map where result will be stored.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in creating CBOR.
+ */
+OCStackResult OCLinksPayloadToCbor(OCLinksPayload *rtPtr, CborEncoder *setMap);
+
+/**
+ * Converts CBOR to OCRDPayload.
+ *
+ * @param rdCBORPayload Payload received from other end in CBOR format.
+ * @param outPayload Parsing the values from CBOR into OCRDPayload structure.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in parsing CBOR.
+ */
+OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload);
+
+/**
+ * Converts cbor map payload to OCTags payload.
+ *
+ * @param tagstMap CborValue holding tags structure.
+ * @param tagsPayload Allocated tags payload.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in creating CBOR.
+ */
+OCStackResult OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPayload);
+
+/**
+ * Converts cbor map payload to OCLinks payload.
+ *
+ * @param tagstMap CborValue holding links structure.
+ * @param tagsPayload Allocated links payload.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in creating CBOR.
+ */
+OCStackResult OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **linksPayload);
+
+/**
+ * Initializes RD payload structure.
+ *
+ * @param payloadType Defines whether payload is RD_PAYLOAD_TYPE_DISCOVERY or
+ * RD_PAYLOAD_TYPE_PUBLISH.
+ *
+ * @return Allocated memory for the OCRDPayload and NULL in case if failed to
+ * allocate memory
+ */
+OCRDPayload *OCRDPayloadCreate();
+
+/**
+ * Initializes RD Discovery payload structure and sets the bias factor.
+ *
+ * @param name Name of the discovery device payload.
+ * @param identity Device identity of the discovery device.
+ * @param biasFactor Value specifies the selection factor. It is weigthage of
+ * CPU, Memory, Network, Load and Power capability of the RD server.
+ *
+ * @return Allocated memory for the OCRDDiscoveryPayload and NULL in case if
+ * failed to allocate memory.
+ */
+OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(const char *name, const char *identity, int biasFactor);
+
+/**
+ * Free memory allocation of the RDPayload and its internal structure.
+ *
+ * @param payload Pointer to already allocated memory for OCRDPayload.
+ */
+void OCRDPayloadDestroy(OCRDPayload *payload);
+
+/**
+ * Copies tag paramter to creates OCTagsPayload.
+ *
+ * @param deviceName The device name as set during enrollment.
+ * @param id The device UUID
+ * @param baseURI baseURI pointing to the resource directory location.
+ * @param bitmap The bitmap value include observe, discovery and secure bit set.
+ * @param port The secure port in case above bitmap is set to secure.
+ * @param ins Unique value per collection.
+ * @param rts Defines allowed resource types.
+ * @param drel Defines defaultr relationship.
+ * @param ttl Time to leave for the . Used only in resource directory.
+ *
+ * @retun Allocated memory for OCTagsPayload or else NULL in case of error.
+ */
+OCTagsPayload* OCCopyTagsResources(const char *deviceName, const unsigned char *id,
+    const char *baseURI, uint8_t bitmap, uint16_t port, uint8_t ins, const char *rts, const char *drel, uint32_t ttl);
+
+/**
+ * Copies link resource to create LinksPayload.
+ *
+ * @param href URI of the resource
+ * @param rt Array of String pointing to resource types.
+ * @param itf Array of String pointing to interface
+ * @param rel Relation
+ * @param obs Whether to observe or not.
+ * @param title Title
+ * @param uri URI
+ * @param ins Unique value per link.
+ * @param mt Media Type
+
+ * @retun Allocated memory for OCLinksPayload or else NULL in case of error.
+ */
+OCLinksPayload* OCCopyLinksResources(const char *href, OCStringLL *rt, OCStringLL *itf,
+    const char *rel, bool obs, const char *title, const char *uri, uint8_t ins, OCStringLL *mt);
+
+/**
+ * Creates a resource collection object.
+ *
+ * @param tags Pointer pointing to tags payload.
+ * @param links Pointer pointing to links payload.
+ *
+ * @return Memory allocation for OCResourceCollectionPayload, else NULL.
+ */
+OCResourceCollectionPayload* OCCopyCollectionResource(OCTagsPayload *tags, OCLinksPayload *links);
+
+/**
+ * Adds discocvery collection in discovery payload.
+ *
+ * @param payload Pointer to the discovery payload. It adds allocated collection resource.
+ * @param tags Pointer to the tags payload.
+ * @param links Pointer to the links payload.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in creating CBOR.
+ */
+
+OCStackResult OCDiscoveryCollectionPayloadAddResource(OCDiscoveryPayload *payload,  OCTagsPayload *tags,
+    OCLinksPayload *links);
+
+/**
+ * Destroys tags payload including internal structure allocated
+ *
+ * @param tags - Allocated memory of the tags payload.
+ */
+void OCFreeTagsResource(OCTagsPayload *tags);
+
+/**
+ * Destroys allocated links payload including internal structure allocated.
+ *
+ * @param links - Allocated memory to the links payload.
+ */
+void OCFreeLinksResource(OCLinksPayload *links);
+
+/**
+ * ResourceCollection payload destroy. Includes free up tags and links structure.
+ *
+ * @param payload Pointer pointing to allocated memroy of ResourceCollection.
+ */
+void OCFreeCollectionResource(OCResourceCollectionPayload *payload);
+
+/**
+ * Discovery collection payload destroy includes internal structure OCResourceCollectionPayload.
+ *
+ * @param payload Pointer pointing to allocated memory of OCDiscoveryPayload.
+ */
+void OCDiscoveryCollectionPayloadDestroy(OCDiscoveryPayload* payload);
+
+/**
+ * Prints tags payload.
+ *
+ * @param level LogLevel for the print.
+ * @param tags Structure of the tags payload.
+ */
+void OCTagsLog(const LogLevel level, const OCTagsPayload *tags);
+
+/**
+ * Prints links payload.
+ *
+ * @param level LogLevel for the print.
+ * @param tags Structure of the links payload.
+ */
+void OCLinksLog(const LogLevel level, const OCLinksPayload *links);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif /* OCTYPES_H_ */
index 8145378..4f3ccd4 100755 (executable)
@@ -27,6 +27,7 @@
 #include "ocstackinternal.h"
 #include "ocresource.h"
 #include "logger.h"
+#include "rdpayload.h"
 
 #define TAG "OCPayload"
 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
@@ -59,11 +60,9 @@ void OCPayloadDestroy(OCPayload* payload)
         case PAYLOAD_TYPE_SECURITY:
             OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
             break;
-#ifdef WITH_RD
         case PAYLOAD_TYPE_RD:
            OCRDPayloadDestroy((OCRDPayload*)payload);
            break;
-#endif
         default:
             OC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
             OICFree(payload);
index 8e64af5..6904852 100644 (file)
 #include "ocrandom.h"
 #include "ocresourcehandler.h"
 #include "cbor.h"
+#include "rdpayload.h"
 
 #define TAG "OCPayloadConvert"
 // Arbitrarily chosen size that seems to contain the majority of packages
 #define INIT_SIZE (255)
 
+#define CBOR_ROOT_ARRAY_LENGTH 1
+
 // 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,
@@ -140,10 +143,8 @@ static int64_t OCConvertPayloadHelper(OCPayload* payload, uint8_t* outPayload, s
             return OCConvertPresencePayload((OCPresencePayload*)payload, outPayload, size);
         case PAYLOAD_TYPE_SECURITY:
             return OCConvertSecurityPayload((OCSecurityPayload*)payload, outPayload, size);
-#ifdef WITH_RD
         case PAYLOAD_TYPE_RD:
             return OCRDPayloadToCbor((OCRDPayload*)payload, outPayload, size);
-#endif
         default:
             OC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
             return OC_STACK_NOTIMPL;
@@ -200,114 +201,163 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t* o
         size_t* size)
 {
     CborEncoder encoder = {0};
+    CborEncoder rootArray = {0};
     int64_t err = 0;
-    size_t resourceCount =  OCDiscoveryPayloadGetResourceCount(payload);
 
     cbor_encoder_init(&encoder, outPayload, *size, 0);
 
-    CborEncoder rootArray;
-    err = err | cbor_encoder_create_array(&encoder, &rootArray, resourceCount);
-
-    for(size_t i = 0; i < resourceCount; ++i)
+    if (payload->collectionResources)
     {
-        CborEncoder map;
-        OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
-
-        if(!resource)
+        CborError cborEncoderResult;
+        cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, CBOR_ROOT_ARRAY_LENGTH);
+        if (CborNoError != cborEncoderResult)
         {
-            return OC_STACK_INVALID_PARAM;
+            OC_LOG(ERROR, TAG, "Failed creating root array.");
+            goto cbor_error;
         }
 
-        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
+        CborEncoder colArray;
+        cborEncoderResult = cbor_encoder_create_array(&rootArray, &colArray, CborIndefiniteLength);
+        if (CborNoError != cborEncoderResult)
         {
-            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);
+            OC_LOG(ERROR, TAG, "Failed creating collection array.");
+            goto cbor_error;
+        }
 
-            // Resource Type
+        OCResourceCollectionPayload *colResources = payload->collectionResources;
+        while (colResources)
+        {
+            if (OC_STACK_OK != OCTagsPayloadToCbor(colResources->tags, &colArray))
             {
-                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);
+                goto cbor_error;
+            }
+            if (OC_STACK_OK != OCLinksPayloadToCbor(colResources->setLinks, &colArray))
+            {
+                goto cbor_error;
+            }
+            colResources = colResources->next;
+        }
+        cborEncoderResult = cbor_encoder_close_container(&rootArray, &colArray);
+        if (CborNoError != cborEncoderResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed closing collection array.");
+            goto cbor_error;
+        }
+        cborEncoderResult = cbor_encoder_close_container(&encoder, &rootArray);
+        if (CborNoError != cborEncoderResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed closing root array.");
+            goto cbor_error;
+        }
+    }
+    else if (payload->resources)
+    {
+        size_t resourceCount =  OCDiscoveryPayloadGetResourceCount(payload);
+        err = err || cbor_encoder_create_array(&encoder, &rootArray, resourceCount);
 
-                OCStringLL* rtPtr = resource->types;
-                while(rtPtr)
-                {
-                    err = err | cbor_encode_text_string(&rtArray, rtPtr->value,
-                            strlen(rtPtr->value));
-                    rtPtr = rtPtr->next;
-                }
+        for(size_t i = 0; i < resourceCount; ++i)
+        {
+            CborEncoder map;
+            OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
 
-                err = err | cbor_encoder_close_container(&propMap, &rtArray);
+            if(!resource)
+            {
+                OICFree(outPayload);
+                return OC_STACK_INVALID_PARAM;
             }
 
-            // Interface Types
-            {
-                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;
+            err = err | cbor_encoder_create_map(&rootArray, &map, 3);
+            // Uri
+            err = err | AddTextStringToMap(&map, OC_RSRVD_HREF,
+                    sizeof(OC_RSRVD_HREF) - 1,
+                    resource->uri);
 
-                while(ifPtr)
-                {
-                    err = err | cbor_encode_text_string(&ifArray, ifPtr->value,
-                        strlen(ifPtr->value));
-                    ifPtr= ifPtr->next;
-                }
+            // 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);
 
-                err = err | cbor_encoder_close_container(&propMap, &ifArray);
-            }
-            // Policy
+            // Prop Tag
             {
-                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);
+                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);
+                // 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);
 
-                // Bitmap
-                err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
-                        sizeof(OC_RSRVD_BITMAP) - 1);
-                err = err | cbor_encode_uint(&policyMap, resource->bitmap);
+                    OCStringLL* rtPtr = resource->types;
+                    while(rtPtr)
+                    {
+                        err = err | cbor_encode_text_string(&rtArray, rtPtr->value,
+                                strlen(rtPtr->value));
+                        rtPtr = rtPtr->next;
+                    }
 
-                if(resource->secure)
+                    err = err | cbor_encoder_close_container(&propMap, &rtArray);
+                }
+                // Interface Types
                 {
-                    err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
-                            sizeof(OC_RSRVD_SECURE) - 1);
-                    err = err | cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE);
-
-                    if(resource->port != 0)
+                    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(&policyMap, OC_RSRVD_HOSTING_PORT,
-                                sizeof(OC_RSRVD_HOSTING_PORT) - 1);
-                        err = err | cbor_encode_uint(&policyMap, resource->port);
+                        err = err | cbor_encode_text_string(&ifArray, ifPtr->value,
+                            strlen(ifPtr->value));
+                        ifPtr= ifPtr->next;
                     }
+
+                    err = err || cbor_encoder_close_container(&propMap, &ifArray);
                 }
 
-                err = err | cbor_encoder_close_container(&propMap, &policyMap);
+                // Policy
+                {
+                    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);
+
+                    // Bitmap
+                    err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
+                            sizeof(OC_RSRVD_BITMAP) - 1);
+                    err = err || cbor_encode_uint(&policyMap, resource->bitmap);
+
+                    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);
+
+                        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 = err || cbor_encoder_close_container(&propMap, &policyMap);
+                }
+                // Close
+                err = err || cbor_encoder_close_container(&map, &propMap);
             }
-            // Close
-            err = err | cbor_encoder_close_container(&map, &propMap);
+            // Close Item
+            err = err || cbor_encoder_close_container(&rootArray, &map);
         }
-        // Close Item
-        err = err | cbor_encoder_close_container(&rootArray, &map);
+        // Close main array
+        err = err | cbor_encoder_close_container(&encoder, &rootArray);
     }
-    // Close main array
-    err = err | cbor_encoder_close_container(&encoder, &rootArray);
 
     return checkError(err, &encoder, outPayload, size);
+cbor_error:
+    OICFree(outPayload);
+    return OC_STACK_ERROR;
 }
 
 static int64_t OCConvertDevicePayload(OCDevicePayload* payload, uint8_t* outPayload,
index 36f726b..d7a1df5 100644 (file)
 #include "ocpayloadcbor.h"
 #include <stdlib.h>
 #include "logger.h"
+#include "oic_string.h"
 #include "oic_malloc.h"
 #include "ocstackinternal.h"
 #include "ocpayload.h"
 #include "cbor.h"
+#include "payload_logging.h"
+#include "rdpayload.h"
 
 #define TAG "OCPayloadParse"
 
@@ -43,7 +46,7 @@ OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
     CborValue rootValue;
     bool err = false;
 
-    OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize);
+    OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d %d", payloadSize, payloadType);
     if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
     {
         OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
@@ -60,7 +63,7 @@ OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
     // enter the array
     err = err || cbor_value_enter_container(&rootValue, &arrayValue);
 
-    if(err || arrayValue.type != CborMapType)
+    if(err)
     {
         OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
         return OC_STACK_MALFORMED_RESPONSE;
@@ -87,11 +90,9 @@ OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
         case PAYLOAD_TYPE_SECURITY:
             result = OCParseSecurityPayload(outPayload, &arrayValue);
             break;
-#ifdef WITH_RD
         case PAYLOAD_TYPE_RD:
             result = OCRDCborToPayload(&arrayValue, outPayload);
             break;
-#endif
         default:
             OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
             result = OC_STACK_ERROR;
@@ -175,186 +176,234 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue*
         return OC_STACK_NO_MEMORY;
     }
 
-    size_t resourceCount = 0;
-    while(!err &&
-            cbor_value_is_map(arrayVal))
+    if (cbor_value_is_array(arrayVal))
     {
-        OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
-        if(!resource)
+        OCLinksPayload *linksPayload = NULL;
+        OCTagsPayload *tagsPayload = NULL;
+        while (cbor_value_is_container(arrayVal))
         {
-            OC_LOG(ERROR, TAG, "Memory allocation failed");
-            OCDiscoveryPayloadDestroy(out);
-            return OC_STACK_NO_MEMORY;
-        }
-        CborValue curVal;
+            linksPayload = NULL;
+            tagsPayload = NULL;
+            CborValue colResources;
+            CborError cborFindResult = cbor_value_enter_container(arrayVal, &colResources);
+            if (CborNoError != cborFindResult)
+            {
+                goto cbor_error;
+            }
 
-        // Uri
-        err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
-        size_t len;
-        err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
+            if (OC_STACK_OK != OCTagsCborToPayload(&colResources, &tagsPayload))
+            {
+                OC_LOG(ERROR, TAG, "Tags cbor parsing failed.");
+                OCFreeTagsResource(tagsPayload);
+                goto cbor_error;
+            }
 
-        // SID
-        err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
-        err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
+            if (OC_STACK_OK != OCLinksCborToPayload(&colResources, &linksPayload))
+            {
+                OC_LOG(ERROR, TAG, "Links cbor parsing failed.");
+                OCFreeTagsResource(tagsPayload);
+                OCFreeLinksResource(linksPayload);
+                goto cbor_error;
+            }
 
-        // Prop Tag
+            if (OC_STACK_OK != OCDiscoveryCollectionPayloadAddResource(out, tagsPayload, linksPayload))
+            {
+                OC_LOG(ERROR, TAG, "Memory allocation failed");
+                OCFreeLinksResource(linksPayload);
+                OCFreeTagsResource(tagsPayload);
+                OCDiscoveryPayloadDestroy(out);
+                return OC_STACK_NO_MEMORY;
+            }
+            if (CborNoError != cbor_value_advance(arrayVal))
+            {
+                OC_LOG(ERROR, TAG, "Cbor value advanced failed.");
+                goto cbor_error;
+            }
+        }
+    }
+    if (cbor_value_is_map(arrayVal))
+    {
+        size_t resourceCount = 0;
+        while(!err &&
+                cbor_value_is_map(arrayVal))
         {
-             err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
-            // ResourceTypes
-            CborValue rtArray;
-             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
+            OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
+            if(!resource)
+            {
+                OC_LOG(ERROR, TAG, "Memory allocation failed");
+                OCDiscoveryPayloadDestroy(out);
+                return OC_STACK_NO_MEMORY;
+            }
+            CborValue curVal;
 
-            CborValue rtVal;
-             err = err || cbor_value_enter_container(&rtArray, &rtVal);
+            // Uri
+            err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
+            size_t len;
+            err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
+
+            // SID
+            err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
+            err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
 
-            OCStringLL* llPtr = NULL;
-            while(!err && cbor_value_is_text_string(&rtVal))
+            // Prop Tag
             {
-                if(resource->types == NULL)
+                 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
+                // ResourceTypes
+                CborValue rtArray;
+                 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
+
+                CborValue rtVal;
+                 err = err || cbor_value_enter_container(&rtArray, &rtVal);
+
+                OCStringLL* llPtr = NULL;
+                while(!err && cbor_value_is_text_string(&rtVal))
                 {
-                    resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
-                    llPtr = resource->types;
-                    if(!llPtr)
+                    if(resource->types == NULL)
                     {
-                        OC_LOG(ERROR, TAG, "Memory allocation failed");
-                        OICFree(resource->uri);
-                        OICFree(resource->sid);
-                        OICFree(resource);
-                        OCDiscoveryPayloadDestroy(out);
-                        return OC_STACK_NO_MEMORY;
+                        resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+                        llPtr = resource->types;
+                        if(!llPtr)
+                        {
+                            OC_LOG(ERROR, TAG, "Memory allocation failed");
+                            OICFree(resource->uri);
+                            OICFree(resource->sid);
+                            OICFree(resource);
+                            OCDiscoveryPayloadDestroy(out);
+                            return OC_STACK_NO_MEMORY;
+                        }
                     }
-                }
-                else if(llPtr)
-                {
-                    llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
-                    llPtr = llPtr->next;
-                    if(!llPtr)
+                    else if(llPtr)
                     {
-                        OC_LOG(ERROR, TAG, "Memory allocation failed");
-                        OICFree(resource->uri);
-                        OICFree(resource->sid);
-                        OCFreeOCStringLL(resource->types);
-                        OICFree(resource);
-                        OCDiscoveryPayloadDestroy(out);
-                        return OC_STACK_NO_MEMORY;
+                        llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+                        llPtr = llPtr->next;
+                        if(!llPtr)
+                        {
+                            OC_LOG(ERROR, TAG, "Memory allocation failed");
+                            OICFree(resource->uri);
+                            OICFree(resource->sid);
+                            OCFreeOCStringLL(resource->types);
+                            OICFree(resource);
+                            OCDiscoveryPayloadDestroy(out);
+                            return OC_STACK_NO_MEMORY;
+                        }
+                    }
+                    else
+                    {
+                            OC_LOG(ERROR, TAG, "Unknown state in resource type copying");
+                            OICFree(resource->uri);
+                            OICFree(resource->sid);
+                            OCFreeOCStringLL(resource->types);
+                            OICFree(resource);
+                            OCDiscoveryPayloadDestroy(out);
+                            return OC_STACK_NO_MEMORY;
                     }
-                }
-                else
-                {
-                        OC_LOG(ERROR, TAG, "Unknown state in resource type copying");
-                        OICFree(resource->uri);
-                        OICFree(resource->sid);
-                        OCFreeOCStringLL(resource->types);
-                        OICFree(resource);
-                        OCDiscoveryPayloadDestroy(out);
-                        return OC_STACK_NO_MEMORY;
-                }
 
-                 err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
-                 err = err || cbor_value_advance(&rtVal);
-            }
+                     err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
+                     err = err || cbor_value_advance(&rtVal);
+                }
 
-             err = err || cbor_value_leave_container(&rtArray, &rtVal);
-            //
-            // Interface Types
-            CborValue ifArray;
-             err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
-            CborValue ifVal;
-             err = err || cbor_value_enter_container(&ifArray, &ifVal);
+                 err = err || cbor_value_leave_container(&rtArray, &rtVal);
+                //
+                // Interface Types
+                CborValue ifArray;
+                 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
+                CborValue ifVal;
+                 err = err || cbor_value_enter_container(&ifArray, &ifVal);
 
-            llPtr = NULL;
-            while(!err && cbor_value_is_text_string(&ifVal))
-            {
-                if(resource->interfaces == NULL)
+                llPtr = NULL;
+                while(!err && cbor_value_is_text_string(&ifVal))
                 {
-                    resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
-                    llPtr = resource->interfaces;
-                    if(!llPtr)
+                    if(resource->interfaces == NULL)
                     {
-                        OC_LOG(ERROR, TAG, "Memory allocation failed");
-                        OICFree(resource->uri);
-                        OICFree(resource->sid);
-                        OCFreeOCStringLL(resource->types);
-                        OICFree(resource);
-                        OCDiscoveryPayloadDestroy(out);
-                        return OC_STACK_NO_MEMORY;
+                        resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+                        llPtr = resource->interfaces;
+                        if(!llPtr)
+                        {
+                            OC_LOG(ERROR, TAG, "Memory allocation failed");
+                            OICFree(resource->uri);
+                            OICFree(resource->sid);
+                            OCFreeOCStringLL(resource->types);
+                            OICFree(resource);
+                            OCDiscoveryPayloadDestroy(out);
+                            return OC_STACK_NO_MEMORY;
+                        }
                     }
-                }
-                else if (llPtr)
-                {
-                    llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
-                    llPtr = llPtr->next;
-                    if(!llPtr)
+                    else if (llPtr)
                     {
-                        OC_LOG(ERROR, TAG, "Memory allocation failed");
-                        OICFree(resource->uri);
-                        OICFree(resource->sid);
-                        OCFreeOCStringLL(resource->types);
-                        OCFreeOCStringLL(resource->interfaces);
-                        OICFree(resource);
-                        OCDiscoveryPayloadDestroy(out);
-                        return OC_STACK_NO_MEMORY;
+                        llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+                        llPtr = llPtr->next;
+                        if(!llPtr)
+                        {
+                            OC_LOG(ERROR, TAG, "Memory allocation failed");
+                            OICFree(resource->uri);
+                            OICFree(resource->sid);
+                            OCFreeOCStringLL(resource->types);
+                            OCFreeOCStringLL(resource->interfaces);
+                            OICFree(resource);
+                            OCDiscoveryPayloadDestroy(out);
+                            return OC_STACK_NO_MEMORY;
+                        }
+                    }
+                    else
+                    {
+                            OC_LOG(ERROR, TAG, "Unknown state in resource interfaces copying");
+                            OICFree(resource->uri);
+                            OICFree(resource->sid);
+                            OCFreeOCStringLL(resource->types);
+                            OICFree(resource);
+                            OCDiscoveryPayloadDestroy(out);
+                            return OC_STACK_NO_MEMORY;
                     }
-                }
-                else
-                {
-                        OC_LOG(ERROR, TAG, "Unknown state in resource interfaces copying");
-                        OICFree(resource->uri);
-                        OICFree(resource->sid);
-                        OCFreeOCStringLL(resource->types);
-                        OICFree(resource);
-                        OCDiscoveryPayloadDestroy(out);
-                        return OC_STACK_NO_MEMORY;
-                }
 
-                 err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
-                 err = err || cbor_value_advance(&ifVal);
-            }
-             err = err || cbor_value_leave_container(&ifArray, &ifVal);
+                     err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
+                     err = err || cbor_value_advance(&ifVal);
+                }
+                 err = err || cbor_value_leave_container(&ifArray, &ifVal);
 
-            // Policy
-            {
-                CborValue policyMap;
-                err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
-
-                // Bitmap
-                CborValue val;
-                err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
-                uint64_t temp = 0;
-                err = err || cbor_value_get_uint64(&val, &temp);
-                resource->bitmap = (uint8_t)temp;
-                // Secure Flag
-                err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
-                if(cbor_value_is_valid(&val))
+                // Policy
                 {
-                    err = err || cbor_value_get_boolean(&val, &(resource->secure));
-                    // Port
-                    CborValue port;
-                    err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
-                                    &port);
-                    if(cbor_value_is_valid(&port))
+                    CborValue policyMap;
+                    err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
+
+                    // Bitmap
+                    CborValue val;
+                    err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
+                    uint64_t temp = 0;
+                    err = err || cbor_value_get_uint64(&val, &temp);
+                    resource->bitmap = (uint8_t)temp;
+                    // Secure Flag
+                    err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
+                    if(cbor_value_is_valid(&val))
                     {
-                        err = err || cbor_value_get_uint64(&port, &temp);
-                        resource->port = (uint16_t)temp;
+                        err = err || cbor_value_get_boolean(&val, &(resource->secure));
+                        // Port
+                        CborValue port;
+                        err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
+                                        &port);
+                        if(cbor_value_is_valid(&port))
+                        {
+                            err = err || cbor_value_get_uint64(&port, &temp);
+                            resource->port = (uint16_t)temp;
+                        }
                     }
                 }
             }
-        }
 
-        err = err || cbor_value_advance(arrayVal);
-        if(err)
-        {
-            OICFree(resource->uri);
-            OICFree(resource->sid);
-            OCFreeOCStringLL(resource->types);
-            OCFreeOCStringLL(resource->interfaces);
-            OICFree(resource);
-            OCDiscoveryPayloadDestroy(out);
-            OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
-            return OC_STACK_MALFORMED_RESPONSE;
+            err = err || cbor_value_advance(arrayVal);
+            if(err)
+            {
+                OICFree(resource->uri);
+                OICFree(resource->sid);
+                OCFreeOCStringLL(resource->types);
+                OCFreeOCStringLL(resource->interfaces);
+                OICFree(resource);
+                OCDiscoveryPayloadDestroy(out);
+                OC_LOG_V(ERROR, TAG, "CBOR in error condition: %d", err);
+                return OC_STACK_MALFORMED_RESPONSE;
+            }
+            ++resourceCount;
+            OCDiscoveryPayloadAddNewResource(out, resource);
         }
-        ++resourceCount;
-        OCDiscoveryPayloadAddNewResource(out, resource);
     }
 
     if(err)
@@ -367,6 +416,9 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue*
         *outPayload = (OCPayload*)out;
         return OC_STACK_OK;
     }
+cbor_error:
+    OCDiscoveryCollectionPayloadDestroy(out);
+    return OC_STACK_MALFORMED_RESPONSE;
 }
 
 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
index 04f709b..0d45a24 100644 (file)
 #include "secureresourcemanager.h"
 #include "cacommon.h"
 #include "cainterface.h"
+#include "rdpayload.h"
 
 #ifdef WITH_RD
 #include "rd_server.h"
-#endif 
+#endif
 
 #ifdef ROUTING_GATEWAY
 #include "routingmanager.h"
@@ -287,6 +288,27 @@ OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
     return OC_STACK_OK;
 }
 
+OCStackResult BuildVirtualCollectionResourceResponse(const OCResourceCollectionPayload *resourcePtr,
+        OCDiscoveryPayload *payload, OCDevAddr *devAddr)
+{
+    if (!resourcePtr || !payload)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (resourcePtr->tags && (resourcePtr->tags->bitmap & OC_SECURE))
+    {
+       if (GetSecurePortInfo(devAddr, &resourcePtr->tags->port) != OC_STACK_OK)
+       {
+           OC_LOG(ERROR, TAG, "Failed setting secure port.");
+       }
+    }
+    if (resourcePtr->tags && !resourcePtr->tags->baseURI)
+    {
+        resourcePtr->tags->baseURI = OICStrdup(devAddr->addr);
+    }
+    OCDiscoveryCollectionPayloadAddResource(payload, resourcePtr->tags, resourcePtr->setLinks);
+    return OC_STACK_OK;
+}
 
 uint8_t IsCollectionResource (OCResource *resource)
 {
@@ -546,62 +568,11 @@ OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCRes
 }
 
 #ifdef WITH_RD
-static OCStackResult checkResourceExistsAtRD(const char *interfaceType, const char *resourceType, OCRepPayload **repPayload)
+static OCStackResult checkResourceExistsAtRD(const char *interfaceType, const char *resourceType,
+    OCResourceCollectionPayload **repPayload)
 {
-    char *uri = NULL;
-    char *rt = NULL;
-    char *itf = NULL;
-
-    if (OCRDCheckPublishedResource(interfaceType, resourceType, &uri, &rt, &itf) == OC_STACK_OK)
+    if (OCRDCheckPublishedResource(interfaceType, resourceType, repPayload) == OC_STACK_OK)
     {
-        if (!uri || !rt || !itf)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
-            // if any of the parameter has memory allocated free each one of them.
-            OICFree(uri);
-            OICFree(rt);
-            OICFree(itf);
-            return OC_STACK_NO_MEMORY;
-        }
-
-        OCRepPayload *rdResource = OICCalloc(1, sizeof(OCRepPayload));
-        if (!rdResource)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
-            OICFree(uri);
-            OICFree(rt);
-            OICFree(itf);
-            return OC_STACK_NO_MEMORY;
-        }
-
-        rdResource->uri = uri;
-
-        rdResource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
-        if(!rdResource->types)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
-            OICFree(uri);
-            OICFree(rt);
-            OICFree(itf);
-            OICFree(rdResource);
-            return OC_STACK_NO_MEMORY;
-        }
-        rdResource->types->value = rt;
-
-        rdResource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
-        if(!rdResource->interfaces)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
-            OICFree(uri);
-            OICFree(rt);
-            OICFree(itf);
-            OICFree(rdResource);
-            return OC_STACK_NO_MEMORY;
-        }
-        rdResource->interfaces->value = itf;
-
-        *repPayload = rdResource;
-
         return OC_STACK_OK;
     }
     else
@@ -644,19 +615,19 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
 
             if(payload)
             {
+                bool foundResourceAtRD = false;
                 for(;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
                 {
-                    bool foundResourceAtRD = false;
 #ifdef WITH_RD
                     if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
                     {
-                        OCRepPayload *repPayload = NULL;
+                        OCResourceCollectionPayload *repPayload;
                         discoveryResult = checkResourceExistsAtRD(filterOne, filterTwo, &repPayload);
                         if (discoveryResult != OC_STACK_OK)
                         {
                              break;
                         }
-                        discoveryResult = BuildVirtualResourceResponse((OCResource *)repPayload,
+                        discoveryResult = BuildVirtualCollectionResourceResponse(repPayload,
                                     (OCDiscoveryPayload*)payload,
                                     &request->devAddr);
                         foundResourceAtRD = true;
@@ -669,8 +640,8 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
                                 &request->devAddr);
                     }
                 }
-                // Set discoveryResult appropriately if no 'valid' resources are available.
-                if (((OCDiscoveryPayload*)payload)->resources == NULL)
+                // Set discoveryResult appropriately if no 'valid' resources are available
+                if (((OCDiscoveryPayload*)payload)->resources == NULL && !foundResourceAtRD)
                 {
                     discoveryResult = OC_STACK_NO_RESOURCE;
                 }
@@ -853,13 +824,12 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         type = PAYLOAD_TYPE_SECURITY;
 
     }
-#ifdef WITH_RD
 
-    if (request && request->resourceUrl && strcmp(request->resourceUrl, OC_RSRVD_RD_URI) == 0)
+    if (request && strcmp(request->resourceUrl, OC_RSRVD_RD_URI) == 0)
     {
         type = PAYLOAD_TYPE_RD;
     }
-#endif
+
     result = FormOCEntityHandlerRequest(&ehRequest,
                                         (OCRequestHandle)request,
                                         request->method,
index 6b904b0..8bb0209 100644 (file)
@@ -1173,12 +1173,10 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res
                     {
                         type = PAYLOAD_TYPE_PLATFORM;
                     }
-#ifdef WITH_RD
                     else if (strcmp(cbNode->requestUri, OC_RSRVD_RD_URI) == 0)
                     {
                         type = PAYLOAD_TYPE_RD;
                     }
-#endif
                     else
                     {
                         OC_LOG_V(ERROR, TAG, "Unknown Payload type in Discovery: %d %s",
@@ -1193,7 +1191,6 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res
                          cbNode->method == OC_REST_OBSERVE_ALL ||
                          cbNode->method == OC_REST_DELETE)
                 {
-#ifdef WITH_RD
                     char targetUri[MAX_URI_LENGTH];
                     snprintf(targetUri, MAX_URI_LENGTH, "%s?rt=%s",
                             OC_RSRVD_RD_URI, OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
@@ -1201,7 +1198,6 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res
                     {
                         type = PAYLOAD_TYPE_RD;
                     }
-#endif
                     if (type == PAYLOAD_TYPE_INVALID)
                     {
                         OC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_REPRESENTATION: %d %s",
diff --git a/resource/csdk/stack/src/rdpayload.c b/resource/csdk/stack/src/rdpayload.c
new file mode 100644 (file)
index 0000000..b2453b5
--- /dev/null
@@ -0,0 +1,1145 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include "rdpayload.h"
+
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "octypes.h"
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
+
+#define TAG "OCRDPayload"
+
+#define CBOR_ROOT_ARRAY_LENGTH 1
+
+static CborError FindStringInMap(CborValue *map, char *tags, char **value);
+static CborError FindIntInMap(CborValue *map, char *tags, uint64_t *value);
+static CborError FindStringLLInMap(const CborValue *linksMap, char *tag, OCStringLL **links);
+static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, const char *value);
+static int64_t ConditionalAddIntToMap(CborEncoder *map, const char *tags, const size_t size, const uint64_t *value);
+static int64_t AddStringLLToMap(CborEncoder *map, char *tag, const size_t size, OCStringLL *value);
+
+int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size)
+{
+    if (!outPayload || !size)
+    {
+        OC_LOG(ERROR, TAG, "Invalid parameters.");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    CborEncoder encoder;
+    int flags = 0;
+    cbor_encoder_init(&encoder, outPayload, *size, flags);
+
+    CborEncoder rootArray;
+    CborError cborEncoderResult;
+    cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, CBOR_ROOT_ARRAY_LENGTH);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG(ERROR, TAG, "Failed creating cbor array.");
+        goto cbor_error;
+    }
+
+    if (rdPayload->rdDiscovery)
+    {
+        CborEncoder map;
+        cborEncoderResult = cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+        if (CborNoError != cborEncoderResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed creating discovery map.");
+            goto cbor_error;
+        }
+        if (CborNoError != ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_NAME,
+                sizeof(OC_RSRVD_DEVICE_NAME) - 1, (char *)rdPayload->rdDiscovery->n.deviceName))
+        {
+            OC_LOG(ERROR, TAG, "Failed setting OC_RSRVD_DEVICE_NAME.");
+            goto cbor_error;
+        }
+        if (CborNoError != ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_ID,
+                sizeof(OC_RSRVD_DEVICE_ID) - 1, (char *)rdPayload->rdDiscovery->di.id))
+        {
+            OC_LOG(ERROR, TAG, "Failed setting OC_RSRVD_DEVICE_ID.");
+            goto cbor_error;
+        }
+        uint64_t sel = (uint8_t) rdPayload->rdDiscovery->sel;
+        if (CborNoError != ConditionalAddIntToMap(&map, OC_RSRVD_RD_DISCOVERY_SEL,
+            sizeof(OC_RSRVD_RD_DISCOVERY_SEL) - 1, &sel))
+        {
+            OC_LOG(ERROR, TAG, "Failed setting OC_RSRVD_RD_DISCOVERY_SEL.");
+            goto cbor_error;
+        }
+        cborEncoderResult = cbor_encoder_close_container(&rootArray, &map);
+        if (CborNoError != cborEncoderResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed closing discovery map.");
+            goto cbor_error;
+        }
+    }
+    else if (rdPayload->rdPublish)
+    {
+        CborEncoder colArray;
+        cborEncoderResult = cbor_encoder_create_array(&rootArray, &colArray, CborIndefiniteLength);
+        if (CborNoError != cborEncoderResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed creating collection array.");
+            goto cbor_error;
+        }
+
+        OCResourceCollectionPayload *rdPublish = rdPayload->rdPublish;
+        while (rdPublish)
+        {
+            if (OC_STACK_OK != OCTagsPayloadToCbor(rdPublish->tags, &colArray))
+            {
+                OC_LOG(ERROR, TAG, "Failed creating tags payload.");
+                goto cbor_error;
+            }
+            if (OC_STACK_OK != OCLinksPayloadToCbor(rdPublish->setLinks, &colArray))
+            {
+                OC_LOG(ERROR, TAG, "Failed creating links payload.");
+                goto cbor_error;
+            }
+            rdPublish = rdPublish->next;
+        }
+        cborEncoderResult = cbor_encoder_close_container(&rootArray, &colArray);
+        if (CborNoError != cborEncoderResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed closing collection array.");
+            goto cbor_error;
+        }
+    }
+    cborEncoderResult = cbor_encoder_close_container(&encoder, &rootArray);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG(ERROR, TAG, "Failed closing root array container. ");
+        goto cbor_error;
+    }
+
+    *size = encoder.ptr - outPayload;
+    return OC_STACK_OK;
+
+cbor_error:
+    OICFree(outPayload);
+    return OC_STACK_ERROR;
+}
+
+OCStackResult OCTagsPayloadToCbor(OCTagsPayload *tags, CborEncoder *setMap)
+{
+    CborEncoder tagsMap;
+    CborError cborEncoderResult = cbor_encoder_create_map(setMap, &tagsMap, CborIndefiniteLength);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG(ERROR, TAG, "Failed creating TAGS map.");
+        return OC_STACK_ERROR;
+    }
+
+    if (CborNoError != ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DEVICE_NAME,
+            sizeof(OC_RSRVD_DEVICE_NAME) - 1, (char *)tags->n.deviceName))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_DEVICE_NAME in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    if (CborNoError != ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DEVICE_ID,
+            sizeof(OC_RSRVD_DEVICE_ID) - 1, (char *)tags->di.id))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_DEVICE_ID in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    if (CborNoError != ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_RTS,
+            sizeof(OC_RSRVD_RTS) - 1, (char *)tags->rts))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_RTS in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    if (CborNoError != ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DREL,
+            sizeof(OC_RSRVD_DREL) - 1, (char *)tags->drel))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_DREL in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    if (CborNoError != ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_BASE_URI,
+            sizeof(OC_RSRVD_BASE_URI) - 1, (char *)tags->baseURI))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_BASE_URI in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    uint64_t temp = (uint64_t)tags->bitmap;
+    if (CborNoError != ConditionalAddIntToMap(&tagsMap, OC_RSRVD_BITMAP,
+            sizeof(OC_RSRVD_BITMAP) - 1, &temp))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_BITMAP in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    temp = (uint64_t)tags->port;
+    if (CborNoError != ConditionalAddIntToMap(&tagsMap, OC_RSRVD_HOSTING_PORT,
+            sizeof(OC_RSRVD_HOSTING_PORT) - 1, &temp))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_HOSTING_PORT in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    temp = (uint64_t)tags->ins;
+    if (CborNoError != ConditionalAddIntToMap(&tagsMap, OC_RSRVD_INS,
+            sizeof(OC_RSRVD_INS) - 1, &temp))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_INS in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    temp = (uint64_t)tags->ttl;
+    if (CborNoError != ConditionalAddIntToMap(&tagsMap, OC_RSRVD_TTL,
+            sizeof(OC_RSRVD_TTL) - 1, &temp))
+    {
+        OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_TTL in TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    cborEncoderResult = cbor_encoder_close_container(setMap, &tagsMap);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG(ERROR, TAG, "Failed closing TAGS map.");
+        return OC_STACK_ERROR;
+    }
+    return OC_STACK_OK;
+}
+
+OCStackResult OCLinksPayloadToCbor(OCLinksPayload *rtPtr, CborEncoder *setMap)
+{
+    CborEncoder linksArray;
+    CborError cborEncoderResult;
+
+    cborEncoderResult = cbor_encoder_create_array(setMap, &linksArray, CborIndefiniteLength);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG(ERROR, TAG, "Failed creating LINKS array.");
+        return OC_STACK_ERROR;
+    }
+    while (rtPtr)
+    {
+        CborEncoder linksMap;
+        cborEncoderResult = cbor_encoder_create_map(&linksArray, &linksMap,
+                CborIndefiniteLength);
+        if (CborNoError != cborEncoderResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed creating LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_HREF,
+                sizeof(OC_RSRVD_HREF) - 1, rtPtr->href))
+        {
+            OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_HREF in LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_REL,
+                sizeof(OC_RSRVD_REL) - 1,  rtPtr->rel))
+        {
+            OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_REL in LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_TITLE,
+                sizeof(OC_RSRVD_TITLE) - 1, rtPtr->title))
+        {
+            OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_TITLE in LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_URI,
+                sizeof(OC_RSRVD_URI) - 1, rtPtr->uri))
+        {
+            OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_URI in LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != AddStringLLToMap(&linksMap, OC_RSRVD_RESOURCE_TYPE,
+                sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, rtPtr->rt))
+        {
+            OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_RESOURCE_TYPE in LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != AddStringLLToMap(&linksMap, OC_RSRVD_INTERFACE,
+                sizeof(OC_RSRVD_INTERFACE) - 1, rtPtr->itf))
+        {
+            OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_INTERFACE in LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != AddStringLLToMap(&linksMap, OC_RSRVD_MEDIA_TYPE,
+                sizeof(OC_RSRVD_MEDIA_TYPE) - 1, rtPtr->mt))
+        {
+            OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_MEDIA_TYPE in LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        uint64_t temp = (uint64_t)rtPtr->ins;
+        if (CborNoError != ConditionalAddIntToMap(&linksMap, OC_RSRVD_INS,
+            sizeof(OC_RSRVD_INS) - 1, &temp))
+        {
+            OC_LOG(ERROR, TAG, "Failed adding OC_RSRVD_INS in LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        cborEncoderResult = cbor_encoder_close_container(&linksArray, &linksMap);
+        if (CborNoError != cborEncoderResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed closing LINKS map.");
+            return OC_STACK_ERROR;
+        }
+        rtPtr = rtPtr->next;
+    }
+    cborEncoderResult = cbor_encoder_close_container(setMap, &linksArray);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG(ERROR, TAG, "Failed closing LINKS array.");
+        return OC_STACK_ERROR;;
+    }
+    return OC_STACK_OK;
+}
+
+OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload)
+{
+    CborValue *rdCBORPayload = (CborValue *)cborPayload;
+    CborError cborFindResult;
+
+    OCRDPayload *rdPayload = OCRDPayloadCreate();
+    if (!rdPayload)
+    {
+        goto no_memory;
+    }
+
+    if (cbor_value_is_array(rdCBORPayload))
+    {
+        OCLinksPayload *linksPayload = NULL;
+        OCTagsPayload *tagsPayload = NULL;
+
+        while (cbor_value_is_container(rdCBORPayload))
+        {
+            // enter tags map
+            CborValue tags;
+            cborFindResult = cbor_value_enter_container(rdCBORPayload, &tags);
+            if (cborFindResult != CborNoError)
+            {
+                goto cbor_error;
+            }
+            if (OC_STACK_OK != OCTagsCborToPayload(&tags, &tagsPayload))
+            {
+                OCFreeTagsResource(tagsPayload);
+                goto cbor_error;
+            }
+            OCTagsLog(DEBUG, tagsPayload);
+            if (OC_STACK_OK != OCLinksCborToPayload(&tags, &linksPayload))
+            {
+                OCFreeLinksResource(linksPayload);
+                OCFreeTagsResource(tagsPayload);
+                goto cbor_error;
+            }
+            OCLinksLog(DEBUG, linksPayload);
+            // Move from tags payload to links array.
+            if (CborNoError != cbor_value_advance(rdCBORPayload))
+            {
+                OC_LOG(DEBUG, TAG, "Failed advancing from tags payload to links.");
+                OCFreeLinksResource(linksPayload);
+                OCFreeTagsResource(tagsPayload);
+                goto cbor_error;
+            }
+        }
+        rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
+        if (!rdPayload->rdPublish)
+        {
+            goto cbor_error;
+        }
+    }
+    else if (cbor_value_is_map(rdCBORPayload))
+    {
+        char *name = NULL;
+        if (CborNoError != FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_NAME, &name))
+        {
+            goto cbor_error;
+        }
+        char *id = NULL;
+        if (CborNoError != FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_ID, &id))
+        {
+            goto cbor_error;
+        }
+        uint64_t biasFactor = 0;
+        if (CborNoError != FindIntInMap(rdCBORPayload, OC_RSRVD_RD_DISCOVERY_SEL, &biasFactor))
+        {
+            goto cbor_error;
+        }
+        rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(name, id, (uint8_t)biasFactor);
+        if (!rdPayload->rdDiscovery)
+        {
+            goto no_memory;
+        }
+        OICFree(id);
+        OICFree(name);
+        cborFindResult =  cbor_value_advance(rdCBORPayload);
+        if (CborNoError != cborFindResult)
+        {
+            goto cbor_error;
+        }
+    }
+    OC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
+    *outPayload = (OCPayload *)rdPayload;
+    return OC_STACK_OK;
+no_memory:
+    OC_LOG(ERROR, TAG, "Failed allocating memory.");
+    OCRDPayloadDestroy(rdPayload);
+    return OC_STACK_NO_MEMORY;
+
+cbor_error:
+    OCRDPayloadDestroy(rdPayload);
+    return OC_STACK_ERROR;
+}
+
+static CborError FindStringInMap(CborValue *map, char *tags, char **value)
+{
+    CborValue curVal;
+    size_t len;
+    CborError cborFindResult = cbor_value_map_find_value(map, tags, &curVal);
+    if (CborNoError == cborFindResult && cbor_value_is_text_string(&curVal))
+    {
+        cborFindResult = cbor_value_dup_text_string(&curVal, value, &len, NULL);
+        if (CborNoError != cborFindResult)
+        {
+            OC_LOG_V(ERROR, TAG, "Failed finding value for tag %s .", tags);
+            return cborFindResult;
+        }
+    }
+    return CborNoError;
+}
+
+static CborError FindIntInMap(CborValue *map, char *tags, uint64_t *value)
+{
+    CborValue curVal;
+    CborError cborFindResult = cbor_value_map_find_value(map, tags, &curVal);
+    if (CborNoError == cborFindResult && cbor_value_is_unsigned_integer(&curVal))
+    {
+        cborFindResult = cbor_value_get_uint64(&curVal, value);
+        if (CborNoError != cborFindResult)
+        {
+            OC_LOG_V(ERROR, TAG, "Failed finding value for tag %s .", tags);
+            return cborFindResult;
+        }
+    }
+    return CborNoError;
+}
+
+static CborError FindStringLLInMap(const CborValue *linksMap, char *tag, OCStringLL **links)
+{
+    size_t len;
+    CborError cborFindResult;
+    CborValue rtArray;
+    cborFindResult = cbor_value_map_find_value(linksMap, tag, &rtArray);
+    if (CborNoError != cborFindResult)
+    {
+        return CborUnknownError;
+    }
+    CborValue rtVal;
+    cborFindResult = cbor_value_enter_container(&rtArray, &rtVal);
+    if (CborNoError != cborFindResult)
+    {
+        return CborUnknownError;
+    }
+    OCStringLL* llPtr = *links;
+    while (cbor_value_is_text_string(&rtVal))
+    {
+        if (llPtr == NULL)
+        {
+            llPtr = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!llPtr)
+            {
+                return CborUnknownError;
+            }
+            *links = llPtr;
+        }
+        else if(llPtr)
+        {
+            while (llPtr->next)
+            {
+                llPtr = llPtr->next;
+            }
+            llPtr->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!llPtr->next)
+            {
+                return CborUnknownError;
+            }
+        }
+        cborFindResult = cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
+        if (CborNoError != cborFindResult)
+        {
+            return CborUnknownError;
+        }
+        cborFindResult = cbor_value_advance(&rtVal);
+        if (CborNoError != cborFindResult)
+        {
+            return CborUnknownError;
+        }
+    }
+
+    cborFindResult = cbor_value_leave_container(&rtArray, &rtVal);
+    return cborFindResult;
+}
+
+OCStackResult OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPayload)
+{
+    OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload));
+    if (!tags)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+    if (cbor_value_is_map(tagsMap))
+    {
+        if (CborNoError != FindStringInMap(tagsMap, OC_RSRVD_DEVICE_NAME, &tags->n.deviceName))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != FindStringInMap(tagsMap, OC_RSRVD_DREL, &tags->drel))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != FindStringInMap(tagsMap, OC_RSRVD_RTS, &tags->rts))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        if (CborNoError != FindStringInMap(tagsMap, OC_RSRVD_BASE_URI, &tags->baseURI))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        char *id = NULL;
+        if (CborNoError != FindStringInMap(tagsMap, OC_RSRVD_DEVICE_ID, &id))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        if (id)
+        {
+            OICStrcpy((char*)tags->di.id, MAX_IDENTITY_SIZE, id);
+            tags->di.id_length = MAX_IDENTITY_SIZE;
+            OICFree(id);
+        }
+        uint64_t temp;
+        if (CborNoError != FindIntInMap(tagsMap, OC_RSRVD_HOSTING_PORT, &temp))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        tags->port = (uint16_t) temp;
+        if (CborNoError != FindIntInMap(tagsMap, OC_RSRVD_BITMAP, &temp))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        tags->bitmap = (uint8_t) temp;
+        if (CborNoError != FindIntInMap(tagsMap, OC_RSRVD_INS, &temp))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        tags->ins = (uint8_t) temp;
+        if (CborNoError != FindIntInMap(tagsMap, OC_RSRVD_TTL, &temp))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+        tags->ttl = (uint32_t) temp;
+
+        if (CborNoError != cbor_value_advance(tagsMap))
+        {
+            OCFreeTagsResource(tags);
+            return OC_STACK_ERROR;
+        }
+    }
+    *tagsPayload = tags;
+    return OC_STACK_OK;
+}
+
+OCStackResult OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **linksPayload)
+{
+    CborValue linksMap;
+    CborError cborFindResult = cbor_value_enter_container(linksArray, &linksMap);
+    if (CborNoError != cborFindResult)
+    {
+        OC_LOG(ERROR, TAG, "Failed enter links map");
+        return OC_STACK_ERROR;
+    }
+
+    while (cbor_value_is_map(&linksMap))
+    {
+        OCLinksPayload *setLinks = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload));
+        if (!setLinks)
+        {
+            OC_LOG(ERROR, TAG, "Failed allocating memory.");
+            OCFreeLinksResource(*linksPayload);
+            return OC_STACK_NO_MEMORY;
+        }
+        cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_HREF, &setLinks->href);
+        if (CborNoError != cborFindResult)
+        {
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+        cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel);
+        if (CborNoError != cborFindResult)
+        {
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+
+        cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title);
+        if (CborNoError != cborFindResult)
+        {
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+        cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->uri);
+        if (CborNoError != cborFindResult)
+        {
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt);
+        if (CborNoError != cborFindResult)
+        {
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf);
+        if (CborNoError != cborFindResult)
+        {
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->mt);
+        if (CborNoError != cborFindResult)
+        {
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+        uint64_t temp;
+        cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, &temp);
+        if (CborNoError != cborFindResult)
+        {
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+        setLinks->ins = (uint8_t) temp;
+
+        if (!*linksPayload)
+        {
+            *linksPayload = setLinks;
+        }
+        else
+        {
+            OCLinksPayload *temp = *linksPayload;
+            while (temp->next)
+            {
+                temp = temp->next;
+            }
+            temp->next = setLinks;
+        }
+        cborFindResult = cbor_value_advance(&linksMap);
+        if (CborNoError != cborFindResult)
+        {
+            OC_LOG(ERROR, TAG, "Failed advancing links map");
+            OCFreeLinksResource(*linksPayload);
+            OCFreeLinksResource(setLinks);
+            return OC_STACK_ERROR;
+        }
+    }
+    return OC_STACK_OK;
+}
+
+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));
+}
+
+static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+        const char* value)
+{
+    return value ? AddTextStringToMap(map, key, keylen, value) : 0;
+}
+
+static int64_t ConditionalAddIntToMap(CborEncoder *map, const char *tags, const size_t size,
+    const uint64_t *value)
+{
+    return (*value) ? (cbor_encode_text_string(map, tags, size) |
+                     cbor_encode_uint(map, *value)): 0;
+}
+
+static int64_t AddStringLLToMap(CborEncoder *map, char *tag, const size_t size, OCStringLL *value)
+{
+    CborEncoder array;
+    CborError cborEncoderResult;
+    cborEncoderResult = cbor_encode_text_string(map, tag, size);
+    if (CborNoError != cborEncoderResult)
+    {
+        return cborEncoderResult;
+    }
+    cborEncoderResult = cbor_encoder_create_array(map, &array, CborIndefiniteLength);
+    if (CborNoError != cborEncoderResult)
+    {
+        return cborEncoderResult;
+    }
+    OCStringLL *strType = value;
+    while (strType)
+    {
+        cborEncoderResult = cbor_encode_text_string(&array, strType->value, strlen(strType->value));
+        if (CborNoError != cborEncoderResult)
+        {
+            return cborEncoderResult;
+        }
+        strType = strType->next;
+    }
+    cborEncoderResult = cbor_encoder_close_container(map, &array);
+    if (CborNoError != cborEncoderResult)
+    {
+        return cborEncoderResult;
+    }
+    return cborEncoderResult;
+}
+
+OCRDPayload *OCRDPayloadCreate()
+{
+    OCRDPayload *rdPayload = (OCRDPayload *)OICCalloc(1, sizeof(OCRDPayload));
+
+    if (!rdPayload)
+    {
+        return NULL;
+    }
+
+    rdPayload->base.type = PAYLOAD_TYPE_RD;
+
+    return rdPayload;
+}
+
+OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(const char *deviceName, const char *id, int biasFactor)
+{
+    OCRDDiscoveryPayload *discoveryPayload = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload));
+
+    if (!discoveryPayload)
+    {
+        return NULL;
+    }
+
+    if (deviceName)
+    {
+        discoveryPayload->n.deviceName = OICStrdup(deviceName);
+        if (!discoveryPayload->n.deviceName)
+        {
+            OICFree(discoveryPayload);
+            return NULL;
+        }
+    }
+    if (id)
+    {
+        OICStrcpy((char*)discoveryPayload->di.id, MAX_IDENTITY_SIZE, id);
+    }
+
+    discoveryPayload->sel = biasFactor;
+
+    return discoveryPayload;
+}
+
+void OCRDPayloadDestroy(OCRDPayload *payload)
+{
+    if (!payload)
+    {
+        return;
+    }
+
+    if (payload->rdDiscovery)
+    {
+        if (payload->rdDiscovery->n.deviceName)
+        {
+            OICFree(payload->rdDiscovery->n.deviceName);
+        }
+        OICFree(payload->rdDiscovery);
+    }
+
+    if (payload->rdPublish)
+    {
+        for (OCResourceCollectionPayload *col = payload->rdPublish; col; )
+        {
+            if (col->setLinks)
+            {
+                OCFreeLinksResource(col->setLinks);
+            }
+
+            if (col->tags)
+            {
+                OCFreeTagsResource(col->tags);
+            }
+            OCResourceCollectionPayload *temp = col->next;
+            OICFree(col);
+            col = temp;
+        }
+    }
+
+    OICFree(payload);
+}
+
+OCTagsPayload* OCCopyTagsResources(const char *deviceName, const unsigned char *id, const char *baseURI,
+        uint8_t bitmap, uint16_t port, uint8_t ins, const char *rts,const  char *drel, uint32_t ttl)
+{
+    OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload));
+    if (!tags)
+    {
+        return NULL;
+    }
+       if (deviceName)
+    {
+        tags->n.deviceName = OICStrdup(deviceName);
+        if (!tags->n.deviceName)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    if (id)
+    {
+        OICStrcpy((char*)tags->di.id, MAX_IDENTITY_SIZE, (char *)id);
+        if (!tags->di.id)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    if (baseURI)
+    {
+        tags->baseURI = OICStrdup(baseURI);
+        if (!tags->baseURI)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    tags->bitmap = bitmap;
+    tags->port = port;
+    tags->ins = ins;
+    if (rts)
+    {
+        tags->rts = OICStrdup(rts);
+        if (!tags->rts)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    if (drel)
+    {
+        tags->drel = OICStrdup(drel);
+        if (!tags->drel)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    tags->ttl = ttl;
+    return tags;
+
+memory_allocation_failed:
+    OC_LOG(ERROR, TAG, "Memory allocation failed.");
+    OCFreeTagsResource(tags);
+    return NULL;
+}
+
+OCLinksPayload* OCCopyLinksResources(const char *href, OCStringLL *rt, OCStringLL *itf,
+        const char *rel, bool obs, const char *title, const char *uri, uint8_t ins, OCStringLL *mt)
+{
+    OCLinksPayload *links = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload));
+    if (!links)
+    {
+        OC_LOG(ERROR, TAG, "Failed allocating memory.");
+        return NULL;
+    }
+    if (href)
+    {
+        links->href = OICStrdup(href);
+        if (!links->href)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    if (rt)
+    {
+        links->rt = CloneOCStringLL(rt);
+        if (!links->rt)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    if (itf)
+    {
+        links->itf = CloneOCStringLL(itf);
+        if (!links->itf)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    if (rel)
+    {
+        links->rel = OICStrdup(rel);
+        if (!links->rel)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    links->obs = obs;
+    if (title)
+    {
+        links->title = OICStrdup(title);
+        if (!links->title)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    if (uri)
+    {
+        links->uri = OICStrdup(uri);
+        if (!links->uri)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    links->ins = ins;
+    if (mt)
+    {
+        links->mt = CloneOCStringLL(mt);
+        if (!links->mt)
+        {
+            goto memory_allocation_failed;
+        }
+    }
+    links->next = NULL;
+    return links;
+
+memory_allocation_failed:
+    OC_LOG(ERROR, TAG, "Memory allocation failed.");
+    OCFreeLinksResource(links);
+    return NULL;
+}
+
+void OCLinksAddResource(OCDiscoveryPayload *payload, const char *href, OCStringLL *rt,
+    OCStringLL *itf, const char *rel, bool obs, const char *title, const char *uri,
+    uint8_t ins, OCStringLL *mt)
+{
+    if(!payload->collectionResources->setLinks)
+    {
+        payload->collectionResources->setLinks =
+            OCCopyLinksResources(href, rt, itf, rel, obs, title, uri, ins, mt);
+    }
+    else
+    {
+        OCLinksPayload *p = payload->collectionResources->setLinks;
+        while (p->next)
+        {
+            p = p->next;
+        }
+        p->next = OCCopyLinksResources(href, rt, itf, rel, obs, title, uri, ins, mt);
+    }
+}
+
+OCResourceCollectionPayload* OCCopyCollectionResource(OCTagsPayload *tags, OCLinksPayload *links)
+{
+    if (!tags || !links)
+    {
+        return NULL;
+    }
+    OCResourceCollectionPayload *pl = (OCResourceCollectionPayload *)OICCalloc(1, sizeof(OCResourceCollectionPayload));
+    if(!pl)
+    {
+        OC_LOG(ERROR, TAG, "Failed allocating memory for the OCResourceCollectionPayload.");
+        return NULL;
+    }
+    pl->tags = tags;
+    pl->setLinks = links;
+
+    return pl;
+}
+
+OCStackResult OCDiscoveryCollectionPayloadAddResource(OCDiscoveryPayload *payload, OCTagsPayload *tags, OCLinksPayload *links)
+{
+    OCResourceCollectionPayload* res = OCCopyCollectionResource(tags, links);
+    if (res == NULL)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+    if(!payload->collectionResources)
+    {
+        payload->collectionResources = res;
+    }
+    else
+    {
+        OCResourceCollectionPayload *p = payload->collectionResources;
+        while(p->next)
+        {
+            p = p->next;
+        }
+        p->next = res;
+    }
+    return OC_STACK_OK;
+}
+
+void OCFreeLinksResource(OCLinksPayload *payload)
+{
+    if (!payload)
+    {
+        return;
+    }
+    OICFree(payload->href);
+    OCFreeOCStringLL(payload->rt);
+    OCFreeOCStringLL(payload->itf);
+    OICFree(payload->rel);
+    OICFree(payload->title);
+    OICFree(payload->uri);
+    OCFreeOCStringLL(payload->mt);
+    OCFreeLinksResource(payload->next);
+    OICFree(payload);
+}
+
+void OCFreeTagsResource(OCTagsPayload *payload)
+{
+    if (!payload)
+    {
+        return;
+    }
+    OICFree(payload->n.deviceName);
+    OICFree(payload->baseURI);
+    OICFree(payload->rts);
+    OICFree(payload->drel);
+    OICFree(payload);
+}
+
+void OCFreeCollectionResource(OCResourceCollectionPayload *payload)
+{
+    if (!payload)
+    {
+        return;
+    }
+    if (payload->tags)
+    {
+        OCFreeTagsResource(payload->tags);
+    }
+    if (payload->setLinks)
+    {
+        OCFreeLinksResource(payload->setLinks);
+    }
+    OCFreeCollectionResource(payload->next);
+    OICFree(payload);
+}
+
+void OCDiscoveryCollectionPayloadDestroy(OCDiscoveryPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OCFreeCollectionResource(payload->collectionResources);
+    OICFree(payload);
+}
+
+
+void OCTagsLog(const LogLevel level, const OCTagsPayload *tags)
+{
+    if (tags)
+    {
+        if (tags->n.deviceName)
+        {
+            OC_LOG_V(level, TAG, " Device Name : %s ",tags->n.deviceName);
+        }
+        if (tags->baseURI)
+        {
+            OC_LOG_V(level, TAG, " Base URI : %s ",tags->baseURI);
+        }
+        OC_LOG_V(level, TAG, " Device ID : %s ",tags->di.id);
+        OC_LOG_V(level, TAG, " Bitmap : %d ",tags->bitmap);
+        OC_LOG_V(level, TAG, " Port : %d ",tags->port);
+        OC_LOG_V(level, TAG, " Ins : %d ",tags->ins);
+        OC_LOG_V(level, TAG, " Ttl : %d ",tags->ttl);
+
+        if (tags->rts)
+        {
+            OC_LOG_V(level, TAG, " RTS : %s ",tags->rts);
+        }
+        if (tags->drel)
+        {
+            OC_LOG_V(level, TAG, " DREL : %s ",tags->drel);
+        }
+    }
+}
+
+void OCLinksLog(const LogLevel level, const OCLinksPayload *links)
+{
+    while (links)
+    {
+        if (links->href)
+        {
+            OC_LOG_V(level, TAG, " href: %s ",links->href);
+        }
+        OC_LOG(level, TAG, " RT: ");
+        OCStringLL *rt = links->rt;
+        while (rt)
+        {
+            if (rt->value)
+            {
+                OC_LOG_V(level, TAG, "   %s", rt->value);
+            }
+            rt = rt->next;
+        }
+        OC_LOG(level, TAG, " IF: ");
+        OCStringLL *itf = links->itf;
+        while (itf)
+        {
+            if (itf->value)
+            {
+                OC_LOG_V(level, TAG, "   %s", itf->value);
+            }
+            itf = itf->next;
+        }
+        OC_LOG(level, TAG, " MT: ");
+        OCStringLL *mt = links->mt;
+        while (mt)
+        {
+            if (mt->value)
+            {
+                OC_LOG_V(level, TAG, "   %s", mt->value);
+            }
+            mt = mt->next;
+        }
+        OC_LOG_V(level, TAG, " INS: %d", links->ins);
+        OC_LOG_V(level, TAG, " OBS: %d", links->obs);
+        if (links->rel)
+        {
+            OC_LOG_V(level, TAG, " REL: %s", links->rel);
+        }
+        if (links->title)
+        {
+            OC_LOG_V(level, TAG, " TITLE: %s", links->title);
+        }
+        if (links->uri)
+        {
+            OC_LOG_V(level, TAG, " URI: %s", links->uri);
+        }
+        links = links->next;
+    }
+}
index eff3a9a..b112af1 100644 (file)
@@ -44,37 +44,65 @@ namespace OC
                     : m_clientWrapper(cw), m_devAddr(devAddr)
             {
                 OCResourcePayload* res = payload->resources;
-
-                while(res)
+                OCResourceCollectionPayload* colRes = payload->collectionResources;
+                if (res)
                 {
-                    char uuidString[UUID_STRING_SIZE];
-                    if(OCConvertUuidToString(res->sid, uuidString) != RAND_UUID_OK)
+                    while(res)
                     {
-                        uuidString[0]= '\0';
-                    }
+                        char uuidString[UUID_STRING_SIZE];
+                        if(OCConvertUuidToString(res->sid, uuidString) != RAND_UUID_OK)
+                        {
+                            uuidString[0]= '\0';
+                        }
 
-                    if (res->secure)
-                    {
-                        m_devAddr.flags =
-                              (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
-                    }
+                        if (res->secure)
+                        {
+                            m_devAddr.flags =
+                                  (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
+                        }
 
-                    if (res->port != 0)
-                    {
-                         m_devAddr.port = res->port;
-                    }
+                        if (res->port != 0)
+                        {
+                             m_devAddr.port = res->port;
+                        }
 
-                    m_resources.push_back(std::shared_ptr<OC::OCResource>(
-                                new OC::OCResource(m_clientWrapper, m_devAddr,
-                                    std::string(res->uri),
-                                    std::string(uuidString),
-                                    (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
-                                    StringLLToVector(res->types),
-                                    StringLLToVector(res->interfaces)
-                                    )));
-                    res = res->next;
+                        m_resources.push_back(std::shared_ptr<OC::OCResource>(
+                                    new OC::OCResource(m_clientWrapper, m_devAddr,
+                                        std::string(res->uri),
+                                        std::string(uuidString),
+                                        (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                        StringLLToVector(res->types),
+                                        StringLLToVector(res->interfaces)
+                                        )));
+                        res = res->next;
+                    }
                 }
+                else if (colRes)
+                {
+                    while(colRes)
+                    {
+                        if (colRes->tags->bitmap & OC_SECURE)
+                        {
+                            m_devAddr.flags =
+                                  (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
+                        }
 
+                        if (colRes->tags->port != 0)
+                        {
+                             m_devAddr.port = colRes->tags->port;
+                        }
+
+                        m_resources.push_back(std::shared_ptr<OC::OCResource>(
+                                    new OC::OCResource(m_clientWrapper, m_devAddr,
+                                        std::string(colRes->setLinks->href),
+                                        std::string((char*)colRes->tags->di.id),
+                                        (colRes->tags->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                        StringLLToVector(colRes->setLinks->rt),
+                                        StringLLToVector(colRes->setLinks->itf)
+                                        )));
+                        colRes = colRes->next;
+                    }
+                }
             }
 
             const std::vector<std::shared_ptr<OCResource>>& Resources() const
index 76200c2..3e02991 100755 (executable)
@@ -66,7 +66,6 @@ RD_SRC_DIR = 'src/'
 rd_src = [
         RD_SRC_DIR + '/internal/rd_storage.c',
         RD_SRC_DIR + 'rd_server.c',
-        RD_SRC_DIR + 'rd_payload.c',
         RD_SRC_DIR + 'rd_client.c',
          ]
 
index 20becb7..475eb75 100644 (file)
 // Iotivity Base CAPI
 #include "ocstack.h"
 
-#include "rd_types.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif // __cplusplus
 
+/** Max ADDR SIZE */
+#define MAX_ADDR_STR_SIZE                (40)
+
+/** Callback function for returning RDDiscovery Result. */
+typedef int (* OCRDBiasFactorCB)(char addr[MAX_ADDR_STR_SIZE], uint16_t port);
+
+/** Context structure used sending it as part of the callback context. */
+typedef struct
+{
+    /** Stores the context value of the message sent. */
+    void *context;
+    /** Pointing to the callback function that OCRDDiscover() received. */
+    OCRDBiasFactorCB cbFunc;
+} OCRDClientContextCB;
+
 /**
  * Discovers the resource directory.
  * This function searches a RD server and obtain the bias factor.
index 8a3631e..f9bf46f 100644 (file)
@@ -29,8 +29,7 @@ extern "C" {
 #endif // __cplusplus
 
 /**
-* Starts resource directory.
-* This function creates a RD server and create resource /oic/rd.
+* This function creates resource /oic/rd.
 *
 * @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR in case of error.
 */
@@ -59,7 +58,7 @@ OCStackResult OCRDStop();
  * the case that OC_STACK_SUCCESS is returned.
  */
 OCStackResult OCRDCheckPublishedResource(const char *interfaceType, const char *resourceType,
-         char **uri, char **rt, char **itf);
+        OCResourceCollectionPayload **payload);
 
 #ifdef __cplusplus
 }
diff --git a/service/resource-directory/include/rd_types.h b/service/resource-directory/include/rd_types.h
deleted file mode 100644 (file)
index 879f876..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-//******************************************************************
-//
-// Copyright 2015 Samsung Electronics All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#ifndef _RESOURCE_DIRECTORY_TYPES_H_
-#define _RESOURCE_DIRECTORY_TYPES_H_
-
-#include "ocpayload.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-/** Resource Directory URI used to Discover RD and Publish resources.*/
-#define OC_RSRVD_RD_URI                  "/oic/rd"
-
-/** To represent resource type with rd.*/
-#define OC_RSRVD_RESOURCE_TYPE_RD        "oic.wk.rd"
-
-/** RD Discovery bias factor type. */
-#define OC_RSRVD_RD_DISCOVERY_SEL        "sel"
-
-/** To represent resource type with Publish RD.*/
-#define OC_RSRVD_RESOURCE_TYPE_RDPUBLISH "oic.wk.rdPub"
-
-/** Max ADDR SIZE */
-#define MAX_ADDR_STR_SIZE (40)
-
-/** Callback function for returning RDDiscovery Result. */
-typedef int (* OCRDBiasFactorCB)(char addr[MAX_ADDR_STR_SIZE], uint16_t port);
-
-/** Context structure used sending it as part of the callback context. */
-typedef struct
-{
-    /** Stores the context value of the message sent. */
-    void *context;
-    /** Pointing to the callback function that OCRDDiscover() received. */
-    OCRDBiasFactorCB cbFunc;
-} OCRDClientContextCB;
-
-/**
- * Structure holding discovery payload.
- */
-typedef struct
-{
-    /** Value holding the bias factor of the RD. */
-    uint8_t sel;
-} OCRDDiscoveryPayload;
-
-/**
- * Structure holding RD Links Payload. It is a sub-structure used in
- * OCRDPublishPayload.
- */
-typedef struct OCRDLinksPayload
-{
-    /** Web Link Address of the resource. */
-    char *href;
-    /** Resource type of the resource. */
-    char *rt;
-    /** Interace type of the resource. */
-    char *itf;
-    /** Holding address of the next resource. */
-    struct OCRDLinksPayload *next;
-} OCRDLinksPayload;
-
-/**
- * Structure holding RD Publish payload.
- */
-typedef struct
-{
-    /** Device Name. */
-    OCDeviceInfo deviceName;
-    /** Device id. */
-    OCIdentity deviceId;
-    /** Time to keep holding resource.*/
-    uint32_t ttl;
-    /** List of resource information that will be stored at RD.*/
-    OCRDLinksPayload *links;
-} OCRDPublishPayload;
-
-/**
- * Enum values of multiple RD type payload.
- */
-typedef enum
-{
-    /** Value of the RD discovery payload. */
-    RD_PAYLOAD_TYPE_DISCOVERY,
-    /** Value of the RD publish payload. */
-    RD_PAYLOAD_TYPE_PUBLISH,
-    /** Value of the RD response in the payload. */
-    RD_PAYLOAD_TYPE_RESPONSE
-} OCRDPayloadType;
-
-/**
- * RD Payload that will be transmitted over the wire.
- */
-typedef struct
-{
-    /** Used in ocpayload to check type of the packet. This matches other OC payload.*/
-    OCPayload base;
-    /** Used internally in RD to check the payload whether discovery or publish.*/
-    OCRDPayloadType payloadType;
-    /** Pointer to the discovery response payload.*/
-    OCRDDiscoveryPayload *rdDiscovery;
-    /** Pointer to the publish payload.*/
-    OCRDPublishPayload *rdPublish;
-} OCRDPayload;
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif
index b9a2a16..c4d2128 100644 (file)
@@ -1,3 +1,23 @@
+#******************************************************************
+#
+# Copyright 2015 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
 ##
 # ResourceDirectory Sample Apps build script
 ##
index 41d5abf..cad3ef3 100644 (file)
@@ -34,7 +34,12 @@ void handleSigInt(int signum);
 int main()
 {
     printf("OCResourceDirectory is starting...\n");
-
+    OCStackResult result = OCInit(NULL, 0, OC_CLIENT_SERVER);
+    if (result != OC_STACK_OK)
+    {
+        printf("Failed starting RD server ...\n");
+        return 0;
+    }
     if (OCRDStart() != OC_STACK_OK)
     {
         printf("OCRDStart failed...\n");
index 9c7c77c..0210a49 100644 (file)
 #include "rd_storage.h"
 
 #include <pthread.h>
+#include <string.h>
 
+#include "payload_logging.h"
 #include "oic_malloc.h"
-#include "oic_string.h"
-#include "logger.h"
 
-#include "rd_payload.h"
+#include "rdpayload.h"
 
 #define TAG  PCF("RDStorage")
 
@@ -35,41 +35,77 @@ static OCRDStorePublishResources *g_rdStorage = NULL;
 
 static void printStoragedResources(OCRDStorePublishResources *payload)
 {
-    OC_LOG_V(DEBUG, TAG, "Print Storage Resources ... ");
+    OC_LOG(DEBUG, TAG, "Print Storage Resources ... ");
     for (OCRDStorePublishResources *temp = payload; temp; temp = temp->next)
     {
-        if (temp->publishResource)
+        if (temp->publishedResource)
         {
-            OCRDPublishPayloadLog(DEBUG, TAG, temp->publishResource);
+            OCTagsLog(DEBUG, TAG, temp->publishedResource->tags);
+            OCLinksLog(DEBUG, TAG, temp->publishedResource->setLinks);
         }
     }
 }
 
-OCStackResult OCRDStorePublishedResources(OCRDPublishPayload *payload)
+OCStackResult OCRDStorePublishedResources(const OCResourceCollectionPayload *payload)
 {
-    OCRDStorePublishResources *storeResource = OICCalloc(1, sizeof(OCRDStorePublishResources));
+    OCResourceCollectionPayload *storeResource = (OCResourceCollectionPayload *)OICCalloc(1, sizeof(OCResourceCollectionPayload));
     if (!storeResource)
     {
-        OC_LOG_V(ERROR, TAG, "Failed allocating memory for OCRDStorePublishResources.");
+        OC_LOG(ERROR, TAG, "Failed allocating memory for OCRDStorePublishResources.");
         return OC_STACK_NO_MEMORY;
     }
 
-    OC_LOG_V(DEBUG, TAG, "Storing Resources ... ");
+    OC_LOG(DEBUG, TAG, "Storing Resources ... ");
 
-    OCRDLinksPayload* linksPayload = NULL;
-    for ( OCRDLinksPayload* links = payload->links ; links; links = links->next)
+    OCTagsPayload *tags = payload->tags;
+    storeResource->tags = OCCopyTagsResources(tags->n.deviceName, tags->di.id, tags->baseURI,
+        tags->bitmap, tags->port, tags->ins, tags->rts, tags->drel, tags->ttl);
+    if (!storeResource->tags)
     {
-        OCRDLinksPayloadCreate(links->href, links->rt, links->itf, &linksPayload);
+        OC_LOG(ERROR, TAG, "Failed allocating memory for tags.");
+        OCFreeCollectionResource(storeResource);
+        return OC_STACK_NO_MEMORY;
     }
 
-    storeResource->publishResource = OCRDPublishPayloadCreate(payload->ttl, linksPayload);
-    if (!storeResource->publishResource)
+    for (OCLinksPayload *links = payload->setLinks; links; links = links->next)
     {
-        OC_LOG_V(ERROR, TAG, "Failed allocating memory for OCRDPublishResources.");
-        OICFree(storeResource);
-        return OC_STACK_NO_MEMORY;
+        if (!storeResource->setLinks)
+        {
+            storeResource->setLinks = OCCopyLinksResources(links->href, links->rt, links->itf,
+                links->rel, links->obs, links->title, links->uri, links->ins, links->mt);
+            if (!storeResource->setLinks)
+            {
+                OC_LOG(ERROR, TAG, "Failed allocating memory for links.");
+                OCFreeCollectionResource(storeResource);
+                return OC_STACK_NO_MEMORY;
+            }
+        }
+        else
+        {
+            OCLinksPayload *temp = storeResource->setLinks;
+            while (temp->next)
+            {
+                temp = temp->next;
+            }
+            temp->next = OCCopyLinksResources(links->href, links->rt, links->itf, links->rel,
+                links->obs, links->title, links->uri, links->ins, links->mt);
+            if (!temp->next)
+            {
+                OC_LOG(ERROR, TAG, "Failed allocating memory for links.");
+                OCFreeCollectionResource(storeResource);
+                return OC_STACK_NO_MEMORY;
+            }
+        }
+
     }
     storeResource->next = NULL;
+    OCRDStorePublishResources *resources = (OCRDStorePublishResources *)OICCalloc(1, sizeof(OCRDStorePublishResources));
+    if (!resources)
+    {
+        OCFreeCollectionResource(storeResource);
+        return OC_STACK_NO_MEMORY;
+    }
+    resources->publishedResource = storeResource;
 
     pthread_mutex_lock(&storageMutex);
     if (g_rdStorage)
@@ -79,11 +115,11 @@ OCStackResult OCRDStorePublishedResources(OCRDPublishPayload *payload)
         {
             temp = temp->next;
         }
-        temp->next = storeResource;
+        temp->next = resources;
     }
     else
     {
-        g_rdStorage = storeResource;
+        g_rdStorage = resources;
     }
     pthread_mutex_unlock(&storageMutex);
 
@@ -92,68 +128,103 @@ OCStackResult OCRDStorePublishedResources(OCRDPublishPayload *payload)
 }
 
 OCStackResult OCRDCheckPublishedResource(const char *interfaceType, const char *resourceType,
-        char **uri, char **rt, char **itf)
+        OCResourceCollectionPayload **payload)
 {
     // ResourceType and InterfaceType if both are NULL it will return. If either is
     // not null it will continue execution.
     if (!resourceType && !interfaceType)
     {
-        OC_LOG_V(DEBUG, TAG, "Missing resource type and interace type.");
+        OC_LOG(DEBUG, TAG, "Missing resource type and interace type.");
         return OC_STACK_INVALID_PARAM;
     }
 
-    OC_LOG_V(DEBUG, TAG, "Check Resource in RD");
-
-    if (g_rdStorage && g_rdStorage->publishResource && g_rdStorage->publishResource->links)
+    OC_LOG(DEBUG, TAG, "Check Resource in RD");
+    if (g_rdStorage && g_rdStorage->publishedResource)
     {
-        for (OCRDLinksPayload *tLinks = g_rdStorage->publishResource->links; tLinks; tLinks = tLinks->next)
+        for (OCRDStorePublishResources *pResource = g_rdStorage;
+                pResource; pResource = pResource->next)
         {
-            bool found = false;
-            // If either rt or itf are NULL, it should skip remaining code execution.
-            if (!tLinks->rt || !tLinks->itf)
-            {
-                OC_LOG_V(DEBUG, TAG, "Either resource type and interface type are missing.");
-                continue;
-            }
-            OC_LOG_V(DEBUG, TAG, "Resource Type: %s %s", resourceType, tLinks->rt);
-            OC_LOG_V(DEBUG, TAG, "Resource Type: %s %s", interfaceType, tLinks->itf);
-            if (resourceType && strcmp(resourceType, tLinks->rt) == 0)
+            if (pResource->publishedResource->setLinks)
             {
-                found = true;
-            }
-
-            if (interfaceType && strcmp(interfaceType, tLinks->itf) == 0)
-            {
-                found = true;
-            }
-
-            if (found)
-            {
-                *uri = OICStrdup(tLinks->href);
-                if (!*uri)
-                {
-                    OC_LOG_V(ERROR, TAG, "Copy failed..");
-                    return OC_STACK_ERROR;
-                }
-                *rt = OICStrdup(tLinks->rt);
-                if (!*rt)
+                for (OCLinksPayload *tLinks = pResource->publishedResource->setLinks; tLinks; tLinks = tLinks->next)
                 {
-                    OC_LOG_V(ERROR, TAG, "Copy failed..");
-                    OICFree(*uri);
-                    return OC_STACK_ERROR;
+                    // If either rt or itf are NULL, it should skip remaining code execution.
+                    if (!tLinks->rt || !tLinks->itf)
+                    {
+                        OC_LOG(DEBUG, TAG, "Either resource type and interface type are missing.");
+                        continue;
+                    }
+                    if (resourceType)
+                    {
+                        OCStringLL *temp = tLinks->rt;
+                        while(temp)
+                        {
+                            OC_LOG_V(DEBUG, TAG, "Resource Type: %s %s", resourceType, temp->value);
+                            if (strcmp(resourceType, temp->value) == 0)
+                            {
+                                OCTagsPayload *tag = pResource->publishedResource->tags;
+                                OCTagsPayload *tags = OCCopyTagsResources(tag->n.deviceName, tag->di.id, tag->baseURI,
+                                    tag->bitmap, tag->port, tag->ins, tag->rts, tag->drel, tag->ttl);
+                                if (!tags)
+                                {
+                                    return OC_STACK_NO_MEMORY;
+                                }
+                                OCLinksPayload *links = OCCopyLinksResources(tLinks->href, tLinks->rt, tLinks->itf,
+                                    tLinks->rel, tLinks->obs, tLinks->title, tLinks->uri, tLinks->ins, tLinks->mt);
+                                if (!links)
+                                {
+                                    OCFreeTagsResource(tags);
+                                    return OC_STACK_NO_MEMORY;
+                                }
+                                *payload = OCCopyCollectionResource(tags, links);
+                                if (!*payload)
+                                {
+                                    OCFreeTagsResource(tags);
+                                    OCFreeLinksResource(links);
+                                    return OC_STACK_NO_MEMORY;
+                                }
+                                return OC_STACK_OK;
+                            }
+                            temp = temp->next;
+                        }
+                    }
+                    if (interfaceType)
+                    {
+                        OCStringLL *temp = tLinks->itf;
+                        while (temp)
+                        {
+                            OC_LOG_V(DEBUG, TAG, "Interface Type: %s %s", interfaceType, temp->value);
+                            if (strcmp(interfaceType, temp->value) == 0)
+                            {
+                                OCTagsPayload *tag = pResource->publishedResource->tags;
+                                OCTagsPayload *tags = OCCopyTagsResources(tag->n.deviceName, tag->di.id, tag->baseURI,
+                                    tag->bitmap, tag->port, tag->ins, tag->rts, tag->drel, tag->ttl);
+                                if (!tags)
+                                {
+                                    return OC_STACK_NO_MEMORY;
+                                }
+                                OCLinksPayload *links = OCCopyLinksResources(tLinks->uri, tLinks->rt, tLinks->itf,
+                                    tLinks->rel, tLinks->obs, tLinks->title, tLinks->uri, tLinks->ins, tLinks->mt);
+                                if (!links)
+                                {
+                                    OCFreeTagsResource(tags);
+                                    return OC_STACK_NO_MEMORY;
+                                }
+                                *payload = OCCopyCollectionResource(tags, links);
+                                if (!*payload)
+                                {
+                                    OCFreeTagsResource(tags);
+                                    OCFreeLinksResource(links);
+                                    return OC_STACK_NO_MEMORY;
+                                }
+                                return OC_STACK_OK;
+                            }
+                            temp = temp->next;
+                        }
+                    }
                 }
-                *itf = OICStrdup(tLinks->itf);
-                if (!*itf)
-                {
-                    OC_LOG_V(ERROR, TAG, "Copy failed..");
-                    OICFree(*uri);
-                    OICFree(*rt);
-                    return OC_STACK_ERROR;
-                }
-                return OC_STACK_OK;
             }
         }
     }
-
     return OC_STACK_ERROR;
 }
index cc55425..bbc5e48 100644 (file)
 #ifndef _RESOURCE_DIRECTORY_SERVER_STORAGE_H_
 #define _RESOURCE_DIRECTORY_SERVER_STORAGE_H_
 
-#include "rd_types.h"
+#include "octypes.h"
 
 /** Stucture holding Published Resources on the Resource Directory. */
 typedef struct OCRDStorePublishResources
 {
     /** Publish resource. */
-    OCRDPublishPayload *publishResource;
+    OCResourceCollectionPayload *publishedResource;
     /** Linked list pointing to next published resource. */
     struct OCRDStorePublishResources *next;
 } OCRDStorePublishResources;
@@ -38,7 +38,7 @@ typedef struct OCRDStorePublishResources
  *
  * @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR in case of error.
  */
-OCStackResult OCRDStorePublishedResources(OCRDPublishPayload *payload);
+OCStackResult OCRDStorePublishedResources(const OCResourceCollectionPayload *payload);
 
 #ifdef __cplusplus
 }
index 63077ca..74096e3 100644 (file)
 // limitations under the License.
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <stdarg.h>
-
 #include "rd_client.h"
 
-#include "logger.h"
-#include "oic_malloc.h"
+#include <stdarg.h>
+
 #include "oic_string.h"
+#include "oic_malloc.h"
+#include "payload_logging.h"
 
-#include "rd_payload.h"
+#include "rdpayload.h"
+#include "ocpayload.h"
 
 #define DEFAULT_CONTEXT_VALUE 0x99
 #define OC_RD_PUBLISH_TTL 86400
@@ -51,21 +52,22 @@ static OCStackResult sendRequest(OCMethod method, char *uri, OCDevAddr *addr,
 
     if (result == OC_STACK_OK)
     {
-        OC_LOG_V(DEBUG, TAG, "Resource Directory send successful...");
+        OC_LOG(DEBUG, TAG, "Resource Directory send successful...");
     }
     else
     {
-        OC_LOG_V(ERROR, TAG, "Resource Directory send failed...");
+        OC_LOG(ERROR, TAG, "Resource Directory send failed...");
     }
 
     return result;
 }
 
-static OCStackApplicationResult handlePublishCB(void *ctx,
-        OCDoHandle handle, OCClientResponse *clientResponse)
+static OCStackApplicationResult handlePublishCB(__attribute__((unused))void *ctx,
+        __attribute__((unused)) OCDoHandle handle,
+        __attribute__((unused)) OCClientResponse *clientResponse)
 {
     OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
-    OC_LOG_V(DEBUG, TAG, "Successfully published resources.");
+    OC_LOG(DEBUG, TAG, "Successfully published resources.");
 
     // TOOO: Stop multicast traffic on the client.
 
@@ -78,7 +80,7 @@ static void retreiveRDDetails(OCClientResponse *clientResponse, OCRDBiasFactorCB
             clientResponse->devAddr.port);
 
     OCRDPayload *payload = (OCRDPayload *) clientResponse->payload;
-    OCRDPayloadLog(DEBUG, TAG, payload);
+    OC_LOG_PAYLOAD(DEBUG, (OCPayload *) payload);
 
     // TODO: Multiple Resource Directory will have different biasFactor,
     // needs to cache here detail
@@ -91,7 +93,7 @@ static void retreiveRDDetails(OCClientResponse *clientResponse, OCRDBiasFactorCB
 }
 
 static OCStackApplicationResult handleDiscoverCB(void *ctx,
-        OCDoHandle handle, OCClientResponse *clientResponse)
+        __attribute__((unused)) OCDoHandle handle, OCClientResponse *clientResponse)
 {
     OC_LOG(DEBUG, TAG, "Found Resource Directory");
     OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
@@ -100,16 +102,16 @@ static OCStackApplicationResult handleDiscoverCB(void *ctx,
     if (!cb)
     {
         OC_LOG(ERROR, TAG, "RD Context Invalid Parameters.");
-        return OC_STACK_INVALID_PARAM;
+        return ret;
     }
 
     if (cb->context != (void *) DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG(ERROR, TAG, "RD Context Invalid Context Value Parameters.");
-        return OC_STACK_INVALID_PARAM;
+        return ret;
     }
 
-    OC_LOG(DEBUG, TAG, "Callback Context for DISCOVER query received successfully.");
+    OC_LOG_V(DEBUG, TAG, "Callback Context for DISCOVER query received successfully :%d.", clientResponse->result);
 
     if (clientResponse && clientResponse->result == OC_STACK_OK)
     {
@@ -139,7 +141,7 @@ OCStackResult OCRDDiscover(OCRDBiasFactorCB cbBiasFactor)
 
     OC_LOG_V(DEBUG, TAG, "Querying RD: %s\n", queryUri);
 
-    OCRDClientContextCB *cbContext = OICCalloc(1, sizeof(OCRDClientContextCB));
+    OCRDClientContextCB *cbContext = (OCRDClientContextCB *)OICCalloc(1, sizeof(OCRDClientContextCB));
     if (!cbContext)
     {
         OC_LOG(ERROR, TAG, "Failed allocating memory.");
@@ -157,11 +159,56 @@ OCStackResult OCRDDiscover(OCRDBiasFactorCB cbBiasFactor)
     return sendRequest(OC_REST_DISCOVER, queryUri, NULL, NULL, cbData);
 }
 
+static OCStackResult createStringLL(uint8_t numElements, OCResourceHandle handle,
+    const char* (*getValue)(OCResourceHandle handle, uint8_t i), OCStringLL **stringLL)
+{
+    for (uint8_t i = 0; i < numElements; ++i)
+    {
+        const char *value = getValue(handle, i);
+        if (!*stringLL)
+        {
+            *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!*stringLL)
+            {
+                OC_LOG(ERROR, TAG, "Failed allocating memory.");
+                return OC_STACK_NO_MEMORY;
+            }
+            (*stringLL)->value = OICStrdup(value);
+            if (!(*stringLL)->value)
+            {
+                OC_LOG(ERROR, TAG, "Failed copying to OCStringLL.");
+                return OC_STACK_NO_MEMORY;
+            }
+        }
+        else
+        {
+            OCStringLL *cur = *stringLL;
+            while (cur->next)
+            {
+                cur = cur->next;
+            }
+            cur->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!cur->next)
+            {
+                OC_LOG(ERROR, TAG, "Failed allocating memory.");
+                return OC_STACK_NO_MEMORY;
+            }
+            cur->next->value = OICStrdup(value);
+            if (!cur->next->value)
+            {
+                OC_LOG(ERROR, TAG, "Failed copying to OCStringLL.");
+                return OC_STACK_NO_MEMORY;
+            }
+        }
+    }
+    return OC_STACK_OK;
+}
+
 OCStackResult OCRDPublish(char *addr, uint16_t port, int numArg, ... )
 {
     if (!addr)
     {
-        OC_LOG_V(ERROR, TAG, "RD address not specified.");
+        OC_LOG(ERROR, TAG, "RD address not specified.");
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -176,7 +223,25 @@ OCStackResult OCRDPublish(char *addr, uint16_t port, int numArg, ... )
     cbData.cd = NULL;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
 
-    OCRDLinksPayload* linksPayload = NULL;
+    OCTagsPayload *tagsPayload = NULL;
+    OCLinksPayload *linksPayload = NULL;
+    OCStringLL *rt = NULL;
+    OCStringLL *itf = NULL;
+    OCStringLL *mt = NULL;
+
+    OCRDPayload *rdPayload = OCRDPayloadCreate();
+    if (!rdPayload)
+    {
+        goto no_memory;
+    }
+
+    const unsigned char *id = (unsigned char*) OCGetServerInstanceIDString();
+    tagsPayload = OCCopyTagsResources(NULL, id,
+            NULL, OC_DISCOVERABLE, 0, 0, NULL, NULL, OC_RD_PUBLISH_TTL);
+    if (!tagsPayload)
+    {
+        goto no_memory;
+    }
 
     va_list arguments;
     va_start (arguments, numArg);
@@ -186,35 +251,93 @@ OCStackResult OCRDPublish(char *addr, uint16_t port, int numArg, ... )
         OCResourceHandle handle = va_arg(arguments, OCResourceHandle);
         if (handle)
         {
-            const char* uri = OCGetResourceUri(handle);
-            const char* rt  = OCGetResourceTypeName(handle, 0);
-            const char* itf = OCGetResourceInterfaceName(handle, 0);
-            if (uri && rt && itf)
+            rt = itf = mt = NULL;
+            const char *uri = OCGetResourceUri(handle);
+            uint8_t numElement;
+            if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement))
+            {
+                OCStackResult res = createStringLL(numElement, handle, OCGetResourceTypeName, &rt);
+                if (res != OC_STACK_OK || !rt)
+                {
+                    va_end(arguments);
+                    goto no_memory;
+                }
+            }
+
+            if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement))
+            {
+                OCStackResult res = createStringLL(numElement, handle, OCGetResourceInterfaceName, &itf);
+                if (res != OC_STACK_OK || !itf)
+                {
+                    va_end(arguments);
+                    goto no_memory;
+                }
+            }
+
+            mt = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!mt)
             {
-                OCRDLinksPayloadCreate(uri, rt, itf, &linksPayload);
+                va_end(arguments);
+                goto no_memory;
             }
+            mt->value = OICStrdup("application/json");
+            if (!mt->value)
+            {
+                va_end(arguments);
+                goto no_memory;
+            }
+
+            if (!linksPayload)
+            {
+                linksPayload = OCCopyLinksResources(uri, rt, itf, NULL, 0, NULL,
+                        NULL, j, mt);;
+                if (!linksPayload)
+                {
+                    goto no_memory;
+                }
+            }
+            else
+            {
+                OCLinksPayload *temp = linksPayload;
+                while (temp->next)
+                {
+                    temp = temp->next;
+                }
+                temp->next = OCCopyLinksResources(uri, rt, itf, NULL, 0, NULL,
+                        NULL, j, mt);
+                if (!temp->next)
+                {
+                    goto no_memory;
+                }
+            }
+            OCFreeOCStringLL(rt);
+            OCFreeOCStringLL(itf);
+            OCFreeOCStringLL(mt);
         }
     }
     va_end(arguments);
 
-    OCRDPayload *rdPayload = OCRDPayloadCreate(RD_PAYLOAD_TYPE_PUBLISH);
-    if (!rdPayload)
-    {
-        OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
-        return OC_STACK_NO_MEMORY;
-    }
-    rdPayload->rdPublish = OCRDPublishPayloadCreate(OC_RD_PUBLISH_TTL, linksPayload);
+    rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
     if (!rdPayload->rdPublish)
     {
-        OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
-        return OC_STACK_NO_MEMORY;
+        goto no_memory;
     }
 
     OCDevAddr rdAddr = { 0 };
     OICStrcpy(rdAddr.addr, MAX_ADDR_STR_SIZE, addr);
     rdAddr.port = port;
 
-    OCRDPayloadLog(DEBUG, TAG, rdPayload);
+    OC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
 
     return sendRequest(OC_REST_POST, targetUri, &rdAddr, (OCPayload *)rdPayload, cbData);
+
+no_memory:
+    OC_LOG(ERROR, TAG, "Failed allocating memory.");
+    OCFreeOCStringLL(rt);
+    OCFreeOCStringLL(itf);
+    OCFreeOCStringLL(mt);
+    OCFreeTagsResource(tagsPayload);
+    OCFreeLinksResource(linksPayload);
+    OCRDPayloadDestroy(rdPayload);
+    return OC_STACK_NO_MEMORY;
 }
diff --git a/service/resource-directory/src/rd_payload.c b/service/resource-directory/src/rd_payload.c
deleted file mode 100644 (file)
index cb0b629..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-//******************************************************************
-//
-// Copyright 2015 Samsung Electronics All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include "rd_payload.h"
-
-#include "oic_malloc.h"
-#include "oic_string.h"
-
-#include "octypes.h"
-#include "ocstack.h"
-
-#define TAG PCF("OCRDPayload")
-
-#define CBOR_ROOT_ARRAY_LENGTH 1
-#define CBOR_LINK_ARRAY_LENGTH 3
-
-static void linksPayloadDestroy(OCRDLinksPayload *linkPayload)
-{
-    OCRDLinksPayload *links = linkPayload;
-
-    while (links)
-    {
-        OICFree(links->href);
-        OICFree(links->rt);
-        OICFree(links->itf);
-        OCRDLinksPayload *tmp = links;
-        links = links->next;
-        OICFree(tmp);
-    }
-}
-
-OCStackResult OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size)
-{
-    if (!outPayload || !size)
-    {
-        OC_LOG_V(ERROR, TAG, "Invalid parameters.");
-        return OC_STACK_ERROR;
-    }
-
-    CborEncoder encoder;
-    int flags = 0;
-    cbor_encoder_init(&encoder, outPayload, *size, flags);
-
-    CborEncoder rootArray;
-    CborError cborEncoderResult;
-    cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, CBOR_ROOT_ARRAY_LENGTH);
-    if (CborNoError != cborEncoderResult)
-    {
-        OC_LOG_V(ERROR, TAG, "Failed creating cbor array.");
-        goto exit;
-    }
-
-    CborEncoder map;
-    cborEncoderResult = cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
-    if (CborNoError != cborEncoderResult)
-    {
-        OC_LOG_V(ERROR, TAG, "Failed creating cbor map.");
-        goto exit;
-    }
-
-    cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_CONTENT_TYPE,
-        sizeof(OC_RSRVD_CONTENT_TYPE) - 1);
-    if (CborNoError != cborEncoderResult)
-    {
-        OC_LOG_V(ERROR, TAG, "Failed setting content type.");
-        goto exit;
-    }
-
-    cborEncoderResult = cbor_encode_uint(&map, rdPayload->payloadType);
-    if (CborNoError != cborEncoderResult)
-    {
-        OC_LOG_V(ERROR, TAG, "Failed setting rdPayload->payloadType.");
-        goto exit;
-    }
-
-    if (rdPayload->payloadType == RD_PAYLOAD_TYPE_DISCOVERY)
-    {
-        if (rdPayload->rdDiscovery && rdPayload->rdDiscovery->sel)
-        {
-            cborEncoderResult = cbor_encode_text_string(&map,
-                OC_RSRVD_RD_DISCOVERY_SEL, sizeof(OC_RSRVD_RD_DISCOVERY_SEL) -1);
-            if (CborNoError != cborEncoderResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed setting discovery sel type.");
-                goto exit;
-            }
-            cborEncoderResult = cbor_encode_uint(&map, rdPayload->rdDiscovery->sel);
-            if (CborNoError != cborEncoderResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed setting discovery sel value.");
-                goto exit;
-            }
-        }
-        else
-        {
-            OC_LOG_V(ERROR, TAG, "Missing sel parameter in the discovery payload.");
-            goto exit;
-        }
-    }
-    else if (rdPayload->payloadType == RD_PAYLOAD_TYPE_PUBLISH)
-    {
-        cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_TTL, sizeof(OC_RSRVD_TTL) - 1);
-        if (CborNoError != cborEncoderResult)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed setting publish ttl type.");
-            goto exit;
-        }
-
-        cborEncoderResult = cbor_encode_uint(&map, rdPayload->rdPublish->ttl);
-        if (CborNoError != cborEncoderResult)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed setting publish ttl value.");
-            goto exit;
-        }
-
-        CborEncoder linksArray;
-        cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) - 1);
-        if (CborNoError != cborEncoderResult)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed setting publish links type.");
-            goto exit;
-        }
-
-        cborEncoderResult = cbor_encoder_create_array(&map, &linksArray, CborIndefiniteLength);
-        if (CborNoError != cborEncoderResult)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed setting publish links array.");
-            goto exit;
-        }
-
-        {
-            OCRDLinksPayload *rtPtr = rdPayload->rdPublish->links;
-            while(rtPtr)
-            {
-                CborEncoder linksMap;
-                cborEncoderResult = cbor_encoder_create_map(&linksArray, &linksMap, CBOR_LINK_ARRAY_LENGTH);
-                if (CborNoError != cborEncoderResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed setting publish map.");
-                    goto exit;
-                }
-
-                cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_HREF,
-                        sizeof(OC_RSRVD_HREF) - 1);
-                if (CborNoError != cborEncoderResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed setting publish href type.");
-                    goto exit;
-                }
-
-                cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->href,
-                        strlen(rtPtr->href));
-                if (CborNoError != cborEncoderResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed setting publish href value.");
-                    goto exit;
-                }
-
-                cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_INTERFACE,
-                        sizeof(OC_RSRVD_INTERFACE) - 1);
-                if (CborNoError != cborEncoderResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed setting publish itf type.");
-                    goto exit;
-                }
-
-                cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->itf,
-                        strlen(rtPtr->itf));
-                if (CborNoError != cborEncoderResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed setting publish itf value.");
-                    goto exit;
-                }
-
-                cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_RESOURCE_TYPE,
-                        sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
-                if (CborNoError != cborEncoderResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed setting publish rt type.");
-                    goto exit;
-                }
-
-                cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->rt,
-                        strlen(rtPtr->rt));
-                if (CborNoError != cborEncoderResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed setting publish rt value.");
-                    goto exit;
-                }
-
-                cborEncoderResult = cbor_encoder_close_container(&linksArray, &linksMap);
-                if (CborNoError != cborEncoderResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed closing linksMap publish map.");
-                    goto exit;
-                }
-
-                rtPtr = rtPtr->next;
-            }
-        }
-        cborEncoderResult = cbor_encoder_close_container(&map, &linksArray);
-        if (CborNoError != cborEncoderResult)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed closing linksArray container.");
-            goto exit;
-        }
-    }
-
-    cborEncoderResult = cbor_encoder_close_container(&rootArray, &map);
-    if (CborNoError != cborEncoderResult)
-    {
-        OC_LOG_V(ERROR, TAG, "Failed closing map container.");
-        goto exit;
-    }
-
-    cborEncoderResult = cbor_encoder_close_container(&encoder, &rootArray);
-    if (CborNoError != cborEncoderResult)
-    {
-        OC_LOG_V(ERROR, TAG, "Failed closing encoder container.");
-        goto exit;
-    }
-
-    *size = encoder.ptr - outPayload;
-    return OC_STACK_OK;
-
-exit:
-    OICFree(outPayload);
-    return OC_STACK_ERROR;
-}
-
-OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload)
-{
-    CborValue *rdCBORPayload = (CborValue *)cborPayload;
-    OCRDPayload *rdPayload = NULL;
-
-    if (!cbor_value_is_map(rdCBORPayload))
-    {
-        OC_LOG_V(ERROR, TAG, "RD CBOR Payload is not in map format.");
-        return OC_STACK_ERROR;
-    }
-    else
-    {
-        CborValue curVal;
-        CborError cborFindResult;
-        cborFindResult = cbor_value_map_find_value(rdCBORPayload,
-            OC_RSRVD_CONTENT_TYPE, &curVal);
-        if (CborNoError != cborFindResult)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_CONTENT_TYPE type in the payload.");
-            goto exit;
-        }
-
-        int payloadType = 0 ;
-        if (cbor_value_is_valid(&curVal))
-        {
-            cborFindResult = cbor_value_get_int(&curVal, &payloadType);
-            if (CborNoError != cborFindResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_CONTENT_TYPE value in the payload.");
-                goto exit;
-            }
-        }
-
-        rdPayload = OCRDPayloadCreate(payloadType);
-        if (!rdPayload)
-        {
-            goto no_memory;
-        }
-
-        if (RD_PAYLOAD_TYPE_DISCOVERY == payloadType)
-        {
-            cborFindResult = cbor_value_map_find_value(rdCBORPayload,
-                OC_RSRVD_RD_DISCOVERY_SEL, &curVal);
-            if (CborNoError != cborFindResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL type in the payload.");
-                goto exit;
-            }
-
-            int biasFactor = 0;
-            if (cbor_value_is_valid(&curVal))
-            {
-                cborFindResult = cbor_value_get_int(&curVal, &biasFactor);
-                if (CborNoError != cborFindResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL value in the payload.");
-                    goto exit;
-                }
-            }
-
-            rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(biasFactor);
-            if (!rdPayload->rdDiscovery)
-            {
-                goto no_memory;
-            }
-        }
-        else if (RD_PAYLOAD_TYPE_PUBLISH == payloadType)
-        {    // TTL
-            int ttl = 0;
-            cborFindResult = cbor_value_map_find_value(rdCBORPayload, OC_RSRVD_TTL, &curVal);
-            if (CborNoError != cborFindResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_TTL type in the payload.");
-                goto exit;
-            }
-
-            cborFindResult = cbor_value_get_int(&curVal, &ttl);
-            if (CborNoError != cborFindResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_TTL value in the payload.");
-                goto exit;
-            }
-
-            // Link Array
-            CborValue linkArray;
-            cborFindResult = cbor_value_map_find_value(rdCBORPayload, OC_RSRVD_LINKS, &linkArray);
-            if (CborNoError != cborFindResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_LINKS type in the payload.");
-                goto exit;
-            }
-
-            CborValue linkVal;
-            cborFindResult = cbor_value_enter_container(&linkArray, &linkVal);
-            if (CborNoError != cborFindResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed entering linkArray container in the payload.");
-                goto exit;
-            }
-
-            OCRDLinksPayload *links = NULL;
-            while(cbor_value_is_map(&linkVal))
-            {
-                char *href = NULL;
-                char *itf = NULL;
-                char *rt = NULL;
-                size_t len;
-
-                cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_HREF, &curVal);
-                if (CborNoError != cborFindResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_HREF type in the payload.");
-                    goto exit;
-                }
-
-                cborFindResult = cbor_value_dup_text_string(&curVal, &href, &len, NULL);
-                if (CborNoError != cborFindResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_HREF value in the payload.");
-                    goto exit;
-                }
-
-                cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_INTERFACE, &curVal);
-                if (CborNoError != cborFindResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_INTERFACE type in the payload.");
-                    goto exit;
-                }
-
-                cborFindResult = cbor_value_dup_text_string(&curVal, &itf, &len, NULL);
-                if (CborNoError != cborFindResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_INTERFACE value in the payload.");
-                    goto exit;
-                }
-
-                cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
-                if (CborNoError != cborFindResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_RESOURCE_TYPE type in the payload.");
-                    goto exit;
-                }
-
-                cborFindResult = cbor_value_dup_text_string(&curVal, &rt, &len, NULL);
-                if (CborNoError != cborFindResult)
-                {
-                    OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_RESOURCE_TYPE value in the payload.");
-                    goto exit;
-                }
-
-                OCRDLinksPayloadCreate(href, rt, itf, &links);
-                if (!links)
-                {
-                    goto no_memory;
-                }
-
-                cborFindResult = cbor_value_advance(&linkVal);
-                if (CborNoError != cborFindResult)
-                {
-                        OC_LOG_V(ERROR, TAG, "Failed advancing the linkVal payload.");
-                        goto exit;
-                }
-            }
-            cborFindResult = cbor_value_advance(&linkArray);
-            if (CborNoError != cborFindResult)
-            {
-                OC_LOG_V(ERROR, TAG, "Failed advancing the linkArray payload.");
-                goto exit;
-            }
-            rdPayload->rdPublish = OCRDPublishPayloadCreate(ttl, links);
-            if (!rdPayload->rdPublish)
-            {
-                goto no_memory;
-            }
-        }
-
-        OCRDPayloadLog(DEBUG, TAG, rdPayload);
-        cborFindResult = cbor_value_advance(rdCBORPayload);
-        if (CborNoError != cborFindResult)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed advancing the payload.");
-            goto exit;
-        }
-        *outPayload = (OCPayload *)rdPayload;
-    }
-    return OC_STACK_OK;
-no_memory:
-    OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
-    OCRDPayloadDestroy(rdPayload);
-    return OC_STACK_NO_MEMORY;
-
-exit:
-    OCRDPayloadDestroy(rdPayload);
-    return OC_STACK_ERROR;
-}
-
-OCRDPayload *OCRDPayloadCreate(OCRDPayloadType payloadType)
-{
-    OCRDPayload *rdPayload = (OCRDPayload *)OICCalloc(1, sizeof(OCRDPayload));
-
-    if (!rdPayload)
-    {
-        return NULL;
-    }
-
-    rdPayload->base.type = PAYLOAD_TYPE_RD;
-    rdPayload->payloadType = payloadType;
-
-    return rdPayload;
-}
-
-void OCRDLinksPayloadCreate(const char *uri, const char *rt, const char *itf,
-        OCRDLinksPayload **linksPayload)
-{
-    OCRDLinksPayload *payload = OICCalloc(1, sizeof(OCRDLinksPayload));
-    if (!payload)
-    {
-        goto no_memory;
-    }
-
-    payload->href = OICStrdup(uri);
-    if (!payload->href)
-    {
-        goto no_memory;
-    }
-
-    payload->rt = OICStrdup(rt);
-    if (!payload->rt)
-    {
-        goto no_memory;
-    }
-
-    payload->itf = OICStrdup(itf);
-    if (!payload->itf)
-    {
-        goto no_memory;
-    }
-
-    payload->next = NULL;
-
-    if (*linksPayload == NULL)
-    {
-        *linksPayload = payload;
-    }
-    else
-    {
-        OCRDLinksPayload *temp = *linksPayload;
-        while (temp->next)
-        {
-            temp = temp->next;
-        }
-        temp->next = payload;
-    }
-    return;
-
-no_memory:
-    OC_LOG_V(ERROR, TAG, "Memory allocation failed.");
-    linksPayloadDestroy(payload);
-}
-
-OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(int biasFactor)
-{
-    OCRDDiscoveryPayload *discoveryPayload = OICCalloc(1, sizeof(OCRDDiscoveryPayload));
-
-    if (!discoveryPayload)
-    {
-        return NULL;
-    }
-    discoveryPayload->sel = biasFactor;
-
-    return discoveryPayload;
-}
-
-
-OCRDPublishPayload* OCRDPublishPayloadCreate(int ttl,
-        OCRDLinksPayload *linksPayload)
-{
-    OCRDPublishPayload *rdPublish = OICCalloc(1, sizeof(OCRDPublishPayload));
-    if (!rdPublish)
-    {
-        return NULL;
-    }
-
-    //TODO: Find way of device device id.
-    // rdPayload->rdPublish->id = (uint8_t *)OICCalloc(1, UUID_SIZE);
-    // memcpy(rdPayload->rdPublish->id, , UUID_SIZE);
-    //TODO: Find way of device device name.
-    // rdPayload->rdPublish->n = (char*)OICCalloc(1, strlen(name));
-    // memcpy(rdPayload->rdPublish->n, , strlen(name));
-    rdPublish->ttl = ttl; // TODO Expose API to allow user to set this value.
-    rdPublish->links = linksPayload;
-
-    return rdPublish;
-}
-
-void OCRDPayloadDestroy(OCRDPayload *payload)
-{
-    if (!payload)
-    {
-        return;
-    }
-
-    if (payload->rdDiscovery)
-    {
-        OICFree(payload->rdDiscovery);
-    }
-
-    if (payload->rdPublish)
-    {
-        if (payload->rdPublish->links)
-        {
-            linksPayloadDestroy(payload->rdPublish->links);
-        }
-
-        if (payload->rdPublish->deviceName.deviceName)
-        {
-            OICFree(payload->rdPublish->deviceName.deviceName);
-        }
-
-        OICFree(payload->rdPublish);
-    }
-
-    OICFree(payload);
-}
-
-void OCRDPayloadLog(LogLevel level, const char *tag, const OCRDPayload *payload)
-{
-    if (!payload)
-    {
-        return;
-    }
-
-    OC_LOG_V(level, tag, "BaseType : %d", payload->base.type);
-    OC_LOG_V(level, tag, "RD Payload Type : %d", payload->payloadType);
-
-    if (payload->rdDiscovery)
-    {
-        OC_LOG_V(level, tag, "RD Payload Discovery BIAS : %d", payload->rdDiscovery->sel);
-    }
-    OCRDPublishPayloadLog(level, tag, payload->rdPublish);
-}
-
-void OCRDPublishPayloadLog(LogLevel level, const char *tag, const OCRDPublishPayload *rdPublish)
-{
-    if (rdPublish)
-    {
-        if (rdPublish->deviceName.deviceName)
-        {
-            OC_LOG_V(level, tag, "RD Payload Pulish Name : %s", rdPublish->deviceName.deviceName);
-        }
-
-        if (rdPublish->deviceId.id)
-        {
-            OC_LOG_V(level, tag, "RD Payload Publish ID : %s",  rdPublish->deviceId.id);
-        }
-
-        OC_LOG_V(level, tag, "RD Payload Publish TTL : %d", rdPublish->ttl);
-
-        if (rdPublish->links)
-        {
-            for (OCRDLinksPayload *temp = rdPublish->links; temp; temp = temp->next)
-            {
-                OC_LOG_V(level, tag, "RD Payload Publish Link HREF : %s", temp->href);
-                OC_LOG_V(level, tag, "RD Payload Publish Link RT : %s", temp->rt);
-                OC_LOG_V(level, tag, "RD Payload Publish Link ITF : %s", temp->itf);
-            }
-        }
-    }
-}
index 2d320e8..4b67b97 100644 (file)
@@ -1,6 +1,6 @@
-// Copyright 2015 Samsung Electronics All Rights Reserved.
 //******************************************************************
 //
+// Copyright 2015 Samsung Electronics All Rights Reserved.
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 #include "rd_server.h"
 
-#include "rd_types.h"
-#include "rd_payload.h"
 #include "rd_storage.h"
 
-#include "logger.h"
+#include "rdpayload.h"
+#include "payload_logging.h"
 
 #define TAG  PCF("RDServer")
 
@@ -37,8 +36,6 @@ static OCStackResult sendResponse(const OCEntityHandlerRequest *ehRequest, OCRDP
     response.resourceHandle = ehRequest->resource;
     response.ehResult = OC_EH_OK;
     response.payload = (OCPayload*)(rdPayload);
-    response.payload->type = PAYLOAD_TYPE_RD;
-
     return OCDoResponse(&response);
 }
 
@@ -50,27 +47,27 @@ static OCEntityHandlerResult handleGetRequest(const OCEntityHandlerRequest *ehRe
 {
     if (!ehRequest)
     {
-        OC_LOG_V(DEBUG, TAG, "Invalid request pointer.");
+        OC_LOG(DEBUG, TAG, "Invalid request pointer.");
         return OC_EH_ERROR;
     }
 
     OCEntityHandlerResult ehResult = OC_EH_OK;
     OC_LOG_V(DEBUG, TAG, "Received OC_REST_GET from client with query: %s.", ehRequest->query);
 
-    OCRDPayload *rdPayload = OCRDPayloadCreate(RD_PAYLOAD_TYPE_DISCOVERY);
+    OCRDPayload *rdPayload = OCRDPayloadCreate();
     if (!rdPayload)
     {
         return OC_STACK_NO_MEMORY;
     }
 
-    rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(OC_RD_DISC_SEL);
+    rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(NULL, OCGetServerInstanceIDString(), OC_RD_DISC_SEL);
     if (!rdPayload->rdDiscovery)
     {
         OCRDPayloadDestroy(rdPayload);
         return OC_STACK_NO_MEMORY;
     }
 
-    OCRDPayloadLog(DEBUG, TAG, rdPayload);
+    OC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
 
     if (sendResponse(ehRequest, rdPayload) != OC_STACK_OK)
     {
@@ -78,8 +75,6 @@ static OCEntityHandlerResult handleGetRequest(const OCEntityHandlerRequest *ehRe
         ehResult = OC_EH_ERROR;
     }
 
-    OCRDPayloadDestroy(rdPayload);
-
     return ehResult;
 }
 
@@ -91,28 +86,28 @@ static OCEntityHandlerResult handlePublishRequest(const OCEntityHandlerRequest *
 {
     OCEntityHandlerResult ehResult = OC_EH_OK;
 
-    OC_LOG_V(DEBUG, TAG, "Received OC_REST_PUT from client with query: %s.", ehRequest->query);
-
     if (!ehRequest)
     {
-        OC_LOG_V(DEBUG, TAG, "Invalid request pointer");
+        OC_LOG(DEBUG, TAG, "Invalid request pointer");
         return OC_EH_ERROR;
     }
 
+    OC_LOG_V(DEBUG, TAG, "Received OC_REST_PUT from client with query: %s.", ehRequest->query);
+
     OCRDPayload *payload = (OCRDPayload *)ehRequest->payload;
-    if (payload->payloadType == RD_PAYLOAD_TYPE_PUBLISH)
+    if (payload && payload->rdPublish)
     {
         OCRDStorePublishedResources(payload->rdPublish);
     }
 
-    OCRDPayload *rdPayload = OCRDPayloadCreate(RD_PAYLOAD_TYPE_DISCOVERY);
+    OCRDPayload *rdPayload = OCRDPayloadCreate();
     if (!rdPayload)
     {
+        OC_LOG(ERROR, TAG, "Failed allocating memory.");
         return OC_STACK_NO_MEMORY;
     }
 
-    OCRDPayloadLog(DEBUG, TAG, rdPayload);
-    rdPayload->payloadType = RD_PAYLOAD_TYPE_RESPONSE;
+    OC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
 
     if (sendResponse(ehRequest, rdPayload) != OC_STACK_OK)
     {
@@ -128,7 +123,7 @@ static OCEntityHandlerResult handlePublishRequest(const OCEntityHandlerRequest *
  * will handle REST request (GET/PUT/POST/DEL) for them.
  */
 static OCEntityHandlerResult rdEntityHandler(OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *ehRequest, void *callbackParameter)
+        OCEntityHandlerRequest *ehRequest, __attribute__((unused)) void *callbackParameter)
 {
     OCEntityHandlerResult ehRet = OC_EH_ERROR;
 
@@ -139,7 +134,7 @@ static OCEntityHandlerResult rdEntityHandler(OCEntityHandlerFlag flag,
 
     if (flag & OC_REQUEST_FLAG)
     {
-        OC_LOG_V(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG.");
+        OC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG.");
         switch (ehRequest->method)
         {
             case OC_REST_GET:
@@ -164,31 +159,27 @@ static OCEntityHandlerResult rdEntityHandler(OCEntityHandlerFlag flag,
 }
 
 /**
- * Starts resource directory server and registers RD resource
+ * Registers RD resource
  */
 OCStackResult OCRDStart()
 {
-    OCStackResult result = OCInit(NULL, 0, OC_CLIENT_SERVER);
     OCResourceHandle rdHandle = NULL;
 
+    OCStackResult result = OCCreateResource(&rdHandle,
+                                OC_RSRVD_RESOURCE_TYPE_RD,
+                                OC_RSRVD_INTERFACE_DEFAULT,
+                                OC_RSRVD_RD_URI,
+                                rdEntityHandler,
+                                NULL,
+                                (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE));
+
     if (result == OC_STACK_OK)
     {
-        result = OCCreateResource(&rdHandle,
-                                  OC_RSRVD_RESOURCE_TYPE_RD,
-                                  OC_RSRVD_INTERFACE_DEFAULT,
-                                  OC_RSRVD_RD_URI,
-                                  rdEntityHandler,
-                                  NULL,
-                                  (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE));
-
-        if (result == OC_STACK_OK)
-        {
-            OC_LOG_V(DEBUG, TAG, "Resource Directory Started.");
-        }
-        else
-        {
-            OC_LOG(ERROR, TAG, "Failed starting Resource Directory.");
-        }
+        OC_LOG(DEBUG, TAG, "Resource Directory Started.");
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, "Failed starting Resource Directory.");
     }
 
     return result;
@@ -203,7 +194,7 @@ OCStackResult OCRDStop()
 
     if (result == OC_STACK_OK)
     {
-        OC_LOG_V(DEBUG, TAG, "Resource Directory Stopped.");
+        OC_LOG(DEBUG, TAG, "Resource Directory Stopped.");
     }
     else
     {