RD client features in base layer
authorhyuna0213.jo <hyuna0213.jo@samsung.com>
Wed, 20 Jul 2016 22:56:24 +0000 (07:56 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Tue, 26 Jul 2016 03:46:26 +0000 (03:46 +0000)
- make consistency with the revised RD spec.
- modified build command with RD_MODE=CLIENT or SERVER
- add the RD client API in base layer.
  1. publish resource to resource-directory
  2. delete resource from resource-directory
- remove the build script related current RD implementation
  in service layer. after RD server features is implemented
  in base layer, it will be removed totally.

Change-Id: I992ff34b839cc845c5e44eb1198906bdcc0e2ec0
Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/8983
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Habib Virji <habib.virji@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
32 files changed:
build_common/SConscript
resource/csdk/SConscript
resource/csdk/connectivity/test/SConscript
resource/csdk/stack/include/internal/ocresource.h
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/include/oicresourcedirectory.h [new file with mode: 0644]
resource/csdk/stack/include/payload_logging.h
resource/csdk/stack/include/rdpayload.h
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/oicresourcedirectory.c [new file with mode: 0644]
resource/csdk/stack/src/rdpayload.c
resource/csdk/stack/test/rdtests.cpp [new file with mode: 0644]
resource/examples/SConscript
resource/examples/rdclient.cpp [new file with mode: 0644]
resource/include/IServerWrapper.h
resource/include/InProcServerWrapper.h
resource/include/OCApi.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OCRepresentation.h
resource/include/StringConstants.h
resource/src/InProcServerWrapper.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp
resource/src/OCRepresentation.cpp
resource/src/SConscript
service/SConscript

index 9756ca0..ca26680 100644 (file)
@@ -87,8 +87,8 @@ help_vars.Add(EnumVariable('TARGET_OS', 'Target platform', host, host_target_map
 help_vars.Add(BoolVariable('WITH_RA', 'Build with Remote Access module', False))
 help_vars.Add(BoolVariable('WITH_TCP', 'Build with TCP adapter', False))
 help_vars.Add(ListVariable('WITH_MQ', 'Build with MQ publisher/broker', 'OFF', ['OFF', 'SUB', 'PUB', 'BROKER']))
-help_vars.Add(EnumVariable('WITH_RD', 'Build including Resource Directory', '0', allowed_values=('0', '1')))
 help_vars.Add(BoolVariable('WITH_CLOUD', 'Build including Cloud Connector and Cloud Client sample', False))
+help_vars.Add(ListVariable('RD_MODE', 'Resource Directory build mode', 'CLIENT', ['CLIENT', 'SERVER']))
 
 help_vars.Add(BoolVariable('SIMULATOR', 'Build with simulator module', False))
 
index 9b31045..d3459d3 100644 (file)
@@ -29,6 +29,7 @@ SConscript('#resource/third_party_libs.scons', 'lib_env')
 liboctbstack_env = lib_env.Clone()
 
 target_os = env.get('TARGET_OS')
+rd_mode = env.get('RD_MODE')
 with_ra = env.get('WITH_RA')
 with_ra_ibb = env.get('WITH_RA_IBB')
 with_tcp = env.get('WITH_TCP')
@@ -121,12 +122,6 @@ if env.get('LOGGING'):
 if env.get('DTLS_WITH_X509') == '1':
        liboctbstack_env.AppendUnique(CPPDEFINES = ['__WITH_X509__'])
 
-if env.get('WITH_RD') == '1':
-       liboctbstack_env.PrependUnique(CPPPATH = ['../../service/resource-directory/include'])
-       liboctbstack_env.PrependUnique(LIBPATH = [env.get('BUILD_DIR') + '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']:
@@ -148,10 +143,17 @@ liboctbstack_src = [
        OCTBSTACK_SRC + 'ocobserve.c',
        OCTBSTACK_SRC + 'ocserverrequest.c',
        OCTBSTACK_SRC + 'occollection.c',
-       OCTBSTACK_SRC + 'oicgroup.c',
-       OCTBSTACK_SRC + "rdpayload.c"
+       OCTBSTACK_SRC + 'oicgroup.c'
        ]
 
+if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
+       liboctbstack_src.append(OCTBSTACK_SRC + 'rdpayload.c')
+       liboctbstack_src.append(OCTBSTACK_SRC + 'oicresourcedirectory.c')
+       if 'CLIENT' in rd_mode:
+               liboctbstack_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
+       if 'SERVER' in rd_mode:
+               liboctbstack_env.AppendUnique(CPPDEFINES = ['RD_SERVER'])
+
 if with_tcp == True:
        liboctbstack_src.append(OCTBSTACK_SRC + 'oickeepalive.c')
 
index 2b6a0d3..71dbdda 100644 (file)
@@ -50,9 +50,6 @@ if catest_env.get('SECURED') == '1':
        catest_env.AppendUnique(LIBS = ['tinydtls'])
        catest_env.AppendUnique(LIBS = ['timer'])
 
-if catest_env.get('WITH_RD') == '1':
-       catest_env.PrependUnique(LIBS = ['resource_directory'])
-
 if catest_env.get('LOGGING'):
        catest_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
index 2113320..2740942 100755 (executable)
@@ -240,6 +240,17 @@ typedef struct OCResource {
 
     /** Pointer of ActionSet which to support group action.*/
     OCActionSet *actionsetHead;
+
+    /** 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;
+    };
 } OCResource;
 
 
index 72325a2..ea7daf8 100644 (file)
@@ -558,6 +558,37 @@ OC_EXPORT const OCDPDev_t* OCGetDirectPairedDevices();
  */
 OC_EXPORT OCStackResult OCDoDirectPairing(void *ctx, OCDPDev_t* peer, OCPrm_t pmSel, char *pinNumber,
                                                      OCDirectPairingCB resultCallback);
+
+#if defined(RD_CLIENT) || defined(RD_SERVER)
+/**
+ * This function binds an resource unique id to the resource.
+ *
+ * @param handle            Handle to the resource that the contained resource is to be bound.
+ * @param ins               Unique ID for resource.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OC_EXPORT OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, uint8_t ins);
+
+/**
+ * This function gets the resource unique id for a resource.
+ *
+ * @param handle            Handle of resource.
+ * @param ins               Unique ID for resource.
+ *
+ * @return Ins if resource found or 0 resource not found.
+ */
+OC_EXPORT OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins);
+
+/**
+ * This function gets a resource handle by resource uri.
+ *
+ * @param uri   Uri of Resource to get Resource handle.
+ *
+ * @return Found  resource handle or NULL if not found.
+ */
+OC_EXPORT OCResourceHandle OCGetResourceHandleAtUri(const char *uri);
+#endif
 //#endif // DIRECT_PAIRING
 
 #ifdef __cplusplus
index a78118b..6cc3335 100644 (file)
@@ -168,6 +168,9 @@ extern "C" {
 /** To represent interface.*/
 #define OC_RSRVD_INTERFACE              "if"
 
+/** To indicate how long RD should publish this item.*/
+#define OC_RSRVD_DEVICE_TTL             "lt"
+
 /** To represent time to live.*/
 #define OC_RSRVD_TTL                    "ttl"
 
@@ -314,7 +317,7 @@ extern "C" {
 #define MAC_ADDR_BLOCKS (6)
 
 /** Max identity size. */
-#define MAX_IDENTITY_SIZE (32)
+#define MAX_IDENTITY_SIZE (37)
 
 /** Universal unique identity size. */
 #define UUID_IDENTITY_SIZE (128/8)
@@ -349,10 +352,10 @@ extern "C" {
 #define OC_RSRVD_TITLE                   "title"
 
 /** Defines URI. */
-#define OC_RSRVD_URI                     "uri"
+#define OC_RSRVD_URI                     "anchor"
 
 /** Defines media type. */
-#define OC_RSRVD_MEDIA_TYPE              "mt"
+#define OC_RSRVD_MEDIA_TYPE              "type"
 
 /** To represent resource type with Publish RD.*/
 #define OC_RSRVD_RESOURCE_TYPE_RDPUBLISH "oic.wk.rdpub"
@@ -1193,20 +1196,20 @@ typedef struct OCLinksPayload
 {
     /** This is the target relative URI. */
     char *href;
+    /** The relation of the target URI referenced by the link to the context URI;
+     * The default value is null. */
+    char *rel;
     /** 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;
+    /** Bitmap - The bitmap holds observable, discoverable, secure option flag. */
+    uint8_t p;
     /** 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;
+    char *anchor;
     /** The instance identifier for this web link in an array of web links - used in links. */
     union
     {
@@ -1217,8 +1220,10 @@ typedef struct OCLinksPayload
         /** Use UUID for universal uniqueness - used in /oic/res to identify the device. */
         OCIdentity uniqueUUID;
     };
+    /** Time to keep holding resource.*/
+    uint64_t ttl;
     /** A hint of the media type of the representation of the resource referenced by the target URI. */
-    OCStringLL *mt;
+    OCStringLL *type;
     /** Holding address of the next resource. */
     struct OCLinksPayload *next;
 } OCLinksPayload;
@@ -1230,30 +1235,8 @@ typedef struct
     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;
+    uint64_t ttl;
 } OCTagsPayload;
 
 /** Resource collection payload. */
@@ -1263,8 +1246,6 @@ typedef struct OCResourceCollectionPayload
     OCTagsPayload *tags;
     /** Array of links payload. */
     OCLinksPayload *setLinks;
-    /** Holding address of the next resource. */
-    struct OCResourceCollectionPayload *next;
 } OCResourceCollectionPayload;
 
 typedef struct OCDiscoveryPayload
diff --git a/resource/csdk/stack/include/oicresourcedirectory.h b/resource/csdk/stack/include/oicresourcedirectory.h
new file mode 100644 (file)
index 0000000..e6aa56c
--- /dev/null
@@ -0,0 +1,72 @@
+//******************************************************************
+//
+// Copyright 2016 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 OC_RESOURCE_DIRECTORY_H_
+#define OC_RESOURCE_DIRECTORY_H_
+
+#include "octypes.h"
+#include "logger.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#ifdef RD_CLIENT
+/**
+ * Publish RD resource to Resource Directory.
+ *
+ * @param host The address of the RD.
+ * @param connectivityType Type of connectivity indicating the interface.
+ * @param resourceHandles This is the resource handle which we need to register to RD.
+ * @param nHandles The counts of resource handle.
+ * @param cbData Asynchronous callback function that is invoked by the stack when
+ *               response is received. The callback is generated for each response
+ *               received.
+ * @param qos Quality of service.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OC_EXPORT OCStackResult OCRDPublish(const char *host, OCConnectivityType connectivityType,
+                                    OCResourceHandle resourceHandles[], uint8_t nHandles,
+                                    OCCallbackData *cbData, OCQualityOfService qos);
+
+/**
+ * Delete RD resource from Resource Directory.
+ *
+ * @param host The address of the RD.
+ * @param connectivityType Type of connectivity indicating the interface.
+ * @param resourceHandles This is the resource handle which we need to delete to RD.
+ * @param nHandles The counts of resource handle.
+ * @param cbData Asynchronous callback function that is invoked by the stack when
+ *               response is received. The callback is generated for each response
+ *               received.
+ * @param qos Quality of service.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OC_EXPORT OCStackResult OCRDDelete(const char *host, OCConnectivityType connectivityType,
+                                   OCResourceHandle resourceHandles[], uint8_t nHandles,
+                                   OCCallbackData *cbData, OCQualityOfService qos);
+#endif
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif /* OC_RESOURCE_DIRECTORY_H_ */
index 0939955..44371c7 100644 (file)
@@ -49,6 +49,93 @@ extern "C"
 OC_EXPORT const char *convertTriggerEnumToString(OCPresenceTrigger trigger);
 OC_EXPORT OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr);
 
+#if defined(RD_CLIENT) || defined(RD_SERVER)
+INLINE_API void OCTagsLog(const LogLevel level, const OCTagsPayload *tags)
+{
+    if (tags)
+    {
+        if (tags->n.deviceName)
+        {
+            OIC_LOG_V(level, PL_TAG, " Device Name : %s ", tags->n.deviceName);
+        }
+        if (tags->di.id)
+        {
+            OIC_LOG_V(level, PL_TAG, " Device ID : %s ", tags->di.id);
+        }
+        OIC_LOG_V(level, PL_TAG, " lt : %lld ",tags->ttl);
+    }
+    else
+    {
+        (void) level;
+    }
+}
+
+INLINE_API void OCLinksLog(const LogLevel level, const OCLinksPayload *links)
+{
+    if (!links)
+    {
+        return;
+    }
+
+    while (links)
+    {
+        if (links->href)
+        {
+            OIC_LOG_V(level, PL_TAG, "   href: %s ",links->href);
+        }
+        OIC_LOG(level, PL_TAG, "   RT: ");
+        OCStringLL *rt = links->rt;
+        while (rt)
+        {
+            if (rt->value)
+            {
+                OIC_LOG_V(level, PL_TAG, "   %s", rt->value);
+            }
+            rt = rt->next;
+        }
+        OIC_LOG(level, PL_TAG, "   IF: ");
+        OCStringLL *itf = links->itf;
+        while (itf)
+        {
+            if (itf->value)
+            {
+                OIC_LOG_V(level, PL_TAG, "   %s", itf->value);
+            }
+            itf = itf->next;
+        }
+        OIC_LOG(level, PL_TAG, "   MT: ");
+        OCStringLL *mt = links->type;
+        while (mt)
+        {
+            if (mt->value)
+            {
+                OIC_LOG_V(level, PL_TAG, "   %s", mt->value);
+            }
+            mt = mt->next;
+        }
+        if (links->type)
+        {
+            OIC_LOG_V(level, PL_TAG, "   %s", links->type);
+        }
+        OIC_LOG_V(level, PL_TAG, "   INS: %d", links->ins);
+        OIC_LOG_V(level, PL_TAG, "   TTL: %d", links->ttl);
+        OIC_LOG_V(level, PL_TAG, "   P: %d", links->p);
+        if (links->rel)
+        {
+            OIC_LOG_V(level, PL_TAG, "   REL: %s", links->rel);
+        }
+        if (links->title)
+        {
+            OIC_LOG_V(level, PL_TAG, "   TITLE: %s", links->title);
+        }
+        if (links->anchor)
+        {
+            OIC_LOG_V(level, PL_TAG, "   URI: %s", links->anchor);
+        }
+        links = links->next;
+    }
+}
+#endif
 INLINE_API void OCPayloadLogRep(LogLevel level, OCRepPayload* payload)
 {
     OIC_LOG(level, (PL_TAG), "Payload Type: Representation");
@@ -310,6 +397,7 @@ INLINE_API void OCPayloadLogSecurity(LogLevel level, OCSecurityPayload* payload)
     OIC_LOG_V(level, PL_TAG, "\tSecurity Data: %s", payload->securityData);
 }
 
+#if defined(RD_CLIENT) || defined(RD_SERVER)
 INLINE_API void OCRDPayloadLog(const LogLevel level, const OCRDPayload *payload)
 {
     if (!payload)
@@ -332,7 +420,7 @@ INLINE_API void OCRDPayloadLog(const LogLevel level, const OCRDPayload *payload)
         OCLinksLog(level, rdPublish->setLinks);
     }
 }
-
+#endif
 INLINE_API void OCPayloadLog(LogLevel level, OCPayload* payload)
 {
     if(!payload)
@@ -360,9 +448,11 @@ INLINE_API void OCPayloadLog(LogLevel level, OCPayload* payload)
         case PAYLOAD_TYPE_SECURITY:
             OCPayloadLogSecurity(level, (OCSecurityPayload*)payload);
             break;
+#if defined(RD_CLIENT) || defined(RD_SERVER)
         case PAYLOAD_TYPE_RD:
             OCRDPayloadLog(level, (OCRDPayload*)payload);
             break;
+#endif
         default:
             OIC_LOG_V(level, PL_TAG, "Unknown Payload Type: %d", payload->type);
             break;
index d75cd8e..2afa320 100644 (file)
 extern "C" {
 #endif // __cplusplus
 
+#define OIC_RD_PUBLISH_TTL 86400
+
+#define OIC_RD_DEFAULT_RESOURCE 2
+
+#define DEFAULT_MESSAGE_TYPE "application/json"
+
 /**
  * Converts RD payload from structure to CBOR format. It creates the outPayload
  * which is then transmitted over the wire.
@@ -65,6 +71,21 @@ OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPay
  */
 OCRDPayload *OCRDPayloadCreate();
 
+#ifdef RD_CLIENT
+/**
+ * Initializes RD Publish payload structure.
+ *
+ * @param resourceHandles The handle of registered resource.
+ * @param nHandles The number of registered resource handles.
+ * @param ttl Time to live of the published resource.
+ *
+ * @return Allocated memory for the OCRDPayload and NULL in case if
+ * failed to allocate memory.
+ */
+OCRDPayload *OCRDPublishPayloadCreate(OCResourceHandle resourceHandles[], uint8_t nHandles,
+                                      uint64_t ttl);
+#endif
+
 /**
  * Initializes RD Discovery payload structure and sets the bias factor.
  *
@@ -89,37 +110,33 @@ 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 id The device UUID.
  * @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);
+OCTagsPayload* OCCopyTagsResources(const char *deviceName, const unsigned char *id, uint64_t ttl);
 
 /**
  * Copies link resource to create LinksPayload.
  *
  * @param href URI of the resource
+ * @param rel Relation
  * @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 p Whether to observe or not.
  * @param title Title
- * @param uri URI
+ * @param anchor URI
  * @param ins Unique value per link.
+ * @param ttl Time to live for this link.
  * @param mt Media Type
 
- * @retun Allocated memory for OCLinksPayload or else NULL in case of error.
+ * @retun Allocated memory for OCLinksResource 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);
+OCLinksPayload* OCCopyLinksResources(const char *href, const char *rel, OCStringLL *rt,
+                                     OCStringLL *itf, uint8_t p, const char *title,
+                                     const char *anchor, uint8_t ins, uint64_t ttl,
+                                     OCStringLL *mt);
 
 /**
  * Creates a resource collection object.
@@ -159,22 +176,6 @@ void OCFreeCollectionResource(OCResourceCollectionPayload *payload);
  */
 void OCDiscoveryCollectionPayloadDestroy(OCDiscoveryPayload* payload);
 
-/**
- * Prints tags payload.
- *
- * @param level LogLevel for the print.
- * @param tags Structure of the tags payload.
- */
-OC_EXPORT void OCTagsLog(const LogLevel level, const OCTagsPayload *tags);
-
-/**
- * Prints links payload.
- *
- * @param level LogLevel for the print.
- * @param tags Structure of the links payload.
- */
-OC_EXPORT void OCLinksLog(const LogLevel level, const OCLinksPayload *links);
-
 #ifdef __cplusplus
 }
 #endif // __cplusplus
index 5c5a2e7..b308c0f 100644 (file)
@@ -64,9 +64,11 @@ void OCPayloadDestroy(OCPayload* payload)
         case PAYLOAD_TYPE_SECURITY:
             OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
             break;
+#if defined(RD_CLIENT) || defined(RD_SERVER)
         case PAYLOAD_TYPE_RD:
            OCRDPayloadDestroy((OCRDPayload*)payload);
            break;
+#endif
         default:
             OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
             OICFree(payload);
index e1edc0d..60c8807 100644 (file)
 #include "ocrandom.h"
 #include "ocresourcehandler.h"
 #include "cbor.h"
+
+#if defined(RD_CLIENT) || defined(RD_SERVER)
 #include "rdpayload.h"
+#endif
 
 #define TAG "OIC_RI_PAYLOADCONVERT"
 
@@ -155,8 +158,10 @@ 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);
+#if defined(RD_CLIENT) || defined(RD_SERVER)
         case PAYLOAD_TYPE_RD:
             return OCRDPayloadToCbor((OCRDPayload*)payload, outPayload, size);
+#endif
         default:
             OIC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
             return CborErrorUnknownType;
index c820490..6121839 100644 (file)
 #include "ocpayloadcbor.h"
 #include "ocstackinternal.h"
 #include "payload_logging.h"
-#include "rdpayload.h"
 #include "platform_features.h"
 
+#if defined(RD_CLIENT) || defined(RD_SERVER)
+#include "rdpayload.h"
+#endif
+
 #define TAG "OIC_RI_PAYLOADPARSE"
 
 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *arrayVal);
@@ -86,9 +89,11 @@ OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
         case PAYLOAD_TYPE_SECURITY:
             result = OCParseSecurityPayload(outPayload, payload, payloadSize);
             break;
+#if defined(RD_CLIENT) || defined(RD_SERVER)
         case PAYLOAD_TYPE_RD:
             result = OCRDCborToPayload(&rootValue, outPayload);
             break;
+#endif
         default:
             OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
             result = OC_STACK_INVALID_PARAM;
index 44a2135..4cd74f4 100755 (executable)
@@ -29,7 +29,7 @@
 #ifdef WITH_STRING_H
 #include <string.h>
 #endif
-#ifdef WITH_STRINGS_H
+#ifdef WITH_STRING_H
 #include <strings.h>
 #endif
 
 #include "secureresourcemanager.h"
 #include "cacommon.h"
 #include "cainterface.h"
-#include "rdpayload.h"
 #include "ocpayload.h"
 
-#ifdef WITH_RD
-#include "rd_server.h"
-#endif
-
 #ifdef ROUTING_GATEWAY
 #include "routingmanager.h"
 #endif
@@ -617,102 +612,6 @@ OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCRes
     return OCDoResponse(&response);
 }
 
-#ifdef WITH_RD
-static OCStackResult checkResourceExistsAtRD(const char *interfaceType, const char *resourceType,
-     OCResource **payload, OCDevAddr *devAddr)
-{
-    OCResourceCollectionPayload *repPayload;
-    if (!payload)
-    {
-        return OC_STACK_ERROR;
-    }
-    if (OCRDCheckPublishedResource(interfaceType, resourceType, &repPayload, devAddr) == OC_STACK_OK)
-    {
-        if (!repPayload)
-        {
-            return OC_STACK_ERROR;
-        }
-        OCResource *ptr = ((OCResource *) OICCalloc(1, sizeof(OCResource)));
-        if (!ptr)
-        {
-           return OC_STACK_NO_MEMORY;
-        }
-
-        ptr->uri = OICStrdup(repPayload->setLinks->href);
-        if (!ptr->uri)
-        {
-           return OC_STACK_NO_MEMORY;
-        }
-        OCStringLL *rt = repPayload->setLinks->rt;
-        while (rt)
-        {
-            OCResourceType *temp = (OCResourceType *) OICCalloc(1, sizeof(OCResourceType));
-            if(!temp)
-            {
-                OICFree(ptr->uri);
-                return OC_STACK_NO_MEMORY;
-            }
-            temp->next = NULL;
-            temp->resourcetypename = OICStrdup(rt->value);
-            if (!ptr->rsrcType)
-            {
-                ptr->rsrcType = temp;
-            }
-            else
-            {
-                OCResourceType *type = ptr->rsrcType;
-                while (type->next)
-                {
-                    type = type->next;
-                }
-                type->next = temp;
-            }
-            rt = rt->next;
-        }
-
-        OCStringLL *itf = repPayload->setLinks->itf;
-        while (itf)
-        {
-            OCResourceInterface *temp = (OCResourceInterface *) OICCalloc(1, sizeof(OCResourceInterface));
-            if (!temp)
-            {
-                OICFree(ptr->uri);
-
-                return OC_STACK_NO_MEMORY;
-            }
-            temp->next = NULL;
-            temp->name = OICStrdup(itf->value);
-            if (!ptr->rsrcInterface)
-            {
-                ptr->rsrcInterface = temp;
-            }
-            else
-            {
-                OCResourceInterface *type = ptr->rsrcInterface;
-                while (type->next)
-                {
-                    type = type->next;
-                }
-                type->next = temp;
-            }
-            itf = itf->next;
-        }
-
-        ptr->resourceProperties = (OCResourceProperty) repPayload->tags->bitmap;
-
-        OCFreeCollectionResource(repPayload);
-        *payload = ptr;
-        return OC_STACK_OK;
-    }
-    else
-    {
-        OIC_LOG_V(ERROR, TAG, "The resource type or interface type doe not exist \
-                             on the resource directory");
-    }
-    return OC_STACK_ERROR;
-}
-#endif
-
 static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
 {
     if (!request || !resource)
@@ -816,42 +715,6 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
                     bool foundResourceAtRD = false;
                     for (;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
                     {
-#ifdef WITH_RD
-                        if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
-                        {
-                            OCResource *resource1 = NULL;
-                            OCDevAddr devAddr;
-                            discoveryResult = checkResourceExistsAtRD(interfaceQuery,
-                                resourceTypeQuery, &resource1, &devAddr);
-                            if (discoveryResult != OC_STACK_OK)
-                            {
-                                 break;
-                            }
-                            discoveryResult = BuildVirtualResourceResponse(resource1,
-                                discPayload, &devAddr, true);
-                            if (payload)
-                            {
-                                discPayload->baseURI = OICStrdup(devAddr.addr);
-                            }
-                            OICFree(resource1->uri);
-                            for (OCResourceType *rsrcRt = resource1->rsrcType, *rsrcRtNext = NULL; rsrcRt; )
-                            {
-                                rsrcRtNext = rsrcRt->next;
-                                OICFree(rsrcRt->resourcetypename);
-                                OICFree(rsrcRt);
-                                rsrcRt = rsrcRtNext;
-                            }
-
-                            for (OCResourceInterface *rsrcPtr = resource1->rsrcInterface, *rsrcNext = NULL; rsrcPtr; )
-                            {
-                                rsrcNext = rsrcPtr->next;
-                                OICFree(rsrcPtr->name);
-                                OICFree(rsrcPtr);
-                                rsrcPtr = rsrcNext;
-                            }
-                            foundResourceAtRD = true;
-                        }
-#endif
                         if (!foundResourceAtRD && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
                         {
                             discoveryResult = BuildVirtualResourceResponse(resource,
index d3e8922..a0bf25e 100644 (file)
@@ -4766,3 +4766,61 @@ bool OCResultToSuccess(OCStackResult ocResult)
             return false;
     }
 }
+
+#if defined(RD_CLIENT) || defined(RD_SERVER)
+OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, uint8_t ins)
+{
+    VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
+
+    OCResource *resource = NULL;
+
+    resource = findResource((OCResource *) handle);
+    if (!resource)
+    {
+        OIC_LOG(ERROR, TAG, "Resource not found");
+        return OC_STACK_ERROR;
+    }
+
+    resource->ins = ins;
+
+    return OC_STACK_OK;
+}
+
+OCResourceHandle OCGetResourceHandleAtUri(const char *uri)
+{
+    if (!uri)
+    {
+        OIC_LOG(ERROR, TAG, "Resource uri is NULL");
+        return NULL;
+    }
+
+    OCResource *pointer = headResource;
+
+    while (pointer)
+    {
+        if (strncmp(uri, pointer->uri, MAX_URI_LENGTH) == 0)
+        {
+            OIC_LOG_V(DEBUG, TAG, "Found Resource %s", uri);
+            return pointer;
+        }
+        pointer = pointer->next;
+    }
+    return NULL;
+}
+
+OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins)
+{
+    OCResource *resource = NULL;
+
+    VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(ins, ERROR, OC_STACK_INVALID_PARAM);
+
+    resource = findResource((OCResource *) handle);
+    if (resource)
+    {
+        *ins = resource->ins;
+        return OC_STACK_OK;
+    }
+    return OC_STACK_ERROR;
+}
+#endif
diff --git a/resource/csdk/stack/src/oicresourcedirectory.c b/resource/csdk/stack/src/oicresourcedirectory.c
new file mode 100644 (file)
index 0000000..a0c72bf
--- /dev/null
@@ -0,0 +1,109 @@
+//******************************************************************
+//
+// Copyright 2016 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 "oicresourcedirectory.h"
+
+#include "rdpayload.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "octypes.h"
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "rdpayload.h"
+#include "ocresource.h"
+#include "payload_logging.h"
+
+#define TAG "OIC_RI_RESOURCE_DIRECTORY"
+
+#ifdef RD_CLIENT
+OCStackResult OCRDPublish(const char *host, OCConnectivityType connectivityType,
+                          OCResourceHandle resourceHandles[], uint8_t nHandles,
+                          OCCallbackData *cbData, OCQualityOfService qos)
+{
+    // Validate input parameters
+    if (!host || !cbData || !cbData->cb)
+    {
+        return OC_STACK_INVALID_CALLBACK;
+    }
+
+    OCResourceHandle *pubResHandle = resourceHandles;
+    uint8_t nPubResHandles = nHandles;
+
+    // if resource handles is null, "/oic/p" and "/oic/d" resource will be published to RD.
+    if (!pubResHandle && !nPubResHandles)
+    {
+        OCResourceHandle defaultResHandles[OIC_RD_DEFAULT_RESOURCE] = { 0 };
+
+        // get "/oic/d" resource handle from stack.
+        defaultResHandles[0] = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
+        // get "/oic/p" resource handle from stack.
+        defaultResHandles[1] = OCGetResourceHandleAtUri(OC_RSRVD_PLATFORM_URI);
+
+        pubResHandle = defaultResHandles;
+        nPubResHandles = OIC_RD_DEFAULT_RESOURCE;
+    }
+
+    char targetUri[MAX_URI_LENGTH] = { 0 };
+    snprintf(targetUri, MAX_URI_LENGTH, "%s%s?rt=%s", host,
+             OC_RSRVD_RD_URI, OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
+    OIC_LOG_V(DEBUG, TAG, "Target URI: %s", targetUri);
+
+    OCPayload *rdPayload = (OCPayload *) OCRDPublishPayloadCreate(pubResHandle, nPubResHandles,
+                                                                  OIC_RD_PUBLISH_TTL);
+    if (!rdPayload)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to create RD Payload");
+        return OC_STACK_NO_MEMORY;
+    }
+
+    OIC_LOG(DEBUG, TAG, "Create RD payload successfully");
+
+    return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload,
+                        connectivityType, qos, cbData, NULL, 0);
+}
+
+OCStackResult OCRDDelete(const char *host, OCConnectivityType connectivityType,
+                         OCResourceHandle resourceHandles[], uint8_t nHandles,
+                         OCCallbackData *cbData, OCQualityOfService qos)
+{
+    // Validate input parameters
+    if (!host || !cbData || !cbData->cb)
+    {
+        return OC_STACK_INVALID_CALLBACK;
+    }
+
+    const unsigned char *id = (const unsigned char *) OCGetServerInstanceIDString();
+
+    char targetUri[MAX_URI_LENGTH] = { 0 };
+    snprintf(targetUri, MAX_URI_LENGTH, "%s%s?di=%s", host, OC_RSRVD_RD_URI, id);
+
+    char queryParam[MAX_URI_LENGTH] = { 0 };
+    for (uint8_t j = 0; j < nHandles; j++)
+    {
+        OCResource *handle = (OCResource *) resourceHandles[j];
+        snprintf(queryParam, MAX_URI_LENGTH, "&ins=%d", handle->ins);
+    }
+
+    OICStrcatPartial(targetUri, sizeof(targetUri), queryParam, strlen(queryParam));
+    OIC_LOG_V(DEBUG, TAG, "Target URI: %s", targetUri);
+
+    return OCDoResource(NULL, OC_REST_DELETE, targetUri, NULL, NULL, connectivityType,
+                        qos, cbData, NULL, 0);
+}
+#endif
index de38153..3cffbce 100644 (file)
@@ -31,7 +31,7 @@
 #define CBOR_ROOT_ARRAY_LENGTH 1
 
 static int64_t OCTagsPayloadToCbor(OCTagsPayload *tags, CborEncoder *setMap);
-static int64_t OCLinksPayloadToCbor(OCLinksPayload *rtPtr, CborEncoder *setMap);
+static int64_t OCLinksPayloadToCbor(OCLinksPayload *links, CborEncoder *setMap);
 static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, const char *value);
 static int64_t ConditionalAddIntToMap(CborEncoder *map, const char *tags, const uint64_t *value);
 static int64_t AddStringLLToMap(CborEncoder *map, const char *tag, const OCStringLL *value);
@@ -40,10 +40,13 @@ static CborError OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **li
 static CborError FindStringInMap(const CborValue *map, const char *tags, char **value);
 static CborError FindIntInMap(const CborValue *map, const char *tags, uint64_t *value);
 static CborError FindStringLLInMap(const CborValue *linksMap, const char *tag, OCStringLL **links);
+static OCStackResult CreateStringLL(uint8_t numElements, OCResourceHandle handle,
+                                    const char* (*getValue)(OCResourceHandle handle, uint8_t i),
+                                    OCStringLL **stringLL);
 
 int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size)
 {
-    int64_t cborEncoderResult = CborErrorIO;
+    int64_t cborEncoderResult = CborNoError;
     int flags = 0;
     CborEncoder encoder;
     VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Invalid input parameter rdPayload");
@@ -76,21 +79,18 @@ int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, siz
     }
     else if (rdPayload->rdPublish)
     {
-        CborEncoder colArray;
-        cborEncoderResult |= cbor_encoder_create_array(&encoder, &colArray, CborIndefiniteLength);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create collection array");
+        CborEncoder collMap;
+        cborEncoderResult |= cbor_encoder_create_map(&encoder, &collMap, CborIndefiniteLength);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create collection map");
 
         OCResourceCollectionPayload *rdPublish = rdPayload->rdPublish;
-        while (rdPublish)
-        {
-            cborEncoderResult |= OCTagsPayloadToCbor(rdPublish->tags, &colArray);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding tags payload");
-            cborEncoderResult |= OCLinksPayloadToCbor(rdPublish->setLinks, &colArray);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding setLinks payload");
-            rdPublish = rdPublish->next;
-        }
-        cborEncoderResult |= cbor_encoder_close_container(&encoder, &colArray);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing collection array");
+        cborEncoderResult |= OCTagsPayloadToCbor(rdPublish->tags, &collMap);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding tags payload");
+        cborEncoderResult |= OCLinksPayloadToCbor(rdPublish->setLinks, &collMap);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding setLinks payload");
+
+        cborEncoderResult |= cbor_encoder_close_container(&encoder, &collMap);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing collection map");
     }
     else
     {
@@ -119,97 +119,89 @@ exit:
 
 static int64_t OCTagsPayloadToCbor(OCTagsPayload *tags, CborEncoder *setMap)
 {
-    CborEncoder tagsMap;
     int64_t cborEncoderResult = CborNoError;
-    cborEncoderResult |= cbor_encoder_create_map(setMap, &tagsMap, CborIndefiniteLength);
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create tags map");
 
-    cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DEVICE_NAME, tags->n.deviceName);
+    cborEncoderResult |= ConditionalAddTextStringToMap(setMap, OC_RSRVD_DEVICE_NAME,
+        tags->n.deviceName);
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_NAME in tags map");
 
-    cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DEVICE_ID,
-            (char *)tags->di.id);
+    cborEncoderResult |= ConditionalAddTextStringToMap(setMap, OC_RSRVD_DEVICE_ID,
+        (char *)tags->di.id);
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_ID in tags map");
 
-    cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_RTS, tags->rts);
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_RTS in tags map");
-
-    cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DREL, tags->drel);
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DREL in tags map");
-
-    cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_BASE_URI, tags->baseURI);
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_BASE_URI in tags map");
-
-    {
-        uint64_t value = tags->bitmap;
-        cborEncoderResult |= ConditionalAddIntToMap(&tagsMap, OC_RSRVD_BITMAP, &value);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_BITMAP in tags map");
-
-        value = tags->port;
-        cborEncoderResult |= ConditionalAddIntToMap(&tagsMap, OC_RSRVD_HOSTING_PORT, &value);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_HOSTING_PORT in tags map");
-
-        value = tags->ins;
-        cborEncoderResult |= ConditionalAddIntToMap(&tagsMap, OC_RSRVD_INS, &value);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_INS in tags map");
-
-        value = tags->ttl;
-        cborEncoderResult |= ConditionalAddIntToMap(&tagsMap, OC_RSRVD_TTL, &value);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TTL in tags map");
-    }
-
-    cborEncoderResult |= cbor_encoder_close_container(setMap, &tagsMap);
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close container");
-
+    cborEncoderResult |= ConditionalAddIntToMap(setMap, OC_RSRVD_DEVICE_TTL, &tags->ttl);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TTL in tags map");
 exit:
     return cborEncoderResult;
 }
 
-static int64_t OCLinksPayloadToCbor(OCLinksPayload *rtPtr, CborEncoder *setMap)
+static int64_t OCLinksPayloadToCbor(OCLinksPayload *links, CborEncoder *setMap)
 {
     CborEncoder linksArray;
     int64_t cborEncoderResult = CborNoError;
 
+    cborEncoderResult |= cbor_encode_text_string(setMap, OC_RSRVD_LINKS,
+        sizeof(OC_RSRVD_LINKS) - 1);
+
     cborEncoderResult |= cbor_encoder_create_array(setMap, &linksArray, CborIndefiniteLength);
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create Links array");
 
-    while (rtPtr)
+    while (links)
     {
         CborEncoder linksMap;
         cborEncoderResult |= cbor_encoder_create_map(&linksArray, &linksMap, CborIndefiniteLength);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create Links map");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create links map");
 
-        cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_HREF, rtPtr->href);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_HREF in Links map");
+        cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_HREF, links->href);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_HREF in links map");
 
-        cborEncoderResult|= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_REL, rtPtr->rel);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_REL in Links map");
+        cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_REL, links->rel);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_REL in links map");
 
-        cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_TITLE, rtPtr->title);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TITLE in Links map");
+        cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, links->rt);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_RT in links map");
 
-        cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_URI, rtPtr->uri);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_URI in Links map");
+        cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_INTERFACE, links->itf);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_ITF in links map");
 
-        cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, rtPtr->rt);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_RT in Links map");
+        // Policy
+        CborEncoder policyMap;
+        cborEncoderResult |= cbor_encode_text_string(&linksMap, OC_RSRVD_POLICY,
+            sizeof(OC_RSRVD_POLICY) - 1);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding policy tag to links map");
+        cborEncoderResult |= cbor_encoder_create_map(&linksMap, &policyMap, CborIndefiniteLength);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding policy map to links map");
 
-        cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_INTERFACE, rtPtr->itf);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_ITF in Links map");
+        // Bitmap
+        cborEncoderResult |= cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
+            sizeof(OC_RSRVD_BITMAP) - 1);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding bitmap tag to policy map");
+        cborEncoderResult |= cbor_encode_uint(&policyMap, links->p);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding bitmap value to policy map");
 
-        cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_MEDIA_TYPE, rtPtr->mt);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_MT in Links map");
+        cborEncoderResult |= cbor_encoder_close_container(&linksMap, &policyMap);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing policy map");
 
-        {
-            uint64_t value = rtPtr->ins;
-            cborEncoderResult |= ConditionalAddIntToMap(&linksMap, OC_RSRVD_INS, &value);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_INS in Links map");
-        }
+        cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_TITLE, links->title);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TITLE in links map");
+
+        cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_URI, links->anchor);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_URI in links map");
 
+        cborEncoderResult |= ConditionalAddIntToMap(&linksMap, OC_RSRVD_INS, (uint64_t *) &links->ins);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_INS in links map");
+
+        cborEncoderResult |= ConditionalAddIntToMap(&linksMap, OC_RSRVD_TTL, &links->ttl);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TTL in links map");
+
+        cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_MEDIA_TYPE, links->type);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_MT in links map");
+
+        // Finsihed encoding a resource, close the map.
         cborEncoderResult |= cbor_encoder_close_container(&linksArray, &linksMap);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing Links map");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing links map");
 
-        rtPtr = rtPtr->next;
+        links = links->next;
     }
     cborEncoderResult |= cbor_encoder_close_container(setMap, &linksArray);
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing links array");
@@ -229,40 +221,33 @@ OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPay
 
     ret = OC_STACK_MALFORMED_RESPONSE;
 
-    if (cbor_value_is_array(rdCBORPayload))
+    if (cbor_value_is_map(rdCBORPayload))
     {
-        OCLinksPayload *linksPayload = NULL;
+        // rdCBORPayload is already inside the main root map.
         OCTagsPayload *tagsPayload = NULL;
+        OCLinksPayload *linksPayload = NULL;
+
+        cborFindResult = OCTagsCborToPayload(rdCBORPayload, &tagsPayload);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing tags payload.");
+
+        cborFindResult = OCLinksCborToPayload(rdCBORPayload, &linksPayload);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing links payload.");
+
+        // Move from tags payload to links array.
+        cborFindResult = cbor_value_advance(rdCBORPayload);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCborPayload.");
 
-        while (cbor_value_is_container(rdCBORPayload))
-        {
-            // enter tags map
-            CborValue tags;
-            cborFindResult = cbor_value_enter_container(rdCBORPayload, &tags);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering tags container.");
-
-            cborFindResult= OCTagsCborToPayload(&tags, &tagsPayload);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing tags payload.");
-            OCTagsLog(DEBUG, tagsPayload);
-
-            cborFindResult = OCLinksCborToPayload(&tags, &linksPayload);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing links payload.");
-            OCLinksLog(DEBUG, linksPayload);
-
-            // Move from tags payload to links array.
-            cborFindResult = cbor_value_advance(rdCBORPayload);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCborPayload.");
-        }
         rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
         VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdPublish, "Failed allocating rdPayload->rdPublish");
     }
+    // TODO: This logic needs to be modified to check the payload type exactly..
     else if (cbor_value_is_map(rdCBORPayload))
     {
         rdPayload->rdDiscovery = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload));
         VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdDiscovery, "Failed allocating discoveryPayload");
 
         cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_NAME,
-                &rdPayload->rdDiscovery->n.deviceName);
+                                         &rdPayload->rdDiscovery->n.deviceName);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_NAME.");
         char *deviceId = NULL;
         cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_ID, &deviceId);
@@ -335,14 +320,15 @@ static CborError FindStringLLInMap(const CborValue *linksMap, const char *tag, O
             VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL");
             *links = llPtr;
         }
-        else if(llPtr)
+        else if (llPtr)
         {
             while (llPtr->next)
             {
                 llPtr = llPtr->next;
             }
             llPtr->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
-            VERIFY_PARAM_NON_NULL(TAG, llPtr->next, "Failed allocating OCStringLL->next");
+            llPtr = llPtr->next;
+            VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL->next");
         }
         cborFindResult = cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed duplicating value");
@@ -363,16 +349,10 @@ static CborError OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPay
     OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload));
     VERIFY_PARAM_NON_NULL(TAG, tags, "Failed allocating tags");
 
-    if (cbor_value_is_map(tagsMap))
+    cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_NAME, &tags->n.deviceName);
+    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceName");
+
     {
-        cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_NAME, &tags->n.deviceName);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceName");
-        cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DREL, &tags->drel);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding drel");
-        cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_RTS, &tags->rts);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rts");
-        cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_BASE_URI, &tags->baseURI);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding baseURI");
         char *deviceId = NULL;
         cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_ID, &deviceId);
         if (deviceId)
@@ -381,27 +361,11 @@ static CborError OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPay
             OICFree(deviceId);
         }
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceId");
-        {
-            uint64_t value = 0;
-            cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_HOSTING_PORT, &value);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding port");
-            tags->port = value;
-            value = 0;
-            cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_BITMAP, &value);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding bitmap");
-            tags->bitmap = value;
-            value = 0;
-            cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_INS, &value);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins");
-            tags->ins = value;
-            value = 0;
-            cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_TTL, &value);
-            tags->ttl = value;
-        }
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl");
-        cborFindResult = cbor_value_advance(tagsMap);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing bitmap");
     }
+
+    cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_DEVICE_TTL, &tags->ttl);
+    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl");
+
     *tagsPayload = tags;
     return cborFindResult;
 
@@ -410,11 +374,17 @@ exit:
     return cborFindResult;
 }
 
-static CborError OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **linksPayload)
+static CborError OCLinksCborToPayload(CborValue *links, OCLinksPayload **linksPayload)
 {
-    CborValue linksMap;
     OCLinksPayload *setLinks = NULL;
-    CborError cborFindResult = cbor_value_enter_container(linksArray, &linksMap);
+    CborValue linksMap;
+    CborValue linksArray;
+    CborError cborFindResult = CborErrorOutOfMemory;
+
+    cborFindResult = cbor_value_map_find_value(links, OC_RSRVD_LINKS, &linksArray);
+    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding links array");
+
+    cborFindResult = cbor_value_enter_container(&linksArray, &linksMap);
     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering links map container");
 
     while (cbor_value_is_map(&linksMap))
@@ -428,28 +398,36 @@ static CborError OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **li
         cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rel value");
 
+        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rt value");
+
+        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding itf value");
+
+        // Policy
+        CborValue policyMap;
+        cborFindResult = cbor_value_map_find_value(&linksMap, OC_RSRVD_POLICY, &policyMap);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "to find policy tag");
+
+        // Bitmap
+        cborFindResult = FindIntInMap(&policyMap, OC_RSRVD_BITMAP, (uint64_t *) &setLinks->p);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding bitmap value");
+
         cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding title value");
 
-        cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->uri);
+        cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->anchor);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding uri value");
 
-        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rt value");
+        cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, (uint64_t *) &setLinks->ins);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins value");
 
-        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding itf value");
+        cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_TTL, &setLinks->ttl);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl");
 
-        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->mt);
+        cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->type);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding mt value");
 
-        {
-            uint64_t value = 0;
-            cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, &value);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins value");
-            setLinks->ins = value;
-        }
-
         if (!*linksPayload)
         {
             *linksPayload = setLinks;
@@ -506,6 +484,7 @@ static int64_t AddStringLLToMap(CborEncoder *map, const char *tag, const OCStrin
 {
     CborEncoder array;
     int64_t cborEncoderResult = CborNoError;
+
     cborEncoderResult |= cbor_encode_text_string(map, tag, strlen(tag));
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed encoding string tag name");
     cborEncoderResult |= cbor_encoder_create_array(map, &array, CborIndefiniteLength);
@@ -532,6 +511,143 @@ exit:
     return rdPayload;
 }
 
+#ifdef RD_CLIENT
+OCRDPayload *OCRDPublishPayloadCreate(OCResourceHandle resourceHandles[], uint8_t nHandles,
+                                      uint64_t ttl)
+{
+    OCTagsPayload *tagsPayload = NULL;
+    OCLinksPayload *linksPayload = NULL;
+    OCStringLL *rt = NULL;
+    OCStringLL *itf = NULL;
+    OCStringLL *mt = NULL;
+    OCResourceProperty p = OC_RES_PROP_NONE;
+    uint8_t ins = 0;
+
+    OCRDPayload *rdPayload = OCRDPayloadCreate();
+    if (!rdPayload)
+    {
+        return NULL;
+    }
+
+    const unsigned char *id = (const unsigned char *) OCGetServerInstanceIDString();
+    tagsPayload = OCCopyTagsResources(NULL, id, ttl);
+    if (!tagsPayload)
+    {
+        goto exit;
+    }
+
+    for (uint8_t j = 0; j < nHandles; j++)
+    {
+        OCResourceHandle handle = resourceHandles[j];
+        if (handle)
+        {
+            rt = NULL;
+            itf = NULL;
+            mt = NULL;
+            ins = 0;
+            const char *uri = OCGetResourceUri(handle);
+            uint8_t numElement = 0;
+            if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement))
+            {
+                OCStackResult res = CreateStringLL(numElement, handle, OCGetResourceTypeName, &rt);
+                if (OC_STACK_OK != res || !rt)
+                {
+                    goto exit;
+                }
+            }
+
+            if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement))
+            {
+                OCStackResult res = CreateStringLL(numElement, handle, OCGetResourceInterfaceName,
+                                                   &itf);
+                if (OC_STACK_OK != res || !itf)
+                {
+                    goto exit;
+                }
+            }
+
+            p = OCGetResourceProperties(handle);
+            p = (OCResourceProperty) ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE));
+
+            OCStackResult res = OCGetResourceIns(handle, &ins);
+            if (OC_STACK_OK != res)
+            {
+                goto exit;
+            }
+
+            mt = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!mt)
+            {
+                goto exit;
+            }
+            mt->value = OICStrdup(DEFAULT_MESSAGE_TYPE);
+            if (!mt->value)
+            {
+                goto exit;
+            }
+
+            if (!linksPayload)
+            {
+                linksPayload = OCCopyLinksResources(uri, NULL, rt, itf, p, NULL,
+                                                    NULL, ins, ttl, mt);;
+                if (!linksPayload)
+                {
+                    goto exit;
+                }
+            }
+            else
+            {
+                OCLinksPayload *temp = linksPayload;
+                while (temp->next)
+                {
+                    temp = temp->next;
+                }
+                temp->next = OCCopyLinksResources(uri, NULL, rt, itf, p, NULL,
+                                                  NULL, ins, ttl, mt);
+                if (!temp->next)
+                {
+                    goto exit;
+                }
+            }
+            OCFreeOCStringLL(rt);
+            OCFreeOCStringLL(itf);
+            OCFreeOCStringLL(mt);
+        }
+    }
+
+    rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
+    if (!rdPayload->rdPublish)
+    {
+        goto exit;
+    }
+
+    return rdPayload;
+
+exit:
+    if (rt)
+    {
+        OCFreeOCStringLL(rt);
+    }
+    if (itf)
+    {
+        OCFreeOCStringLL(itf);
+    }
+    if (mt)
+    {
+        OCFreeOCStringLL(mt);
+    }
+    if (tagsPayload)
+    {
+        OCFreeTagsResource(tagsPayload);
+    }
+    if (linksPayload)
+    {
+        OCFreeLinksResource(linksPayload);
+    }
+    OCRDPayloadDestroy(rdPayload);
+    return NULL;
+}
+#endif
 OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(const char *deviceName, const char *id, int biasFactor)
 {
     OCRDDiscoveryPayload *discoveryPayload = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload));
@@ -574,35 +690,31 @@ void OCRDPayloadDestroy(OCRDPayload *payload)
 
     if (payload->rdPublish)
     {
-        for (OCResourceCollectionPayload *col = payload->rdPublish; col; )
+        OCResourceCollectionPayload *col = payload->rdPublish;
+
+        if (col->setLinks)
         {
-            if (col->setLinks)
-            {
-                OCFreeLinksResource(col->setLinks);
-            }
+            OCFreeLinksResource(col->setLinks);
+        }
 
-            if (col->tags)
-            {
-                OCFreeTagsResource(col->tags);
-            }
-            OCResourceCollectionPayload *temp = col->next;
-            OICFree(col);
-            col = temp;
+        if (col->tags)
+        {
+            OCFreeTagsResource(col->tags);
         }
+        OICFree(col);
     }
 
     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* OCCopyTagsResources(const char *deviceName, const unsigned char *id, uint64_t ttl)
 {
     OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload));
     if (!tags)
     {
         return NULL;
     }
-       if (deviceName)
+    if (deviceName)
     {
         tags->n.deviceName = OICStrdup(deviceName);
         if (!tags->n.deviceName)
@@ -614,33 +726,6 @@ OCTagsPayload* OCCopyTagsResources(const char *deviceName, const unsigned char *
     {
         OICStrcpy((char*)tags->di.id, MAX_IDENTITY_SIZE, (char *)id);
     }
-    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;
 
@@ -650,8 +735,10 @@ memory_allocation_failed:
     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* OCCopyLinksResources(const char *href, const char *rel, OCStringLL *rt,
+                                     OCStringLL *itf, uint8_t p, const char *title,
+                                     const char *anchor, uint8_t ins, uint64_t ttl,
+                                     OCStringLL *mt)
 {
     OCLinksPayload *links = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload));
     if (!links)
@@ -667,6 +754,14 @@ OCLinksPayload* OCCopyLinksResources(const char *href, OCStringLL *rt, OCStringL
             goto memory_allocation_failed;
         }
     }
+    if (rel)
+    {
+        links->rel = OICStrdup(rel);
+        if (!links->rel)
+        {
+            goto memory_allocation_failed;
+        }
+    }
     if (rt)
     {
         links->rt = CloneOCStringLL(rt);
@@ -683,15 +778,7 @@ OCLinksPayload* OCCopyLinksResources(const char *href, OCStringLL *rt, OCStringL
             goto memory_allocation_failed;
         }
     }
-    if (rel)
-    {
-        links->rel = OICStrdup(rel);
-        if (!links->rel)
-        {
-            goto memory_allocation_failed;
-        }
-    }
-    links->obs = obs;
+    links->p = p;
     if (title)
     {
         links->title = OICStrdup(title);
@@ -700,19 +787,20 @@ OCLinksPayload* OCCopyLinksResources(const char *href, OCStringLL *rt, OCStringL
             goto memory_allocation_failed;
         }
     }
-    if (uri)
+    if (anchor)
     {
-        links->uri = OICStrdup(uri);
-        if (!links->uri)
+        links->anchor = OICStrdup(anchor);
+        if (!links->anchor)
         {
             goto memory_allocation_failed;
         }
     }
     links->ins = ins;
+    links->ttl = ttl;
     if (mt)
     {
-        links->mt = CloneOCStringLL(mt);
-        if (!links->mt)
+        links->type = CloneOCStringLL(mt);
+        if (!links->type)
         {
             goto memory_allocation_failed;
         }
@@ -742,21 +830,21 @@ exit:
     return pl;
 }
 
-void OCFreeLinksResource(OCLinksPayload *payload)
+void OCFreeLinksResource(OCLinksPayload *links)
 {
-    if (!payload)
+    if (!links)
     {
         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);
+    OICFree(links->href);
+    OICFree(links->rel);
+    OCFreeOCStringLL(links->rt);
+    OCFreeOCStringLL(links->itf);
+    OICFree(links->title);
+    OICFree(links->anchor);
+    OCFreeOCStringLL(links->type);
+    OCFreeLinksResource(links->next);
+    OICFree(links);
 }
 
 void OCFreeTagsResource(OCTagsPayload *payload)
@@ -765,10 +853,7 @@ void OCFreeTagsResource(OCTagsPayload *payload)
     {
         return;
     }
-    OICFree(payload->n.deviceName);
-    OICFree(payload->baseURI);
-    OICFree(payload->rts);
-    OICFree(payload->drel);
+    OICFree(payload->n.deviceName);;
     OICFree(payload);
 }
 
@@ -786,99 +871,52 @@ void OCFreeCollectionResource(OCResourceCollectionPayload *payload)
     {
         OCFreeLinksResource(payload->setLinks);
     }
-    OCFreeCollectionResource(payload->next);
     OICFree(payload);
 }
 
-void OCTagsLog(const LogLevel level, const OCTagsPayload *tags)
+static OCStackResult CreateStringLL(uint8_t numElements, OCResourceHandle handle,
+                                    const char* (*getValue)(OCResourceHandle handle, uint8_t i),
+                                    OCStringLL **stringLL)
 {
-    if (tags)
+    for (uint8_t i = 0; i < numElements; ++i)
     {
-        if (tags->n.deviceName)
-        {
-            OIC_LOG_V(level, TAG, " Device Name : %s ",tags->n.deviceName);
-        }
-        if (tags->baseURI)
+        const char *value = getValue(handle, i);
+        OIC_LOG_V(ERROR, TAG, "value: %s", value);
+        if (!*stringLL)
         {
-            OIC_LOG_V(level, TAG, " Base URI : %s ",tags->baseURI);
-        }
-        OIC_LOG_V(level, TAG, " Device ID : %s ",tags->di.id);
-        OIC_LOG_V(level, TAG, " Bitmap : %d ",tags->bitmap);
-        OIC_LOG_V(level, TAG, " Port : %d ",tags->port);
-        OIC_LOG_V(level, TAG, " Ins : %d ",tags->ins);
-        OIC_LOG_V(level, TAG, " Ttl : %d ",tags->ttl);
-
-        if (tags->rts)
-        {
-            OIC_LOG_V(level, TAG, " RTS : %s ",tags->rts);
-        }
-        if (tags->drel)
-        {
-            OIC_LOG_V(level, TAG, " DREL : %s ",tags->drel);
-        }
-    }
-    else
-    {
-        (void) level;
-    }
-}
-
-void OCLinksLog(const LogLevel level, const OCLinksPayload *links)
-{
-    while (links)
-    {
-        if (links->href)
-        {
-            OIC_LOG_V(level, TAG, " href: %s ",links->href);
-        }
-        OIC_LOG(level, TAG, " RT: ");
-        OCStringLL *rt = links->rt;
-        while (rt)
-        {
-            if (rt->value)
+            *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!*stringLL)
             {
-                OIC_LOG_V(level, TAG, "   %s", rt->value);
+                OIC_LOG(ERROR, TAG, "Failed allocating memory.");
+                return OC_STACK_NO_MEMORY;
             }
-            rt = rt->next;
-        }
-        OIC_LOG(level, TAG, " IF: ");
-        OCStringLL *itf = links->itf;
-        while (itf)
-        {
-            if (itf->value)
+            (*stringLL)->value = OICStrdup(value);
+            if (!(*stringLL)->value)
             {
-                OIC_LOG_V(level, TAG, "   %s", itf->value);
+                OIC_LOG(ERROR, TAG, "Failed copying to OCStringLL.");
+                return OC_STACK_NO_MEMORY;
             }
-            itf = itf->next;
         }
-        OIC_LOG(level, TAG, " MT: ");
-        OCStringLL *mt = links->mt;
-        while (mt)
+        else
         {
-            if (mt->value)
+            OCStringLL *cur = *stringLL;
+            while (cur->next)
             {
-                OIC_LOG_V(level, TAG, "   %s", mt->value);
+                cur = cur->next;
+            }
+            cur->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!cur->next)
+            {
+                OIC_LOG(ERROR, TAG, "Failed allocating memory.");
+                return OC_STACK_NO_MEMORY;
+            }
+            cur->next->value = OICStrdup(value);
+            if (!cur->next->value)
+            {
+                OIC_LOG(ERROR, TAG, "Failed copying to OCStringLL.");
+                return OC_STACK_NO_MEMORY;
             }
-            mt = mt->next;
-        }
-        OIC_LOG_V(level, TAG, " INS: %d", links->ins);
-        OIC_LOG_V(level, TAG, " OBS: %d", links->obs);
-        if (links->rel)
-        {
-            OIC_LOG_V(level, TAG, " REL: %s", links->rel);
-        }
-        if (links->title)
-        {
-            OIC_LOG_V(level, TAG, " TITLE: %s", links->title);
-        }
-        if (links->uri)
-        {
-            OIC_LOG_V(level, TAG, " URI: %s", links->uri);
         }
-        links = links->next;
-    }
-    if (!links)
-    {
-        (void) level;
     }
+    return OC_STACK_OK;
 }
diff --git a/resource/csdk/stack/test/rdtests.cpp b/resource/csdk/stack/test/rdtests.cpp
new file mode 100644 (file)
index 0000000..38dbd84
--- /dev/null
@@ -0,0 +1,262 @@
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+extern "C"
+{
+    #include "rdpayload.h"
+    #include "oicresourcedirectory.h"
+    #include "ocstack.h"
+    #include "ocstackinternal.h"
+    #include "logger.h"
+    #include "oic_malloc.h"
+}
+
+#include "gtest/gtest.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+#include <stdint.h>
+
+#include "gtest_helper.h"
+
+using namespace std;
+
+namespace itst = iotivity::test;
+
+#define DEFAULT_CONTEXT_VALUE 0x99
+
+//-----------------------------------------------------------------------------
+// Private variables
+//-----------------------------------------------------------------------------
+static const char TAG[] = "RDTests";
+
+std::chrono::seconds const SHORT_TEST_TIMEOUT = std::chrono::seconds(5);
+
+//-----------------------------------------------------------------------------
+// Callback functions
+//-----------------------------------------------------------------------------
+static OCStackApplicationResult handlePublishCB(__attribute__((unused))void *ctx,
+                                                __attribute__((unused)) OCDoHandle handle,
+                                                __attribute__((unused))
+                                                OCClientResponse *clientResponse)
+{
+    OIC_LOG(DEBUG, TAG, "Successfully published resources.");
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackApplicationResult handleDeleteCB(__attribute__((unused))void *ctx,
+                                               __attribute__((unused)) OCDoHandle handle,
+                                               __attribute__((unused))
+                                               OCClientResponse *clientResponse)
+{
+    OIC_LOG(DEBUG, TAG, "Successfully delete resources.");
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+//-----------------------------------------------------------------------------
+// Entity handler
+//-----------------------------------------------------------------------------
+OCEntityHandlerResult rdEntityHandler(OCEntityHandlerFlag /*flag*/,
+                                      OCEntityHandlerRequest * /*entityHandlerRequest*/,
+                                      void* /*callbackParam*/)
+{
+    OIC_LOG(INFO, TAG, "Entering entityHandler");
+
+    return OC_EH_OK;
+}
+
+//-----------------------------------------------------------------------------
+//  Tests
+//-----------------------------------------------------------------------------
+class RDTests : public testing::Test {
+    protected:
+    virtual void SetUp()
+    {
+        OCInit("127.0.0.1", 5683, OC_CLIENT_SERVER);
+    }
+
+    virtual void TearDown()
+    {
+        OCStop();
+    }
+};
+
+TEST_F(RDTests, CreateRDPayload)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OCResourceHandle handle;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle, "core.light",
+                                            "oic.if.baseline", "/a/light", rdEntityHandler,
+                                            NULL, OC_DISCOVERABLE | OC_OBSERVABLE));
+
+    // Create RD Publish Payload.
+    OCRDPayload *rdPayload = (OCRDPayload *) OCRDPublishPayloadCreate(&handle, 1, 86400);
+    EXPECT_TRUE(rdPayload != NULL);
+
+    // Cleanup.
+    OCRDPayloadDestroy(rdPayload);
+}
+
+TEST_F(RDTests, ConvertParseRDPayload)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OCResourceHandle handle;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle, "core.light",
+                                            "oic.if.baseline", "/a/light", rdEntityHandler,
+                                            NULL, OC_DISCOVERABLE | OC_OBSERVABLE));
+
+    // Create RD Publish Payload.
+    OCRDPayload *rdPayload = (OCRDPayload *) OCRDPublishPayloadCreate(&handle, 1, 86400);
+    EXPECT_TRUE(rdPayload != NULL);
+
+    if (rdPayload)
+    {
+        // Convert RD Publish Payload to CBOR.
+        size_t curSize = 255;
+        uint8_t *outPayload = (uint8_t *)OICCalloc(1, curSize);
+        OCRDPayloadToCbor(rdPayload, outPayload, &curSize);
+
+        // Parse CBOR back to RD Publish Payload.
+        CborParser parser;
+        CborValue rootValue;
+        cbor_parser_init(outPayload, curSize, 0, &parser, &rootValue);
+
+        OCRDPayload *rdPayload = NULL;
+        EXPECT_EQ(OC_STACK_OK, OCRDCborToPayload(&rootValue, (OCPayload**) &rdPayload));
+
+        // Cleanup.
+        OICFree(outPayload);
+    }
+    OCRDPayloadDestroy(rdPayload);
+}
+
+TEST_F(RDTests, RDPublishResourceNullAddr)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    EXPECT_EQ(OC_STACK_INVALID_IP, OCRDPublish(0, CT_ADAPTER_IP, nullptr, 0, 0, OC_LOW_QOS));
+}
+
+TEST_F(RDTests, RDPublishResourceNullCB)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCRDPublish("127.0.0.1", CT_ADAPTER_IP, nullptr,
+                                                     0, 0, OC_LOW_QOS));
+}
+
+TEST_F(RDTests, RDPublishResource)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OCCallbackData cbData;
+    cbData.cb = &handlePublishCB;
+    cbData.cd = NULL;
+    cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
+
+    OCResourceHandle handle;
+
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle, "core.light",
+                                            "oic.if.baseline", "/a/light", rdEntityHandler,
+                                            NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+
+    EXPECT_EQ(OC_STACK_OK, OCRDPublish("127.0.0.1", CT_ADAPTER_IP, &handle,
+                                       1, &cbData, OC_LOW_QOS));
+}
+
+TEST_F(RDTests, RDPublishMultipleResources)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OCCallbackData cbData;
+    cbData.cb = &handlePublishCB;
+    cbData.cd = NULL;
+    cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
+
+    OCResourceHandle handles[2];
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles[0], "core.light",
+                                            "oic.if.baseline", "/a/light", rdEntityHandler,
+                                            NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles[1], "core.light",
+                                            "oic.if.baseline", "/a/light2", rdEntityHandler,
+                                            NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+
+    EXPECT_EQ(OC_STACK_OK, OCRDPublish("127.0.0.1", CT_ADAPTER_IP, handles,
+                                       2, &cbData, OC_LOW_QOS));
+}
+
+TEST_F(RDTests, RDDeleteResourceNullAddr)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    EXPECT_EQ(OC_STACK_INVALID_IP, OCRDDelete(0, CT_ADAPTER_IP, nullptr, 0, 0, OC_LOW_QOS));
+}
+
+TEST_F(RDTests, RDDeleteResourceNullCB)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+    EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCRDDelete("127.0.0.1", CT_ADAPTER_IP, nullptr,
+                                                    0, 0, OC_LOW_QOS));
+}
+
+TEST_F(RDTests, RDDeleteAllResource)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OCCallbackData cbData;
+    cbData.cb = &handleDeleteCB;
+    cbData.cd = NULL;
+    cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
+
+    EXPECT_EQ(OC_STACK_OK, OCRDDelete("127.0.0.1", CT_ADAPTER_IP, nullptr, 0, &cbData,
+                                      OC_LOW_QOS));
+}
+
+TEST_F(RDTests, RDDeleteSpecificResource)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OCCallbackData cbData;
+    cbData.cb = &handleDeleteCB;
+    cbData.cd = NULL;
+    cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
+
+    OCResourceHandle handle;
+
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle, "core.light",
+                                            "oic.if.baseline", "/a/light", rdEntityHandler,
+                                            NULL, OC_DISCOVERABLE | OC_OBSERVABLE));
+
+    EXPECT_EQ(OC_STACK_OK, OCRDDelete("127.0.0.1", CT_ADAPTER_IP, &handle,
+                                      1, &cbData, OC_LOW_QOS));
+}
index c85806d..ba49690 100644 (file)
@@ -79,6 +79,12 @@ if examples_env.get('WITH_CLOUD'):
 if target_os in ['msys_nt', 'windows']:
        examples_env.AppendUnique(LIBS = ['Comctl32', 'Gdi32', 'User32'])
 
+if examples_env.get('LOGGING'):
+       examples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+if 'CLIENT' in examples_env.get('RD_MODE'):
+       examples_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
+
 def make_single_file_cpp_program(program_name):
        return examples_env.Program(program_name, program_name + ".cpp")
 
@@ -103,7 +109,12 @@ if target_os not in ['windows', 'msys_nt']:
                'groupserver',
                'groupclient',
                'lightserver',
-               'threadingsample',
+               'threadingsample'
+               ]
+
+if 'CLIENT' in examples_env.get('RD_MODE'):
+       example_names += [
+               'rdclient'
                ]
 
 examples = map(make_single_file_cpp_program, example_names)
diff --git a/resource/examples/rdclient.cpp b/resource/examples/rdclient.cpp
new file mode 100644 (file)
index 0000000..9dd0750
--- /dev/null
@@ -0,0 +1,280 @@
+//******************************************************************
+//
+// Copyright 2016 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 "OCPlatform.h"
+#include "OCApi.h"
+
+#include <functional>
+#include <iostream>
+
+using namespace std;
+using namespace OC;
+
+string rdAddress;
+OCConnectivityType connectivityType = CT_ADAPTER_TCP;
+
+ResourceHandles m_publishedResourceHandles;
+
+static void onDelete(const int& eCode);
+static void onPublish(const OCRepresentation& rep, const int& eCode);
+
+class Resource
+{
+
+public:
+    std::string m_resourceUri;
+    OCResourceHandle m_resourceHandle;
+
+public:
+    /// This function internally calls registerResource API.
+    void registerResource()
+    {
+        string resourceURI;
+        string resourceTypeName;
+        string resourceInterface;
+
+        std::cout <<"   resourceURI: ";
+        std::cin >> resourceURI;
+        std::cout <<"   resourceTypeName: ";
+        std::cin >> resourceTypeName;
+        std::cout <<"   resourceInterface: ";
+        std::cin >> resourceInterface;
+
+        m_resourceUri = resourceURI;
+
+        OCPlatform::registerResource(m_resourceHandle, resourceURI, resourceTypeName,
+                                     resourceInterface,
+                                     nullptr,
+                                     OC_DISCOVERABLE);
+
+        m_publishedResourceHandles.push_back(m_resourceHandle);
+        cout << "registerResource is called." << endl;
+    }
+
+    void updateResource()
+    {
+        cout << "   1:: add resource type\n";
+        cout << "   2:: add resource interface\n";
+
+        int selectedMenu;
+        std::cin >> selectedMenu;
+
+        string inputString;
+        switch (selectedMenu)
+        {
+        case 1:
+            std::cout << "Add Resource Type" << std::endl;
+            std::cout <<"   resourceTypeName: ";
+            std::cin >> inputString;
+            OCPlatform::bindTypeToResource(m_resourceHandle, inputString);
+            break;
+        case 2:
+            std::cout << "Add Resource Interface" << std::endl;
+            std::cout <<"   resourceInterface: ";
+            std::cin >> inputString;
+            OCPlatform::bindInterfaceToResource(m_resourceHandle, inputString);
+            break;
+        default:
+            cout << "Invalid option" << endl;
+            return;
+        }
+    }
+
+    void publishResource()
+    {
+        /*
+         * Publish Resource of Resource-Server to RD.
+         */
+
+        OCStackResult result = OCPlatform::publishResourceToRD(rdAddress, connectivityType,
+                                                               m_publishedResourceHandles,
+                                                               &onPublish);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource publish was unsuccessful\n";
+        }
+    }
+
+    void deleteResource()
+    {
+        /*
+         * Delete Resource with Resource Handle.
+         * Don't need to include resource handle,
+         * if resource-server want to delete all resources from RD.
+         * Ex.) OCPlatform::deleteResourceFromRD(rdAddress, connectivityType, &onDelete);
+         */
+        OCStackResult result = OCPlatform::deleteResourceFromRD(rdAddress, connectivityType,
+                                                                m_publishedResourceHandles,
+                                                                &onDelete);
+        if (OC_STACK_OK != result)
+        {
+            cout << "Resource delete was unsuccessful\n";
+        }
+    }
+};
+
+void onDelete(const int& eCode)
+{
+    cout << "Received Delete Resource Response From RD\n";
+    try
+    {
+        if (OC_STACK_RESOURCE_DELETED == eCode)
+        {
+            cout << "Resource delete was successful\n";
+        }
+        else
+        {
+            std::cout << "onDelete Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+    catch(std::exception& e)
+    {
+        std::cout << "Exception: " << e.what() << " in onDelete" << std::endl;
+    }
+}
+
+void onPublish(const OCRepresentation& rep, const int& eCode)
+{
+    cout << endl <<"Received Publish Resource Response From RD\n";
+
+    try
+    {
+        if (OC_STACK_RESOURCE_CREATED == eCode)
+        {
+            cout << "=========== Published Resource ===========" << endl;
+            if (rep.hasAttribute("di"))
+            {
+                std::cout << " di: " << rep.getValue<std::string>("di") << std::endl;
+            }
+
+            // Published Resource is included as the child resource.
+            std::vector<OCRepresentation> children = rep.getChildren();
+
+            for (auto oit = children.begin(); oit != children.end(); ++oit)
+            {
+                std::string m_href;
+                oit->getValue("href", m_href);
+                cout << "   href : " << m_href << "\n";
+
+                cout << "   resource type : \n";
+                for(const std::string& type : oit->getResourceTypes())
+                {
+                    cout << "       " <<  type << "\n";
+                }
+
+                cout << "   resource interface : \n";
+                for(const std::string& type : oit->getResourceInterfaces())
+                {
+                    cout << "       " <<  type << "\n";
+                }
+
+                int m_ins;
+                oit->getValue("ins", m_ins);
+                cout << "   ins : " << m_ins << "\n";
+            }
+            cout << "=========================================" << endl;
+        }
+        else
+        {
+            std::cout << "onPublish Response error: " << eCode << std::endl;
+            std::exit(-1);
+        }
+    }
+    catch(std::exception& e)
+    {
+        std::cout << "Exception: " << e.what() << " in onPublish" << std::endl;
+    }
+}
+
+static void printUsage()
+{
+    std::cout<<"Usage: rdserver <coap+tcp://10.11.12.13:5683>\n";
+}
+
+int main(int argc, char* argv[])
+{
+    ostringstream requestURI;
+
+    if (argc == 2)
+    {
+        rdAddress = argv[1];
+    }
+    else
+    {
+        printUsage();
+        return -1;
+    }
+
+    PlatformConfig config
+    { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+
+    try
+    {
+        OCPlatform::Configure(config);
+
+        int selectedMenu;
+        bool isRun = true;
+
+        std::cout << "Register resources" << std::endl;
+        Resource myResource;
+        myResource.registerResource();
+
+        while (isRun)
+        {
+            cout << "================= MENU =================" << endl;
+            cout << "0 :: Quit" << endl;
+            cout << "1 :: UPDATE RESOURCE" << endl;
+            cout << "2 :: PUBLISH RESOURCE TO RD" << endl;
+            cout << "3 :: DELETE RESOURCE FROM RD" << endl;
+            cout << "========================================" << endl;
+            std::cin >> selectedMenu;
+
+            switch (selectedMenu)
+            {
+            case 0:
+                isRun = false;
+                break;
+            case 1:
+                std::cout << "Update resources" << std::endl;
+                myResource.updateResource();
+                break;
+            case 2:
+                std::cout << "Publish resources to RD" << std::endl;
+                myResource.publishResource();
+                break;
+            case 3:
+                std::cout << "Delete resources from RD" << std::endl;
+                myResource.deleteResource();
+                break;
+            default:
+                cout << "Invalid option" << endl;
+            }
+
+        }
+    }
+    catch (OCException& e)
+    {
+        oclog() << "Exception in main: "<< e.what();
+    }
+
+    return 0;
+}
+
index 62f878a..f422392 100644 (file)
@@ -74,6 +74,19 @@ namespace OC
         virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler) = 0;
 
         virtual OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse) = 0;
+#ifdef RD_CLIENT
+        virtual OCStackResult publishResourceToRD(const std::string& host,
+                                                  OCConnectivityType connectivityType,
+                                                  ResourceHandles& resourceHandles,
+                                                  PublishResourceCallback& callback,
+                                                  OCQualityOfService qos) = 0;
+
+        virtual OCStackResult deleteResourceFromRD(const std::string& host,
+                                                   OCConnectivityType connectivityType,
+                                                   ResourceHandles& resourceHandles,
+                                                   DeleteResourceCallback& callback,
+                                                   OCQualityOfService qos) = 0;
+#endif
     };
 }
 
index 2e04e58..ad578dd 100644 (file)
 
 namespace OC
 {
+#ifdef RD_CLIENT
+    namespace ServerCallbackContext
+    {
+        struct PublishContext
+        {
+            PublishResourceCallback callback;
+            PublishContext(PublishResourceCallback cb) : callback(cb){}
+        };
+
+        struct DeleteContext
+        {
+            DeleteResourceCallback callback;
+            DeleteContext(DeleteResourceCallback cb) : callback(cb){}
+        };
+    }
+#endif
     class InProcServerWrapper : public IServerWrapper
     {
     public:
@@ -68,6 +84,19 @@ namespace OC
         virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler);
 
         virtual OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse);
+#ifdef RD_CLIENT
+        virtual OCStackResult publishResourceToRD(const std::string& host,
+                                                  OCConnectivityType connectivityType,
+                                                  ResourceHandles& resourceHandles,
+                                                  PublishResourceCallback& callback,
+                                                  OCQualityOfService qos);
+
+        virtual OCStackResult deleteResourceFromRD(const std::string& host,
+                                                   OCConnectivityType connectivityType,
+                                                   ResourceHandles& resourceHandles,
+                                                   DeleteResourceCallback& callback,
+                                                   OCQualityOfService qos);
+#endif
     private:
         void processFunc();
         std::thread m_processThread;
index 1188db1..0af7727 100644 (file)
@@ -213,18 +213,21 @@ namespace OC
         Observe,
         ObserveAll
     };
-    //
-    // Typedef for header option vector
-    // OCHeaderOption class is in HeaderOption namespace
+
+    // Typedef for list of resource handles.
+    typedef std::vector<OCResourceHandle> ResourceHandles;
+
+    // Typedef for header option vector.
+    // OCHeaderOption class is in HeaderOption namespace.
     typedef std::vector<HeaderOption::OCHeaderOption> HeaderOptions;
 
-    // Typedef for query parameter map
+    // Typedef for query parameter map.
     typedef std::map<std::string, std::string> QueryParamsMap;
 
     // Typedef for query parameter map with Vector
     typedef std::map< std::string, std::vector<std::string> > QueryParamsList;
 
-    // Typedef for list of observation IDs
+    // Typedef for list of observation IDs.
     typedef std::vector<OCObservationId> ObservationIds;
 
     enum class ObserveAction
@@ -297,7 +300,11 @@ namespace OC
     typedef std::function<void(const HeaderOptions&,
                                const OCRepresentation&, const int,
                                std::shared_ptr<OCResource>)> MQCreateTopicCallback;
+#ifdef RD_CLIENT
+    typedef std::function<void(const OCRepresentation&, const int)> PublishResourceCallback;
 
+    typedef std::function<void(const int)> DeleteResourceCallback;
+#endif
 } // namespace OC
 
 #endif
index f5e9692..78742bf 100644 (file)
@@ -715,6 +715,99 @@ namespace OC
                                          OCConnectivityType connectivityType,
                                          PostCallback cloudConnectHandler);
 #endif // WITH_CLOUD
+#ifdef RD_CLIENT
+        /**
+         * API for Virtual Resource("/oic/d" and "/oic/p") Publish to Resource Directory.
+         * @note This API applies to resource server side only.
+         *
+         * @param host Host IP Address of a service to direct resource publish query.
+         * @param connectivityType ::OCConnectivityType type of connectivity.
+         * @param callback Handles callbacks, success states and failure states.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult publishResourceToRD(const std::string& host,
+                                          OCConnectivityType connectivityType,
+                                          PublishResourceCallback callback);
+
+        /**
+         * API for Resource Publish to Resource Directory.
+         * @note This API applies to resource server side only.
+         *
+         * @param host Host IP Address of a service to direct resource publish query.
+         * @param connectivityType ::OCConnectivityType type of connectivity.
+         * @param resourceHandle resource handle of the resource.
+         * @param callback Handles callbacks, success states and failure states.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult publishResourceToRD(const std::string& host,
+                                          OCConnectivityType connectivityType,
+                                          ResourceHandles& resourceHandles,
+                                          PublishResourceCallback callback);
+
+        /**
+         * @overload
+         *
+         * @param host Host IP Address of a service to direct resource publish query.
+         * @param connectivityType ::OCConnectivityType type of connectivity.
+         * @param resourceHandle resource handle of the resource.
+         * @param callback function to callback with published resources.
+         * @param QoS the quality of communication
+         * @see publishResourceToRD(const std::string&, OCConnectivityType, OCResourceHandle,
+         * uint8_t, PublishResourceCallback)
+         */
+        OCStackResult publishResourceToRD(const std::string& host,
+                                          OCConnectivityType connectivityType,
+                                          ResourceHandles& resourceHandles,
+                                          PublishResourceCallback callback, QualityOfService QoS);
+
+        /**
+         * API for published resource delete from Resource Directory.
+         * @note This API applies to resource server side only.
+         *
+         * @param host Host IP Address of a service to direct resource delete query.
+         * @param connectivityType ::OCConnectivityType type of connectivity.
+         * @param callback Handles callbacks, success states and failure states.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           DeleteResourceCallback callback);
+
+        /**
+         * @overload
+         *
+         * @param host Host IP Address of a service to direct resource delete query.
+         * @param connectivityType ::OCConnectivityType type of connectivity.
+         * @param resourceHandle resource handle of the resource.
+         * @param callback function to callback with published resources.
+         * @param QoS the quality of communication
+         * @see publishResourceToRD(const std::string&, OCConnectivityType, OCResourceHandle,
+         * uint8_t, PublishResourceCallback)
+         */
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           ResourceHandles& resourceHandles,
+                                           DeleteResourceCallback callback);
+
+        /**
+         * @overload
+         *
+         * @param host Host IP Address of a service to direct resource delete query.
+         * @param connectivityType ::OCConnectivityType type of connectivity.
+         * @param resourceHandle resource handle of the resource.
+         * @param callback function to callback with published resources.
+         * @param QoS the quality of communication
+         * @see publishResourceToRD(const std::string&, OCConnectivityType, OCResourceHandle,
+         * uint8_t, PublishResourceCallback)
+         */
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           ResourceHandles& resourceHandles,
+                                           DeleteResourceCallback callback, QualityOfService QoS);
+#endif
     }
 }
 
index 7897c46..b3d1aa3 100644 (file)
@@ -238,7 +238,31 @@ namespace OC
                         const std::vector<std::string>& resourceTypes,
                         const std::vector<std::string>& interfaces);
         OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse);
-
+#ifdef RD_CLIENT
+        OCStackResult publishResourceToRD(const std::string& host,
+                                          OCConnectivityType connectivityType,
+                                          ResourceHandles& resourceHandles,
+                                          PublishResourceCallback callback);
+
+        OCStackResult publishResourceToRD(const std::string& host,
+                                          OCConnectivityType connectivityType,
+                                          ResourceHandles& resourceHandles,
+                                          PublishResourceCallback callback, QualityOfService qos);
+
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           DeleteResourceCallback callback);
+
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           ResourceHandles& resourceHandles,
+                                           DeleteResourceCallback callback);
+
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           ResourceHandles& resourceHandles,
+                                           DeleteResourceCallback callback, QualityOfService qos);
+#endif
         std::weak_ptr<std::recursive_mutex> csdkLock();
 
         OCStackResult findDirectPairingDevices(unsigned short waittime,
index be9a117..c07974a 100644 (file)
@@ -66,7 +66,9 @@ namespace OC
             void setPayload(const OCPlatformPayload* rep);
 
             void setPayload(const OCRepPayload* rep);
-
+#ifdef RD_CLIENT
+            void setPayload(const OCRDPayload* rep);
+#endif
             OCRepPayload* getPayload() const;
 
             const std::vector<OCRepresentation>& representations() const;
@@ -464,6 +466,9 @@ namespace OC
             template<typename T>
             T payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl);
             void setPayload(const OCRepPayload* payload);
+#ifdef RD_CLIENT
+            void setPayload(const OCLinksPayload* payload);
+#endif
             void setPayloadArray(const OCRepPayloadValue* pl);
             void getPayloadArray(OCRepPayload* payload,
                     const OCRepresentation::AttributeItem& item) const;
index 0f3e397..44e1178 100644 (file)
@@ -124,6 +124,7 @@ namespace OC
         static const char DUPLICATE_UUID[]             = "Duplicate UUID in DB";
         static const char INCONSISTENT_DB[]            = "Data in provisioning DB is inconsistent";
         static const char AUTHENTICATION_FAILURE[]     = "Authentication failure";
+        static const char PUBLISH_RESOURCE_FAILED[]    = "Publish Resource failure";
     }
 
     namespace Error
index 2fd1c19..bd7639d 100644 (file)
 #include <OCPlatform.h>
 #include <OCUtilities.h>
 
+#ifdef RD_CLIENT
+#include <oicresourcedirectory.h>
+#endif
+
 using namespace std;
 using namespace OC;
 
@@ -595,7 +599,149 @@ namespace OC
             return result;
         }
     }
+#ifdef RD_CLIENT
+    OCRepresentation parseRDResponseCallback(OCClientResponse* clientResponse)
+    {
+        if (nullptr == clientResponse->payload ||
+                    PAYLOAD_TYPE_RD != clientResponse->payload->type)
+        {
+            return OCRepresentation();
+        }
+
+        MessageContainer oc;
+        oc.setPayload(clientResponse->payload);
+
+        std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
+        if (it == oc.representations().end())
+        {
+            return OCRepresentation();
+        }
 
+        // first one is considered the root, everything else is considered a child of this one.
+        OCRepresentation root = *it;
+        root.setDevAddr(clientResponse->devAddr);
+        root.setUri(clientResponse->resourceUri);
+        ++it;
+
+        std::for_each(it, oc.representations().end(),
+                [&root](const OCRepresentation& repItr)
+                {root.addChild(repItr);});
+        return root;
+
+    }
+
+    OCStackApplicationResult publishResourceToRDCallback(void* ctx, OCDoHandle /*handle*/,
+                                                         OCClientResponse* clientResponse)
+    {
+        ServerCallbackContext::PublishContext* context =
+        static_cast<ServerCallbackContext::PublishContext*>(ctx);
+
+        try
+        {
+            // Update resource unique id in stack.
+            if (clientResponse)
+            {
+                if (clientResponse->payload)
+                {
+                    OCRDPayload *rdPayload = (OCRDPayload *) clientResponse->payload;
+                    OCLinksPayload *links = rdPayload->rdPublish->setLinks;
+
+                    while (links)
+                    {
+                        OCResourceHandle handle = OCGetResourceHandleAtUri(links->href);
+                        OCBindResourceInsToResource(handle, links->ins);
+                        links = links->next;
+                    }
+
+                }
+            }
+
+            OCRepresentation rep = parseRDResponseCallback(clientResponse);
+            std::thread exec(context->callback, rep, clientResponse->result);
+            exec.detach();
+        }
+        catch (OC::OCException& e)
+        {
+            oclog() <<"Exception in publishResourceToRDCallback, ignoring response: "
+                <<e.what() <<std::flush;
+        }
+
+        return OC_STACK_KEEP_TRANSACTION;
+    }
+
+    OCStackResult InProcServerWrapper::publishResourceToRD(const std::string& host,
+                                                           OCConnectivityType connectivityType,
+                                                           ResourceHandles& resourceHandles,
+                                                           PublishResourceCallback& callback,
+                                                           OCQualityOfService qos)
+    {
+        ServerCallbackContext::PublishContext* ctx =
+            new ServerCallbackContext::PublishContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                publishResourceToRDCallback,
+                [](void* c)
+                {delete static_cast<ServerCallbackContext::PublishContext*>(c);}
+                );
+
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCRDPublish(host.c_str(), connectivityType, &resourceHandles[0],
+                                 resourceHandles.size(), &cbdata, qos);
+        }
+
+        if (OC_STACK_OK != result)
+        {
+            throw OCException(OC::Exception::PUBLISH_RESOURCE_FAILED, result);
+        }
+        return result;
+    }
+
+    OCStackApplicationResult deleteResourceFromRDCallback(void* ctx, OCDoHandle /*handle*/,
+                                                          OCClientResponse* clientResponse)
+    {
+        ServerCallbackContext::DeleteContext* context =
+        static_cast<ServerCallbackContext::DeleteContext*>(ctx);
+
+        std::thread exec(context->callback, clientResponse->result);
+        exec.detach();
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OCStackResult InProcServerWrapper::deleteResourceFromRD(const std::string& host,
+                                                            OCConnectivityType connectivityType,
+                                                            ResourceHandles& resourceHandles,
+                                                            DeleteResourceCallback& callback,
+                                                            OCQualityOfService qos)
+    {
+        ServerCallbackContext::DeleteContext* ctx =
+            new ServerCallbackContext::DeleteContext(callback);
+        OCCallbackData cbdata(
+                static_cast<void*>(ctx),
+                deleteResourceFromRDCallback,
+                [](void* c)
+                {delete static_cast<ServerCallbackContext::DeleteContext*>(c);}
+                );
+
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCRDDelete(host.c_str(), connectivityType, &resourceHandles[0],
+                                resourceHandles.size(), &cbdata, qos);
+        }
+
+        if (OC_STACK_OK != result)
+        {
+            throw OCException(OC::Exception::PUBLISH_RESOURCE_FAILED, result);
+        }
+        return result;
+    }
+#endif
     InProcServerWrapper::~InProcServerWrapper()
     {
         if(m_processThread.joinable())
index 913f658..8373b23 100644 (file)
@@ -343,6 +343,65 @@ namespace OC
                                                        connectivityType, cloudConnectHandler);
         }
 #endif // WITH_CLOUD
+#ifdef RD_CLIENT
+        OCStackResult publishResourceToRD(const std::string& host,
+                                          OCConnectivityType connectivityType,
+                                          PublishResourceCallback callback)
+        {
+            ResourceHandles resourceHandles;
+            return OCPlatform_impl::Instance().publishResourceToRD(host, connectivityType,
+                                                                   resourceHandles,
+                                                                   callback);
+        }
+
+        OCStackResult publishResourceToRD(const std::string& host,
+                                          OCConnectivityType connectivityType,
+                                          ResourceHandles& resourceHandles,
+                                          PublishResourceCallback callback)
+        {
+            return OCPlatform_impl::Instance().publishResourceToRD(host, connectivityType,
+                                                                   resourceHandles,
+                                                                   callback);
+        }
+
+        OCStackResult publishResourceToRD(const std::string& host,
+                                          OCConnectivityType connectivityType,
+                                          ResourceHandles& resourceHandles,
+                                          PublishResourceCallback callback, QualityOfService QoS)
+        {
+            return OCPlatform_impl::Instance().publishResourceToRD(host, connectivityType,
+                                                                   resourceHandles,
+                                                                   callback, QoS);
+        }
+
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           DeleteResourceCallback callback)
+        {
+            ResourceHandles resourceHandles;
+            return OCPlatform_impl::Instance().deleteResourceFromRD(host, connectivityType,
+                                                                    resourceHandles, callback);
+        }
+
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           ResourceHandles& resourceHandles,
+                                           DeleteResourceCallback callback)
+        {
+            return OCPlatform_impl::Instance().deleteResourceFromRD(host, connectivityType,
+                                                                    resourceHandles, callback);
+        }
+
+        OCStackResult deleteResourceFromRD(const std::string& host,
+                                           OCConnectivityType connectivityType,
+                                           ResourceHandles& resourceHandles,
+                                           DeleteResourceCallback callback, QualityOfService QoS)
+        {
+            return OCPlatform_impl::Instance().deleteResourceFromRD(host, connectivityType,
+                                                                    resourceHandles, callback,
+                                                                    QoS);
+        }
+#endif
     } // namespace OCPlatform
 } //namespace OC
 
index f5817c6..4c89788 100644 (file)
@@ -399,7 +399,47 @@ namespace OC
         return checked_guard(m_server, &IServerWrapper::sendResponse,
                              pResponse);
     }
+#ifdef RD_CLIENT
+    OCStackResult OCPlatform_impl::publishResourceToRD(const std::string& host,
+                                                       OCConnectivityType connectivityType,
+                                                       ResourceHandles& resourceHandles,
+                                                       PublishResourceCallback callback)
+    {
+        return publishResourceToRD(host, connectivityType, resourceHandles,
+                                   callback, m_cfg.QoS);
+    }
+
+    OCStackResult OCPlatform_impl::publishResourceToRD(const std::string& host,
+                                                       OCConnectivityType connectivityType,
+                                                       ResourceHandles& resourceHandles,
+                                                       PublishResourceCallback callback,
+                                                       QualityOfService qos)
+    {
+        return checked_guard(m_server, &IServerWrapper::publishResourceToRD,
+                             host, connectivityType, resourceHandles, callback,
+                             static_cast<OCQualityOfService>(qos));
+    }
 
+    OCStackResult OCPlatform_impl::deleteResourceFromRD(const std::string& host,
+                                                        OCConnectivityType connectivityType,
+                                                        ResourceHandles& resourceHandles,
+                                                        DeleteResourceCallback callback)
+    {
+        return deleteResourceFromRD(host, connectivityType, resourceHandles, callback,
+                                    m_cfg.QoS);
+    }
+
+    OCStackResult OCPlatform_impl::deleteResourceFromRD(const std::string& host,
+                                                        OCConnectivityType connectivityType,
+                                                        ResourceHandles& resourceHandles,
+                                                        DeleteResourceCallback callback,
+                                                        QualityOfService qos)
+    {
+        return checked_guard(m_server, &IServerWrapper::deleteResourceFromRD,
+                             host, connectivityType, resourceHandles, callback,
+                             static_cast<OCQualityOfService>(qos));
+    }
+#endif
     std::weak_ptr<std::recursive_mutex> OCPlatform_impl::csdkLock()
     {
         return m_csdkLock;
index 06b2083..476d72b 100644 (file)
@@ -59,6 +59,11 @@ namespace OC
             case PAYLOAD_TYPE_PLATFORM:
                 setPayload(reinterpret_cast<const OCPlatformPayload*>(rep));
                 break;
+#ifdef RD_CLIENT
+            case PAYLOAD_TYPE_RD:
+                setPayload(reinterpret_cast<const OCRDPayload*>(rep));
+                break;
+#endif
             default:
                 throw OC::OCException("Invalid Payload type in setPayload");
                 break;
@@ -150,7 +155,7 @@ namespace OC
     void MessageContainer::setPayload(const OCRepPayload* payload)
     {
         const OCRepPayload* pl = payload;
-        while(pl)
+        while (pl)
         {
             OCRepresentation cur;
             cur.setPayload(pl);
@@ -159,7 +164,29 @@ namespace OC
             this->addRepresentation(cur);
         }
     }
+#ifdef RD_CLIENT
+    void MessageContainer::setPayload(const OCRDPayload* payload)
+    {
+        OCRepresentation rep;
+        rep[OC_RSRVD_DEVICE_ID] = (payload->rdPublish->tags->di.id) ?
+            std::string(reinterpret_cast<const char*>(payload->rdPublish->tags->di.id)) :
+            std::string();
+        rep[OC_RSRVD_DEVICE_NAME] = (payload->rdPublish->tags->n.deviceName) ?
+            std::string(payload->rdPublish->tags->n.deviceName) :
+            std::string();
+        this->addRepresentation(rep);
 
+        const OCLinksPayload* pl = payload->rdPublish->setLinks;
+        while (pl)
+        {
+            OCRepresentation cur;
+            cur.setPayload(pl);
+
+            pl = pl->next;
+            this->addRepresentation(cur);
+        }
+    }
+#endif
     OCRepPayload* MessageContainer::getPayload() const
     {
         OCRepPayload* root = nullptr;
@@ -657,7 +684,43 @@ namespace OC
             val = val->next;
         }
     }
+#ifdef RD_CLIENT
+    void OCRepresentation::setPayload(const OCLinksPayload* pl)
+    {
+        if (pl->href)
+        {
+            setValue<std::string>(OC_RSRVD_HREF, pl->href);
+        }
+        if (pl->rel)
+        {
+            setValue<std::string>(OC_RSRVD_REL, pl->rel);
+        }
+        OCStringLL* ll = pl->rt;
+        while (ll)
+        {
+            addResourceType(ll->value);
+            ll = ll->next;
+        }
+        ll = pl->itf;
+        while (ll)
+        {
+            addResourceInterface(ll->value);
+            ll = ll->next;
+        }
 
+        setValue<int>(OC_RSRVD_POLICY, pl->p);
+        setValue<int>(OC_RSRVD_INS, pl->ins);
+        setValue<int>(OC_RSRVD_TTL, pl->ttl);
+        if (pl->title)
+        {
+            setValue<std::string>(OC_RSRVD_TITLE, pl->title);
+        }
+        if (pl->anchor)
+        {
+            setValue<std::string>(OC_RSRVD_URI, pl->anchor);
+        }
+    }
+#endif
     void OCRepresentation::addChild(const OCRepresentation& rep)
     {
         m_children.push_back(rep);
index 32ff64b..c5f10d2 100644 (file)
@@ -80,6 +80,11 @@ if target_os in ['msys_nt', 'windows']:
 if oclib_env.get('WITH_CLOUD'):
        oclib_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
 
+if 'CLIENT' in oclib_env.get('RD_MODE'):
+       oclib_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
+if 'SERVER' in oclib_env.get('RD_MODE'):
+       oclib_env.AppendUnique(CPPDEFINES = ['RD_SERVER'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
index 114be6e..7d8f1ac 100755 (executable)
@@ -47,9 +47,9 @@ if target_os not in ['arduino','darwin', 'ios', 'windows']:
     if target_os in ['linux'] and env.get('SIMULATOR', False):
         SConscript('simulator/SConscript')
 
-# Build resource directory project
-if env.get('WITH_RD') == '1':
-    SConscript('resource-directory/SConscript')
+    # Build resource directory project
+    #if env.get('WITH_RD') == '1':
+        #SConscript('resource-directory/SConscript')
 
 # Build EasySetup module
 if target_os in ['arduino', 'android', 'linux','tizen']: