Resolve circular dependency for resource directory server
authorHabib Virji <habib.virji@samsung.com>
Tue, 1 Nov 2016 17:39:23 +0000 (17:39 +0000)
committerZiran Sun <ziran.sun@samsung.com>
Tue, 29 Nov 2016 15:27:57 +0000 (15:27 +0000)
[Habib Virji]
RD Shared Library creates a circular dependency between
resource_directory and octbstack. This patch resolves this dependency by
creating a seprating findResource part of the resource_directory.

[Philippe Coval]
Backported to 1.2-branch
Without this change built on Tizen with RD_MODE=CLIENT,SERVER
 failed on missing oicresourcedirectory.c

Change-Id: I653b9130e10f22dd61f4f1bd0b6ff4c47a69606a
Signed-off-by: Habib Virji <habib.virji@samsung.com>
Origin: https://gerrit.iotivity.org/gerrit/13935
Signed-off-by: Philippe Coval <philippe.coval@osg.samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/14813
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Shuvradeb Barman Srijon <srijon.sb@samsung.com>
Reviewed-by: Ziran Sun <ziran.sun@samsung.com>
resource/csdk/SConscript
resource/csdk/resource-directory/include/rd_database.h
resource/csdk/resource-directory/src/internal/rd_database.c
resource/csdk/resource-directory/unittests/rddatabase.cpp
resource/csdk/resource-directory/unittests/rdtests.cpp
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/oicresourcedirectory.c [new file with mode: 0644]

index 3139bfc501045513d69f362d0c1c8cab02e659dc..4bc1fdc9596ebe332f7c0f385f7647697dc5a3d2 100644 (file)
@@ -158,15 +158,14 @@ if liboctbstack_env.get('ROUTING') in ['GW', 'EP']:
        liboctbstack_env.Prepend(LIBS = ['routingmanager'])
 
 if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
-       liboctbstack_env.PrependUnique(CPPPATH = ['resource-directory/include'])
-       if 'CLIENT' in rd_mode:
-               liboctbstack_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
-       if 'SERVER' in rd_mode:
-               liboctbstack_env.AppendUnique(CPPDEFINES = ['RD_SERVER'])
-               if target_os in ['tizen']:
-                       liboctbstack_env.ParseConfig('pkg-config --cflags --libs sqlite3')
-               else:
-                       liboctbstack_env.AppendUnique(CPPPATH = ['#extlibs/sqlite3'])
+    if 'CLIENT' in rd_mode:
+        liboctbstack_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
+    if 'SERVER' in rd_mode:
+        liboctbstack_env.AppendUnique(CPPDEFINES = ['RD_SERVER'])
+        if target_os in ['tizen']:
+            liboctbstack_env.ParseConfig('pkg-config --cflags --libs sqlite3')
+        else:
+            liboctbstack_env.AppendUnique(CPPPATH = ['#extlibs/sqlite3'])
 
 ######################################################################
 # Source files and Targets
@@ -191,9 +190,19 @@ if with_tcp == True:
        liboctbstack_src.append(OCTBSTACK_SRC + 'oickeepalive.c')
 
 if 'SERVER' in rd_mode:
-       liboctbstack_src.append(OCTBSTACK_SRC + 'oicresourcedirectory.c')
-       if target_os not in ['tizen']:
-               liboctbstack_src.append('#extlibs/sqlite3/sqlite3.c')
+    liboctbstack_src.append(OCTBSTACK_SRC + 'oicresourcedirectory.c')
+    if target_os not in ['tizen']:
+        liboctbstack_src.append('#extlibs/sqlite3/sqlite3.c')
+
+if target_os in ['linux']:
+    # Linux uses a Shared library because SCons chooses the shared library on Linux
+    # when only 'octbstack' is added to the LIBS.
+    # TODO: Switch Linux to use a Static library for testing like every other OS.
+    test_liboctbstack = liboctbstack_env.SharedLibrary('octbstack_test', liboctbstack_src)
+else:
+    test_liboctbstack = liboctbstack_env.StaticLibrary('octbstack_test', liboctbstack_src)
+
+octbstack_libs = Flatten(test_liboctbstack)
 
 if target_os in ['windows', 'msys_nt']:
        # Avoid a name conflict with the octbstack.lib target of the SharedLibrary.
index 3f82f580bbe6abc644dff941138caf68a3bfd230..f23330c9c215f85522ec2ffe8a4338a3957e2e44 100644 (file)
@@ -46,19 +46,6 @@ OCStackResult OCRDDatabaseInit(const char *path);
  */
 OCStackResult OCRDDatabaseStoreResources(const OCRepPayload *payload, const OCDevAddr *address);
 
-/**
- * Search the RD database for queries.
- *
- * @param interfaceType is the interface type that is queried.
- * @param resourceType is the resource type that is queried.
- * @param discPayload is NULL if no resource found or else OCDiscoveryPayload with the details
- * about the resource.
- *
- * @return ::OC_STACK_OK in case of success or else other value.
- */
-OCStackResult OCRDDatabaseCheckResources(const char *interfaceType, const char *resourceType,
-    OCDiscoveryPayload *discPayload);
-
 /**
  * Updates the RD resource
  *
index e0c3127c5d2f1e32b49b777f62275352606e2bc2..8be91e9319fd91bd57a3dbb71526ad244fdc09af 100644 (file)
@@ -384,201 +384,4 @@ OCStackResult OCRDDatabaseDeleteDevice(const char *deviceId)
     return OC_STACK_OK;
 }
 
-static OCStackResult appendStringLL(OCStringLL **type, const unsigned char *value)
-{
-    OCStringLL *temp= (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
-    if (!temp)
-    {
-        return OC_STACK_NO_MEMORY;
-    }
-    temp->value = OICStrdup((char *)value);
-    if (!temp->value)
-    {
-        return OC_STACK_NO_MEMORY;
-    }
-    temp->next = NULL;
-
-    if (!*type)
-    {
-        *type = temp;
-    }
-    else
-    {
-        OCStringLL *tmp = *type;
-        for (; tmp->next; tmp = tmp->next);
-        tmp->next = temp;
-    }
-    return OC_STACK_OK;
-}
-
-OCStackResult OCRDDatabaseCheckResources(const char *interfaceType, const char *resourceType, OCDiscoveryPayload *discPayload)
-{
-    CHECK_DATABASE_INIT;
-    if (!interfaceType && !resourceType)
-    {
-        return OC_STACK_INVALID_QUERY;
-    }
-    OCResourcePayload *resourcePayload = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
-    if (!resourcePayload)
-    {
-        return OC_STACK_NO_MEMORY;
-    }
-
-    if (resourceType)
-    {
-        sqlite3_stmt *stmt = 0;
-        const char *input = "SELECT * FROM RD_DEVICE_LINK_LIST INNER JOIN RD_LINK_RT ON " \
-        "RD_DEVICE_LINK_LIST.INS=RD_LINK_RT.LINK_ID WHERE RD_LINK_RT.rt LIKE ? ";
-
-        VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, -1, &stmt, NULL));
-        VERIFY_SQLITE(sqlite3_bind_text(stmt, 1, resourceType, strlen(resourceType) + 1, SQLITE_STATIC));
-
-        int res = sqlite3_step (stmt);
-        if (SQLITE_ROW == res|| SQLITE_DONE == res)
-        {
-            int id = sqlite3_column_int(stmt, 0);
-            const unsigned char *uri = sqlite3_column_text(stmt, uri_index - 1);
-            int bitmap = sqlite3_column_int(stmt, p_index - 1);
-            int deviceId = sqlite3_column_int(stmt, d_index - 1);
-            OIC_LOG_V(DEBUG, TAG, " %s %d", uri, deviceId);
-            resourcePayload->uri = OICStrdup((char *)uri);
-            if (!resourcePayload->uri)
-            {
-                OCDiscoveryResourceDestroy(resourcePayload);
-                return OC_STACK_NO_MEMORY;
-            }
-            VERIFY_SQLITE(sqlite3_reset(stmt));
-
-            sqlite3_stmt *stmtRT = 0;
-            const char *rt = "SELECT rt FROM RD_LINK_RT WHERE LINK_ID=?";
-            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, rt, -1, &stmtRT, NULL));
-            VERIFY_SQLITE(sqlite3_bind_int(stmtRT, 1, id));
-            while (SQLITE_ROW == sqlite3_step(stmtRT))
-            {
-                const unsigned char *rt1 = sqlite3_column_text(stmtRT, (rt_value_index - 1));
-                if (rt1)
-                {
-                    appendStringLL(&resourcePayload->types, rt1);
-                }
-            }
-
-            sqlite3_stmt *stmtIF = 0;
-            const char *itf = "SELECT if FROM RD_LINK_IF WHERE LINK_ID=?";
-            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, itf, -1, &stmtIF, NULL));
-            VERIFY_SQLITE(sqlite3_bind_int(stmtIF, 1, id));
-            while (SQLITE_ROW == sqlite3_step(stmtIF))
-            {
-                const unsigned char *itf = sqlite3_column_text(stmtIF, (if_value_index - 1));
-                if (itf)
-                {
-                    appendStringLL(&resourcePayload->interfaces, itf);
-                }
-            }
-
-            resourcePayload->bitmap = bitmap & (OC_OBSERVABLE | OC_DISCOVERABLE);
-            resourcePayload->secure = (bitmap & OC_SECURE) != 0;
-
-            const char *address = "SELECT di, address FROM RD_DEVICE_LIST INNER JOIN RD_DEVICE_LINK_LIST ON " \
-            "RD_DEVICE_LINK_LIST.DEVICE_ID = RD_DEVICE_LIST.ID WHERE RD_DEVICE_LINK_LIST.DEVICE_ID=?";
-
-            sqlite3_stmt *stmt1 = 0;
-            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, address, -1, &stmt1, NULL));
-            VERIFY_SQLITE(sqlite3_bind_int(stmt1, 1, deviceId));
-            // TODO: Right now, we have a bug where discovery payload can only send one device information.
-            res = sqlite3_step(stmt1);
-            if (SQLITE_ROW == res || SQLITE_DONE == res)
-            {
-                const unsigned char *di = sqlite3_column_text(stmt1, (device_index - 1));
-                const unsigned char *address = sqlite3_column_text(stmt1, (address_index - 1));
-                if (address && di)
-                {
-                    OIC_LOG_V(DEBUG, TAG, " %s %s", di, address);
-                    (discPayload)->baseURI = OICStrdup((char *)address);
-                    (discPayload)->sid = OICStrdup((char *)di);
-                }
-            }
-            OCDiscoveryPayloadAddNewResource(discPayload, resourcePayload);
-        }
-    }
-    if (interfaceType)
-    {
-        sqlite3_stmt *stmt = 0;
-        const char *input = "SELECT * FROM RD_DEVICE_LINK_LIST INNER JOIN RD_LINK_IF ON " \
-        "RD_DEVICE_LINK_LIST.INS=RD_LINK_IF.LINK_ID WHERE RD_LINK_IF.if LIKE ? ";
-
-        VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, -1, &stmt, NULL));
-        VERIFY_SQLITE(sqlite3_bind_text(stmt, 1, interfaceType, strlen(interfaceType) + 1, SQLITE_STATIC));
-
-        int res = sqlite3_step (stmt);
-        if (SQLITE_ROW == res|| SQLITE_DONE == res)
-        {
-            int id = sqlite3_column_int(stmt, 0);
-            const unsigned char *uri = sqlite3_column_text(stmt, uri_index - 1);
-            int bitmap = sqlite3_column_int(stmt, p_index - 1);
-            int deviceId = sqlite3_column_int(stmt, d_index - 1);
-            OIC_LOG_V(DEBUG, TAG, " %s %d", uri, deviceId);
-            if (uri)
-            {
-                resourcePayload->uri = OICStrdup((char *)uri);
-                if (!resourcePayload->uri)
-                {
-                    OCDiscoveryResourceDestroy(resourcePayload);
-                    return OC_STACK_NO_MEMORY;
-                }
-                VERIFY_SQLITE(sqlite3_reset(stmt));
-            }
-
-            sqlite3_stmt *stmtRT = 0;
-            const char *rt = "SELECT rt FROM RD_LINK_RT WHERE LINK_ID=?";
-            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, rt, -1, &stmtRT, NULL));
-            VERIFY_SQLITE(sqlite3_bind_int(stmtRT, bind_index_value, id));
-            while (SQLITE_ROW == sqlite3_step(stmtRT))
-            {
-                const unsigned char *rt1 = sqlite3_column_text(stmtRT, (rt_value_index - 1));
-                if (rt1)
-                {
-                    appendStringLL(&resourcePayload->types, rt1);
-                }
-            }
-
-            sqlite3_stmt *stmtIF = 0;
-            const char *itf = "SELECT if FROM RD_LINK_IF WHERE LINK_ID=?";
-            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, itf, -1, &stmtIF, NULL));
-            VERIFY_SQLITE(sqlite3_bind_int(stmtIF, 1, id));
-            while (SQLITE_ROW == sqlite3_step (stmtIF))
-            {
-                const unsigned char *itf = sqlite3_column_text(stmtIF, (if_value_index - 1));
-                if (itf)
-                {
-                    appendStringLL(&resourcePayload->interfaces, itf);
-                }
-            }
-
-            resourcePayload->bitmap = bitmap & (OC_OBSERVABLE | OC_DISCOVERABLE);
-            resourcePayload->secure = ((bitmap & OC_SECURE) != 0);
-
-            const char *address = "SELECT di, address FROM RD_DEVICE_LIST INNER JOIN RD_DEVICE_LINK_LIST ON " \
-            "RD_DEVICE_LINK_LIST.DEVICE_ID = RD_DEVICE_LIST.ID WHERE RD_DEVICE_LINK_LIST.DEVICE_ID=?";
-
-            sqlite3_stmt *stmt1 = 0;
-            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, address, -1, &stmt1, NULL));
-            VERIFY_SQLITE(sqlite3_bind_int(stmt1, 1, deviceId));
-
-            res = sqlite3_step(stmt1);
-            if (SQLITE_ROW == res || SQLITE_DONE == res)
-            {
-                const unsigned char *di = sqlite3_column_text(stmt1, 0);
-                const unsigned char *address = sqlite3_column_text(stmt1, 1);
-                if (address && di)
-                {
-                    OIC_LOG_V(DEBUG, TAG, " %s %s", di, address);
-                    (discPayload)->baseURI = OICStrdup((char *)address);
-                    (discPayload)->sid = OICStrdup((char *)di);
-                }
-            }
-            OCDiscoveryPayloadAddNewResource(discPayload, resourcePayload);
-        }
-    }
-    return OC_STACK_OK;
-}
 #endif
index 148295f0057f88bde9c6fad11e94abc6a787a088..a4dfcc81311088f338f83cdeed0f1265c800f770 100644 (file)
@@ -55,6 +55,7 @@ using namespace std;
 namespace itst = iotivity::test;
 
 #define DEFAULT_CONTEXT_VALUE 0x99
+#define DEFAULT_MESSAGE_TYPE "application/json"
 
 //-----------------------------------------------------------------------------
 // Private variables
index 1cf84f05dd35989b5e77203877657aa834bda92b..50909ade45c4d0d028150d28edcef4f862ea950d 100644 (file)
@@ -20,8 +20,8 @@
 
 extern "C"
 {
-    #include "rd_server.h"
     #include "rd_client.h"
+    #include "rd_server.h"
     #include "ocstack.h"
     #include "logger.h"
     #include "oic_malloc.h"
@@ -62,7 +62,7 @@ std::chrono::seconds const SHORT_TEST_TIMEOUT = std::chrono::seconds(5);
 //-----------------------------------------------------------------------------
 // Callback functions
 //-----------------------------------------------------------------------------
-#ifdef RD_SERVER
+#if (defined(RD_SERVER) && defined(RD_CLIENT))
 static OCStackApplicationResult handleDiscoveryCB(__attribute__((unused))void *ctx,
                                                   __attribute__((unused)) OCDoHandle handle,
                                                   __attribute__((unused))
@@ -124,7 +124,7 @@ class RDTests : public testing::Test {
     }
 };
 
-#ifdef RD_SERVER
+#if (defined(RD_SERVER) && defined(RD_CLIENT))
 TEST_F(RDTests, CreateRDResource)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
@@ -134,7 +134,6 @@ TEST_F(RDTests, CreateRDResource)
     cbData.cb = &handleDiscoveryCB;;
     cbData.cd = NULL;
     cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
-
     EXPECT_EQ(OC_STACK_OK, OCRDDiscover(CT_ADAPTER_IP, &cbData, OC_LOW_QOS));
 
     EXPECT_EQ(OC_STACK_OK, OCRDStop());
index 3232dda0fec5a1ee26d42a98eec16ec2ca38af1d..6769fc19615e9be9df7871790bf63dafd52045a1 100644 (file)
@@ -599,6 +599,7 @@ OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins);
 */
 OCResourceHandle OCGetResourceHandleAtUri(const char *uri);
 
+
 #ifdef RD_SERVER
 /**
 * Search the RD database for queries.
index dc49851f0e3264f43d72ed967407d86e69b1f299..afeecc8809cdb84dcb65051c61dae136124c04a7 100755 (executable)
 #include "routingmanager.h"
 #endif
 
-#ifdef RD_SERVER
-#include "rd_database.h"
-#endif
-
 /// Module Name
 #define TAG "OIC_RI_RESOURCE"
 
diff --git a/resource/csdk/stack/src/oicresourcedirectory.c b/resource/csdk/stack/src/oicresourcedirectory.c
new file mode 100644 (file)
index 0000000..7e8e6b9
--- /dev/null
@@ -0,0 +1,269 @@
+//******************************************************************
+//
+// 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 a
+//
+//      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 <stdlib.h>
+#include <string.h>
+
+#ifdef RD_SERVER
+#include "sqlite3.h"
+#endif
+
+#include "octypes.h"
+#include "ocstack.h"
+#include "logger.h"
+#include "ocpayload.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#define TAG "OIC_RI_RESOURCEDIRECTORY"
+
+#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
+             TAG, #arg " is NULL"); return (retVal); } }
+
+#ifdef RD_SERVER
+
+#define RD_PATH "RD.db"
+
+static sqlite3 *gRDDB = NULL;
+
+static const uint8_t uri_index = 2;
+static const uint8_t p_index = 5;
+static const uint8_t mt_index = 7;
+static const uint8_t d_index = 8;
+
+static const uint8_t rt_value_index = 1;
+static const uint8_t rt_link_id_index = 2;
+
+static const uint8_t if_value_index = 1;
+static const uint8_t if_link_id_index = 2;
+
+#define VERIFY_SQLITE(arg) \
+if (SQLITE_OK != (arg)) \
+{ \
+    OIC_LOG_V(ERROR, TAG, "Error in " #arg ", Error Message: %s",  sqlite3_errmsg(gRDDB)); \
+    sqlite3_exec(gRDDB, "ROLLBACK", NULL, NULL, NULL); \
+    return OC_STACK_ERROR; \
+}
+
+static void errorCallback(void *arg, int errCode, const char *errMsg)
+{
+    OC_UNUSED(arg);
+    OC_UNUSED(errCode);
+    OC_UNUSED(errMsg);
+    OIC_LOG_V(ERROR, TAG, "SQLLite Error: %s : %d", errMsg, errCode);
+}
+
+static OCStackResult initializeDatabase(const char *path)
+{
+    if (SQLITE_OK == sqlite3_config(SQLITE_CONFIG_LOG, errorCallback))
+    {
+        OIC_LOG_V(INFO, TAG, "SQLite debugging log initialized.");
+    }
+
+    sqlite3_open_v2(!path ? RD_PATH : path, &gRDDB, SQLITE_OPEN_READONLY, NULL);
+    if (!gRDDB)
+    {
+        return OC_STACK_ERROR;
+    }
+    return OC_STACK_OK;
+}
+
+static OCStackResult appendStringLL(OCStringLL **type, const unsigned char *value)
+{
+    OCStringLL *temp= (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+    if (!temp)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+    temp->value = OICStrdup((char *)value);
+    if (!temp->value)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+    temp->next = NULL;
+
+    if (!*type)
+    {
+        *type = temp;
+    }
+    else
+    {
+        OCStringLL *tmp = *type;
+        for (; tmp->next; tmp = tmp->next);
+        tmp->next = temp;
+    }
+    return OC_STACK_OK;
+}
+
+OCStackResult OCRDDatabaseCheckResources(const char *interfaceType, const char *resourceType,
+    OCDiscoveryPayload *discPayload)
+{
+    if (initializeDatabase(NULL) != OC_STACK_OK)
+    {
+        return OC_STACK_INTERNAL_SERVER_ERROR;
+    }
+    if (!interfaceType && !resourceType)
+    {
+        return OC_STACK_INVALID_QUERY;
+    }
+    OCResourcePayload *resourcePayload = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
+    if (!resourcePayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    if (resourceType)
+    {
+        sqlite3_stmt *stmt = 0;
+        const char *input = "SELECT * FROM RD_DEVICE_LINK_LIST INNER JOIN RD_LINK_RT ON " \
+        "RD_DEVICE_LINK_LIST.INS=RD_LINK_RT.LINK_ID WHERE RD_LINK_RT.rt LIKE ? ";
+
+        VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, -1, &stmt, NULL));
+        VERIFY_SQLITE(sqlite3_bind_text(stmt, 1, resourceType, strlen(resourceType) + 1, SQLITE_STATIC));
+
+        int res = sqlite3_step (stmt);
+        if (res == SQLITE_ROW || res == SQLITE_DONE)
+        {
+            int id = sqlite3_column_int(stmt, 0);
+            const unsigned char *uri = sqlite3_column_text(stmt, uri_index - 1);
+            int bitmap = sqlite3_column_int(stmt, p_index - 1);
+            int deviceId = sqlite3_column_int(stmt, d_index - 1);
+            OIC_LOG_V(DEBUG, TAG, " %s %d", uri, deviceId);
+            resourcePayload->uri = OICStrdup((char *)uri);
+            if (!resourcePayload->uri)
+            {
+                OCDiscoveryResourceDestroy(resourcePayload);
+                return OC_STACK_NO_MEMORY;
+            }
+            res = sqlite3_reset(stmt);
+            VERIFY_SQLITE(res);
+
+            sqlite3_stmt *stmtRT = 0;
+            const char *rt = "SELECT rt FROM RD_LINK_RT WHERE LINK_ID=?";
+            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, rt, -1, &stmtRT, NULL));
+            VERIFY_SQLITE(sqlite3_bind_int(stmtRT, 1, id));
+            while (SQLITE_ROW == sqlite3_step(stmtRT))
+            {
+                const unsigned char *rt1 = sqlite3_column_text(stmtRT, (rt_value_index - 1));
+                appendStringLL(&resourcePayload->types, rt1);
+            }
+
+            sqlite3_stmt *stmtIF = 0;
+            const char *itf = "SELECT if FROM RD_LINK_IF WHERE LINK_ID=?";
+            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, itf, -1, &stmtIF, NULL));
+            VERIFY_SQLITE(sqlite3_bind_int(stmtIF, 1, id));
+            while (SQLITE_ROW == sqlite3_step(stmtIF))
+            {
+                const unsigned char *itf = sqlite3_column_text(stmtIF, (if_value_index - 1));
+                appendStringLL(&resourcePayload->interfaces, itf);
+            }
+
+            resourcePayload->bitmap = bitmap & (OC_OBSERVABLE | OC_DISCOVERABLE);
+            resourcePayload->secure = (bitmap & OC_SECURE) != 0;
+
+            const char *address = "SELECT di, address FROM RD_DEVICE_LIST INNER JOIN RD_DEVICE_LINK_LIST ON " \
+            "RD_DEVICE_LINK_LIST.DEVICE_ID = RD_DEVICE_LIST.ID WHERE RD_DEVICE_LINK_LIST.DEVICE_ID=?";
+
+            sqlite3_stmt *stmt1 = 0;
+            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, address, -1, &stmt1, NULL));
+            VERIFY_SQLITE(sqlite3_bind_int(stmt1, 1, deviceId));
+            // TODO: Right now, we have a bug where discovery payload can only send one device information.
+            res = sqlite3_step(stmt1);
+            if (res == SQLITE_ROW || res == SQLITE_DONE)
+            {
+                const unsigned char *di = sqlite3_column_text(stmt1, 0);
+                const unsigned char *address = sqlite3_column_text(stmt1, 1);
+                OIC_LOG_V(DEBUG, TAG, " %s %s", di, address);
+                (discPayload)->baseURI = OICStrdup((char *)address);
+                (discPayload)->sid = OICStrdup((char *)di);
+            }
+            OCDiscoveryPayloadAddNewResource(discPayload, resourcePayload);
+        }
+    }
+    if (interfaceType)
+    {
+        sqlite3_stmt *stmt = 0;
+        const char *input = "SELECT * FROM RD_DEVICE_LINK_LIST INNER JOIN RD_LINK_IF ON " \
+        "RD_DEVICE_LINK_LIST.INS=RD_LINK_IF.LINK_ID WHERE RD_LINK_IF.if LIKE ? ";
+
+        VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, input, -1, &stmt, NULL));
+        VERIFY_SQLITE(sqlite3_bind_text(stmt, 1, interfaceType, strlen(interfaceType) + 1, SQLITE_STATIC));
+
+        int res = sqlite3_step (stmt);
+        if (res == SQLITE_ROW || res == SQLITE_DONE)
+        {
+            int id = sqlite3_column_int(stmt, 0);
+            const unsigned char *uri = sqlite3_column_text(stmt, uri_index - 1);
+            int bitmap = sqlite3_column_int(stmt, p_index - 1);
+            int deviceId = sqlite3_column_int(stmt, d_index - 1);
+            OIC_LOG_V(DEBUG, TAG, " %s %d", uri, deviceId);
+            resourcePayload->uri = OICStrdup((char *)uri);
+            if (!resourcePayload->uri)
+            {
+                OCDiscoveryResourceDestroy(resourcePayload);
+                return OC_STACK_NO_MEMORY;
+            }
+            VERIFY_SQLITE(sqlite3_reset(stmt));
+
+            sqlite3_stmt *stmtRT = 0;
+            const char *rt = "SELECT rt FROM RD_LINK_RT WHERE LINK_ID=?";
+            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, rt, -1, &stmtRT, NULL));
+            VERIFY_SQLITE(sqlite3_bind_int(stmtRT, 1, id));
+            while (SQLITE_ROW == sqlite3_step(stmtRT))
+            {
+                const unsigned char *rt1 = sqlite3_column_text(stmtRT, (rt_value_index - 1));
+                appendStringLL(&resourcePayload->types, rt1);
+            }
+
+            sqlite3_stmt *stmtIF = 0;
+            const char *itf = "SELECT if FROM RD_LINK_IF WHERE LINK_ID=?";
+            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, itf, -1, &stmtIF, NULL));
+            VERIFY_SQLITE(sqlite3_bind_int(stmtIF, 1, id));
+            while (SQLITE_ROW == sqlite3_step (stmtIF))
+            {
+                const unsigned char *itf = sqlite3_column_text(stmtIF, (if_value_index - 1));
+                appendStringLL(&resourcePayload->interfaces, itf);
+            }
+
+            resourcePayload->bitmap = bitmap & (OC_OBSERVABLE | OC_DISCOVERABLE);
+            resourcePayload->secure = ((bitmap & OC_SECURE) != 0);
+
+            const char *address = "SELECT di, address FROM RD_DEVICE_LIST INNER JOIN RD_DEVICE_LINK_LIST ON " \
+            "RD_DEVICE_LINK_LIST.DEVICE_ID = RD_DEVICE_LIST.ID WHERE RD_DEVICE_LINK_LIST.DEVICE_ID=?";
+
+            sqlite3_stmt *stmt1 = 0;
+            VERIFY_SQLITE(sqlite3_prepare_v2(gRDDB, address, -1, &stmt1, NULL));
+            VERIFY_SQLITE(sqlite3_bind_int(stmt1, 1, deviceId));
+
+            res = sqlite3_step(stmt1);
+            if (res == SQLITE_ROW || res == SQLITE_DONE)
+            {
+                const unsigned char *di = sqlite3_column_text(stmt1, 0);
+                const unsigned char *address = sqlite3_column_text(stmt1, 1);
+                OIC_LOG_V(DEBUG, TAG, " %s %s", di, address);
+                (discPayload)->baseURI = OICStrdup((char *)address);
+                (discPayload)->sid = OICStrdup((char *)di);
+            }
+            OCDiscoveryPayloadAddNewResource(discPayload, resourcePayload);
+        }
+    }
+    return OC_STACK_OK;
+}
+#endif