Tracking OTM state on client side
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / provisioningdatabasemanager.c
index 80b3eb2..c774b76 100644 (file)
 #include "pmutility.h"
 #include "oic_string.h"
 #include "utlist.h"
+#include "srmutility.h"
 
 
 #define DB_FILE "PDM.db"
 
-#define TAG "PDM"
-
-#define PDM_STALE_STATE 1
-#define PDM_ACTIVE_STATE 0
+#define TAG "OIC_PDM"
 
 #define PDM_FIRST_INDEX 0
 #define PDM_SECOND_INDEX 1
@@ -46,6 +44,8 @@
 #define PDM_BIND_INDEX_SECOND 2
 #define PDM_BIND_INDEX_THIRD 3
 
+#define HEX_UUID_STR_LENGTH (UUID_LENGTH*2 + 4)
+
 #define PDM_CREATE_T_DEVICE_LIST "create table T_DEVICE_LIST(ID INTEGER PRIMARY KEY AUTOINCREMENT,\
                                   UUID BLOB NOT NULL UNIQUE, STATE INT NOT NULL);"
 
  * Macro to verify sqlite success.
  * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
  */
-#define PDM_VERIFY_SQLITE_OK(tag, arg, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
+#define PDM_VERIFY_SQLITE_OK(tag, arg, stmt, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
             { OIC_LOG_V((logLevel), tag, "Error in " #arg ", Error Message: %s", \
-               sqlite3_errmsg(g_db)); return retValue; }}while(0)
+               sqlite3_errmsg(g_db)); sqlite3_finalize(stmt); return retValue; }}while(0)
+
 
 #define PDM_SQLITE_TRANSACTION_BEGIN "BEGIN TRANSACTION;"
 #define PDM_SQLITE_TRANSACTION_COMMIT "COMMIT;"
 #define PDM_SQLITE_TRANSACTION_ROLLBACK "ROLLBACK;"
 #define PDM_SQLITE_GET_STALE_INFO "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE STATE = ?"
 #define PDM_SQLITE_INSERT_T_DEVICE_LIST "INSERT INTO T_DEVICE_LIST VALUES(?,?,?)"
-#define PDM_SQLITE_GET_ID "SELECT ID FROM T_DEVICE_LIST WHERE UUID like ?"
+#define PDM_SQLITE_GET_ID "SELECT ID FROM T_DEVICE_LIST WHERE UUID = "
+#define PDM_SQLITE_GET_ID_SIZE (int)sizeof(PDM_SQLITE_GET_ID)
 #define PDM_SQLITE_INSERT_LINK_DATA "INSERT INTO T_DEVICE_LINK_STATE VALUES(?,?,?)"
 #define PDM_SQLITE_DELETE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? and ID2 = ?"
 #define PDM_SQLITE_DELETE_DEVICE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? or ID2 = ?"
 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST  WHERE ID = ?"
+#define PDM_SQLITE_DELETE_DEVICE_WITH_STATE "DELETE FROM T_DEVICE_LIST  WHERE STATE= ?"
 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ?  WHERE ID = ? and ID2 = ?"
 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
                                            (ID = ? or ID2 = ?) and state = 0"
 #define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
                                           ID = ? and ID2 = ? and state = 0"
-#define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ?  WHERE UUID like ?"
-#define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID like ?"
+#define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ? WHERE UUID = "
+#define PDM_SQLITE_UPDATE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_UPDATE_DEVICE)
+#define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID = "
+#define PDM_SQLITE_GET_DEVICE_STATUS_SIZE (int)sizeof(PDM_SQLITE_GET_DEVICE_STATUS)
 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
                                                           WHERE ID = ? or ID2 = ?"
+#define OTM_CREATE_TABLE "CREATE TABLE IF NOT EXISTS otm(\
+id INTEGER PRIMARY KEY AUTOINCREMENT,\
+owner TEXT,\
+uuid TEXT NOT NULL UNIQUE,\
+state INT DEFAULT(1) NOT NULL,\
+time TIMESTAMP DEFAULT(datetime(\'now\',\'localtime\')) NOT NULL);"
+
+#define OTM_INSERT "INSERT INTO otm(owner,uuid) VALUES(?,?)"
+#define OTM_UPDATE "UPDATE otm SET state=? WHERE uuid=?"
+#define OTM_GET_STATE "SELECT state FROM otm WHERE uuid=?"
 
 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
   { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
@@ -96,20 +111,28 @@ static bool gInit = false;  /* Only if we can open sqlite db successfully, gInit
  */
 static OCStackResult createDB(const char* path)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
 
     int result = 0;
     result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, result, NULL, ERROR, OC_STACK_ERROR);
 
     result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LIST, NULL, NULL, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, result, NULL, ERROR, OC_STACK_ERROR);
 
     OIC_LOG(INFO, TAG, "Created T_DEVICE_LIST");
     result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LINK, NULL, NULL, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, result, NULL, ERROR, OC_STACK_ERROR);
 
     OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
+
+    result = sqlite3_exec(g_db, OTM_CREATE_TABLE, NULL, NULL, NULL);
+    PDM_VERIFY_SQLITE_OK(TAG, result, NULL, ERROR, OC_STACK_ERROR);
+
     gInit = true;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
     return OC_STACK_OK;
 }
 
@@ -121,7 +144,7 @@ static OCStackResult begin()
 {
     int res = 0;
     res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
     return OC_STACK_OK;
 }
 
@@ -132,7 +155,7 @@ static OCStackResult commit()
 {
     int res = 0;
     res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
     return OC_STACK_OK;
 }
 
@@ -143,11 +166,47 @@ static OCStackResult rollback()
 {
     int res = 0;
     res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
     return OC_STACK_OK;
 }
 
 /**
+ * Function to convert UUID into hex representation
+ */
+static bool convertUuidToHexString(const OicUuid_t* uuidOfDevice, char* uuidHexString)
+{
+    if(NULL == uuidOfDevice || NULL == uuidHexString)
+    {
+        OIC_LOG(ERROR, TAG, "convertUuidToHexString : Invalid param");
+        return false;
+    }
+
+    char *strUUID = NULL;
+    OCStackResult ret = ConvertUuidToStr(uuidOfDevice, &strUUID);
+    if(OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "SendDeleteCredentialRequest : Failed to canonical UUID encoding");
+        return OC_STACK_ERROR;
+
+    }
+    char* headPtr = strUUID;
+    strncat(uuidHexString, "x'",2);
+    while(('\0' != *headPtr))
+    {
+        char tmp = *headPtr;
+        if('-' != tmp)
+        {
+            strncat(uuidHexString, &tmp,1);
+        }
+        headPtr++;
+    }
+    strncat(uuidHexString, "'",1);
+
+    OICFree(strUUID);
+    return true;
+}
+
+/**
  * Error log callback called by SQLite stack in case of error
  */
 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
@@ -155,11 +214,13 @@ void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
     (void) pArg;
     (void) iErrCode;
     (void) zMsg;
-    OIC_LOG_V(DEBUG,TAG, "(%d) %s", iErrCode, zMsg);
+    OIC_LOG_V(DEBUG,TAG, "%s : (%d) %s", __func__, iErrCode, zMsg);
 }
 
 OCStackResult PDMInit(const char *path)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     int rc;
     const char *dbPath = NULL;
     if (SQLITE_OK !=  sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
@@ -179,84 +240,212 @@ OCStackResult PDMInit(const char *path)
     if (SQLITE_OK != rc)
     {
         OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
-        return createDB(dbPath);
+        sqlite3_close(g_db);
+        OCStackResult ret = createDB(dbPath);
+        if (OC_STACK_OK != ret)
+        {
+            sqlite3_close(g_db);
+        }
+        return ret;
     }
+
+    rc = sqlite3_exec(g_db, OTM_CREATE_TABLE, NULL, NULL, NULL);
+    PDM_VERIFY_SQLITE_OK(TAG, rc, NULL, ERROR, OC_STACK_ERROR);
+
     gInit = true;
+
+    /*
+     * Remove PDM_DEVICE_INIT status devices.
+     * PDM_DEVICE_INIT means that the OTM process is in progress.
+     * PDM_DEVICE_INIT state device can be existed when the program is terminated during the OTM process in progress.
+     * For this reason, PDM_DEVICE_INIT devices should be removed at PDM initialization time.
+     */
+    if(OC_STACK_OK != PDMDeleteDeviceWithState(PDM_DEVICE_INIT))
+    {
+        OIC_LOG_V(WARNING, TAG, "Failed to delete init state devices.");
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
     return OC_STACK_OK;
 }
 
-
-OCStackResult PDMAddDevice(const OicUuid_t *UUID)
+OCStackResult OTMStart(const OicUuid_t *uuid, const OicUuid_t *owner)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
-    if (NULL == UUID)
+
+    if (NULL == uuid || NULL == owner)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
     sqlite3_stmt *stmt = 0;
     int res =0;
-    res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
-                              strlen(PDM_SQLITE_INSERT_T_DEVICE_LIST) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    char *uuidStr = NULL;
+    OCStackResult ret = OC_STACK_OK;
 
-    res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    res = sqlite3_prepare_v2(g_db, OTM_INSERT, strlen(OTM_INSERT) + 1, &stmt, NULL);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
+
+    ConvertUuidToStr(owner, &uuidStr);
+
+    res = sqlite3_bind_text(stmt, 1, uuidStr, strlen(uuidStr), SQLITE_TRANSIENT);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
 
-    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_ACTIVE_STATE);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    OICFree(uuidStr);
+    uuidStr = NULL;
+    ConvertUuidToStr(uuid, &uuidStr);
+
+    res = sqlite3_bind_text(stmt, 2, uuidStr, strlen(uuidStr), SQLITE_TRANSIENT);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
+
+    OICFree(uuidStr);
 
     res = sqlite3_step(stmt);
     if (SQLITE_DONE != res)
     {
         if (SQLITE_CONSTRAINT == res)
         {
-            //new OCStack result code
-            OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
-            sqlite3_finalize(stmt);
-            return OC_STACK_DUPLICATE_UUID;
+            int state;
+            if(OC_STACK_OK == OTMGetState(uuid, &state) && 1 == state)
+            {
+                OIC_LOG_V(WARNING, TAG, "%s OTM already started", __func__);
+                ret = OC_STACK_DUPLICATE_UUID;
+            }
         }
-        OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
+        else
+        {
+            ret = OC_STACK_ERROR;
+        }
+    }
+    sqlite3_finalize(stmt);
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_OK;
+}
+
+OCStackResult OTMSetState(const OicUuid_t *uuid, int state)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    CHECK_PDM_INIT(TAG);
+
+    if (NULL == uuid)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    sqlite3_stmt *stmt = 0;
+    int res = 0 ;
+    char *uuidStr = NULL;
+
+    res = sqlite3_prepare_v2(g_db, OTM_UPDATE, strlen(OTM_UPDATE) + 1, &stmt, NULL);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
+
+    res = sqlite3_bind_int(stmt, 1, state);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
+
+    ConvertUuidToStr(uuid, &uuidStr);
+
+    res = sqlite3_bind_text(stmt, 2, uuidStr, strlen(uuidStr), SQLITE_TRANSIENT);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
+
+    OICFree(uuidStr);
+
+    if (SQLITE_DONE != sqlite3_step(stmt))
+    {
+        OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
         sqlite3_finalize(stmt);
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
-/**
- * Function to check whether device is stale or not
- */
-static OCStackResult isDeviceStale(const OicUuid_t *uuid, bool *result)
+OCStackResult OTMStop(const OicUuid_t *uuid)
 {
-    if (NULL == uuid || NULL == result)
+    return OTMSetState(uuid, 2);
+}
+
+OCStackResult OTMGetState(const OicUuid_t *uuid, int *state)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    CHECK_PDM_INIT(TAG);
+
+    if (NULL == uuid)
     {
-        OIC_LOG(ERROR, TAG, "UUID or result is NULL");
         return OC_STACK_INVALID_PARAM;
     }
 
     sqlite3_stmt *stmt = 0;
     int res = 0;
-    res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_STATUS, strlen(PDM_SQLITE_GET_DEVICE_STATUS) + 1,
-                              &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    char *uuidStr = NULL;
+    OCStackResult ret = OC_STACK_ERROR;
 
-    res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, uuid, UUID_LENGTH, SQLITE_STATIC);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    res = sqlite3_prepare_v2(g_db, OTM_GET_STATE, strlen(OTM_GET_STATE) + 1, &stmt, NULL);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
 
-    bool retValue = false;
-    while(SQLITE_ROW == sqlite3_step(stmt))
+    ConvertUuidToStr(uuid, &uuidStr);
+    res = sqlite3_bind_text(stmt, 1, uuidStr, strlen(uuidStr), SQLITE_TRANSIENT);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
+
+    while (SQLITE_ROW == sqlite3_step(stmt))
     {
-        int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
-        OIC_LOG_V(DEBUG, TAG, "Stale state is %d", tempStaleStateFromDb);
-        if (PDM_STALE_STATE == tempStaleStateFromDb)
+        *state = sqlite3_column_int(stmt, 1);
+        OIC_LOG_V(DEBUG, TAG, "%s state is %d", uuidStr, *state);
+        ret = OC_STACK_OK;
+        break;
+    }
+
+    OICFree(uuidStr);
+    sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return ret;
+}
+
+OCStackResult PDMAddDevice(const OicUuid_t *UUID)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    CHECK_PDM_INIT(TAG);
+    if (NULL == UUID)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    sqlite3_stmt *stmt = 0;
+    int res =0;
+    res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
+                              strlen(PDM_SQLITE_INSERT_T_DEVICE_LIST) + 1, &stmt, NULL);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
+
+    res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
+
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_INIT);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
+
+    res = sqlite3_step(stmt);
+    if (SQLITE_DONE != res)
+    {
+        if (SQLITE_CONSTRAINT == res)
         {
-            OIC_LOG(INFO, TAG, "Device is stale");
-            retValue = true;
+            //new OCStack result code
+            OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
+            sqlite3_finalize(stmt);
+            return OC_STACK_DUPLICATE_UUID;
         }
+        OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
+        sqlite3_finalize(stmt);
+        return OC_STACK_ERROR;
     }
-    *result = retValue;
     sqlite3_finalize(stmt);
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
@@ -265,24 +454,39 @@ static OCStackResult isDeviceStale(const OicUuid_t *uuid, bool *result)
  */
 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
-    res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    char sqlStat[PDM_SQLITE_GET_ID_SIZE - 1 + HEX_UUID_STR_LENGTH];
+    char hexUUID[HEX_UUID_STR_LENGTH];
 
-    res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    memset(sqlStat, 0, sizeof(sqlStat));
+    strncpy(sqlStat, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE - 1);
+    memset(hexUUID, 0, sizeof(hexUUID));
+
+    if (!convertUuidToHexString(UUID, hexUUID))
+    {
+        return OC_STACK_ERROR;
+    }
+
+    strncpy(sqlStat + PDM_SQLITE_GET_ID_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
+    res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
-    OIC_LOG(DEBUG, TAG, "Binding Done");
     while (SQLITE_ROW == sqlite3_step(stmt))
     {
         int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
         OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
         *id = tempId;
         sqlite3_finalize(stmt);
+        OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
         return OC_STACK_OK;
     }
+
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
     return OC_STACK_INVALID_PARAM;
 }
 
@@ -291,6 +495,7 @@ static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
  */
 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
 
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID || NULL == result)
@@ -300,13 +505,22 @@ OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
     }
     sqlite3_stmt *stmt = 0;
     int res = 0;
-    res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    char sqlStat[PDM_SQLITE_GET_ID_SIZE - 1 + HEX_UUID_STR_LENGTH];
+    char hexUUID[HEX_UUID_STR_LENGTH];
 
-    res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    memset(sqlStat, 0, sizeof(sqlStat));
+    strncpy(sqlStat, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE - 1);
+    memset(hexUUID, 0, sizeof(hexUUID));
+
+    if (!convertUuidToHexString(UUID, hexUUID))
+    {
+        return OC_STACK_ERROR;
+    }
+
+    strncpy(sqlStat + PDM_SQLITE_GET_ID_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
+    res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
-    OIC_LOG(DEBUG, TAG, "Binding Done");
     bool retValue = false;
     while(SQLITE_ROW == sqlite3_step(stmt))
     {
@@ -316,6 +530,8 @@ OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
 
     sqlite3_finalize(stmt);
     *result = retValue;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
@@ -324,20 +540,22 @@ OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
  */
 static OCStackResult addlink(int id1, int id2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
                               strlen(PDM_SQLITE_INSERT_LINK_DATA) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
-    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_ACTIVE_STATE);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_ACTIVE);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     if (sqlite3_step(stmt) != SQLITE_DONE)
     {
@@ -346,11 +564,14 @@ static OCStackResult addlink(int id1, int id2)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID1 || NULL == UUID2)
     {
@@ -358,26 +579,27 @@ OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
         return  OC_STACK_INVALID_PARAM;
     }
 
-    bool result = false;
-    if (OC_STACK_OK != isDeviceStale(UUID1, &result))
+    PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
+    if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
     {
         OIC_LOG(ERROR, TAG, "Internal error occured");
         return OC_STACK_ERROR;
     }
-    if (result)
+    if (PDM_DEVICE_ACTIVE != state)
     {
-        OIC_LOG(ERROR, TAG, "UUID1:Stale device");
+        OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
         return OC_STACK_INVALID_PARAM;
     }
-    result = false;
-    if (OC_STACK_OK != isDeviceStale(UUID2, &result))
+
+    state = PDM_DEVICE_UNKNOWN;
+    if (OC_STACK_OK != PDMGetDeviceState(UUID2, &state))
     {
         OIC_LOG(ERROR, TAG, "Internal error occured");
         return OC_STACK_ERROR;
     }
-    if (result)
+    if (PDM_DEVICE_ACTIVE != state)
     {
-        OIC_LOG(ERROR, TAG, "UUID2:Stale device");
+        OIC_LOG_V(ERROR, TAG, "UUID2: Device state is not active : %d", state);
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -395,6 +617,7 @@ OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
     }
 
     ASCENDING_ORDER(id1, id2);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return addlink(id1, id2);
 }
 
@@ -403,16 +626,18 @@ OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
  */
 static OCStackResult removeLink(int id1, int id2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     int res = 0;
     sqlite3_stmt *stmt = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK, strlen(PDM_SQLITE_DELETE_LINK) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     if (SQLITE_DONE != sqlite3_step(stmt))
     {
@@ -421,11 +646,14 @@ static OCStackResult removeLink(int id1, int id2)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID1 || NULL == UUID2)
     {
@@ -447,19 +675,22 @@ OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
         return OC_STACK_INVALID_PARAM;
     }
     ASCENDING_ORDER(id1, id2);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return removeLink(id1, id2);
 }
 
 static OCStackResult removeFromDeviceList(int id)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
                               strlen(PDM_SQLITE_DELETE_DEVICE) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     if (sqlite3_step(stmt) != SQLITE_DONE)
     {
@@ -468,11 +699,14 @@ static OCStackResult removeFromDeviceList(int id)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID)
     {
@@ -492,26 +726,29 @@ OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
         return OC_STACK_ERROR;
     }
     commit();
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 
 static OCStackResult updateLinkState(int id1, int id2, int state)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0 ;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
                               strlen(PDM_SQLITE_UPDATE_LINK) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     if (SQLITE_DONE != sqlite3_step(stmt))
     {
@@ -520,11 +757,14 @@ static OCStackResult updateLinkState(int id1, int id2, int state)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
     {
@@ -546,12 +786,14 @@ OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
         return OC_STACK_INVALID_PARAM;
     }
     ASCENDING_ORDER(id1, id2);
-    return updateLinkState(id1, id2, PDM_STALE_STATE);
-
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return updateLinkState(id1, id2, PDM_DEVICE_STALE);
 }
 
 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL != *uuidList)
     {
@@ -562,7 +804,7 @@ OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
                               strlen(PDM_SQLITE_LIST_ALL_UUID) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     size_t counter  = 0;
     while (SQLITE_ROW == sqlite3_step(stmt))
@@ -582,19 +824,22 @@ OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
     }
     *numOfDevices = counter;
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
                               strlen(PDM_SQLITE_GET_UUID) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     while (SQLITE_ROW == sqlite3_step(stmt))
     {
@@ -602,7 +847,7 @@ static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
         memcpy(uid, ptr, sizeof(OicUuid_t));
 
         int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
-        if(PDM_STALE_STATE == temp)
+        if(PDM_DEVICE_STALE == temp)
         {
             if(result)
             {
@@ -620,11 +865,14 @@ static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
         return OC_STACK_OK;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_INVALID_PARAM;
 }
 
 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
     {
@@ -635,16 +883,16 @@ OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST
         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
         return OC_STACK_INVALID_PARAM;
     }
-    bool result = false;
-    OCStackResult ret = isDeviceStale(UUID, &result);
+    PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
+    OCStackResult ret = PDMGetDeviceState(UUID, &state);
     if (OC_STACK_OK != ret)
     {
         OIC_LOG(ERROR, TAG, "Internal error occured");
         return OC_STACK_ERROR;
     }
-    if (result)
+    if (PDM_DEVICE_ACTIVE != state)
     {
-        OIC_LOG(ERROR, TAG, "Device is stale");
+        OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
         return OC_STACK_INVALID_PARAM;
     }
     int id = 0;
@@ -659,13 +907,13 @@ OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
                               strlen(PDM_SQLITE_GET_LINKED_DEVICES) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     size_t counter  = 0;
     while (SQLITE_ROW == sqlite3_step(stmt))
@@ -696,11 +944,14 @@ OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST
     }
     *numOfDevices = counter;
      sqlite3_finalize(stmt);
+     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
      return OC_STACK_OK;
 }
 
 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL != *staleDevList)
     {
@@ -712,10 +963,10 @@ OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *num
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
                               strlen(PDM_SQLITE_GET_STALE_INFO) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
-    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_STALE_STATE);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_DEVICE_STALE);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     size_t counter  = 0;
     while (SQLITE_ROW == sqlite3_step(stmt))
@@ -741,20 +992,26 @@ OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *num
     }
     *numOfDevices = counter;
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMClose()
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     int res = 0;
     res = sqlite3_close(g_db);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     if(ptr)
     {
         OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
@@ -764,10 +1021,14 @@ void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
             OICFree(tmp1);
         }
     }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
 }
 
 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     if(ptr)
     {
         OCPairList_t *tmp1 = NULL,*tmp2=NULL;
@@ -777,11 +1038,15 @@ void PDMDestoryStaleLinkList(OCPairList_t* ptr)
             OICFree(tmp1);
         }
     }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
 }
 
 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
                                bool* result)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
     {
@@ -801,27 +1066,27 @@ OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
         return OC_STACK_INVALID_PARAM;
     }
 
-    bool isStale = false;
-    if (OC_STACK_OK != isDeviceStale(uuidOfDevice1, &isStale))
+    PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
+    if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
     {
         OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
         return OC_STACK_ERROR;
     }
-    if (isStale)
+    if (PDM_DEVICE_ACTIVE != state)
     {
-        OIC_LOG(ERROR, TAG, "uuidOfDevice1:Device is stale");
+        OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
         return OC_STACK_INVALID_PARAM;
     }
 
-    isStale = false;
-    if (OC_STACK_OK != isDeviceStale(uuidOfDevice2, &isStale))
+    state = PDM_DEVICE_UNKNOWN;
+    if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
     {
         OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
         return OC_STACK_ERROR;
     }
-    if (isStale)
+    if (PDM_DEVICE_ACTIVE != state)
     {
-        OIC_LOG(ERROR, TAG, "uuidOfDevice2:Device is stale");
+        OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -831,13 +1096,13 @@ OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
                               strlen(PDM_SQLITE_GET_DEVICE_LINKS) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     bool ret = false;
     while(SQLITE_ROW == sqlite3_step(stmt))
@@ -847,22 +1112,36 @@ OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
     }
     sqlite3_finalize(stmt);
     *result = ret;
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
-static OCStackResult updateDeviceState(const OicUuid_t *uuid, int state)
+static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    OIC_LOG_V(WARNING, TAG, "UUID is: %s", (char*) uuid);
+
     sqlite3_stmt *stmt = 0;
     int res = 0 ;
-    res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_DEVICE,
-                              strlen(PDM_SQLITE_UPDATE_DEVICE) + 1, &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    char sqlStat[PDM_SQLITE_UPDATE_DEVICE_SIZE - 1 + HEX_UUID_STR_LENGTH];
+    char hexUUID[HEX_UUID_STR_LENGTH];
 
-    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    memset(sqlStat, 0, sizeof(sqlStat));
+    strncpy(sqlStat, PDM_SQLITE_UPDATE_DEVICE, PDM_SQLITE_UPDATE_DEVICE_SIZE - 1);
+    memset(hexUUID, 0, sizeof(hexUUID));
 
-    res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, uuid, UUID_LENGTH, SQLITE_STATIC);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    if (!convertUuidToHexString(uuid, hexUUID))
+    {
+        return OC_STACK_ERROR;
+    }
+
+    strncpy(sqlStat + PDM_SQLITE_UPDATE_DEVICE_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
+    res = sqlite3_prepare_v2(g_db, sqlStat,
+                                  (int)sizeof(sqlStat), &stmt, NULL);
+
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     if (SQLITE_DONE != sqlite3_step(stmt))
     {
@@ -871,11 +1150,14 @@ static OCStackResult updateDeviceState(const OicUuid_t *uuid, int state)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0 ;
 
@@ -889,13 +1171,13 @@ static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
                               strlen(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE) + 1,
                                &stmt, NULL);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
-    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
 
     if (SQLITE_DONE != sqlite3_step(stmt))
     {
@@ -904,26 +1186,36 @@ static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
-OCStackResult PDMSetDeviceStale(const OicUuid_t* uuidOfDevice)
+OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    OCStackResult res = OC_STACK_ERROR;
+
     CHECK_PDM_INIT(TAG);
-    if (NULL == uuidOfDevice)
+    if (NULL == uuid)
     {
         OIC_LOG(ERROR, TAG, "Invalid PARAM");
         return  OC_STACK_INVALID_PARAM;
     }
     begin();
-    OCStackResult res = updateLinkForStaleDevice(uuidOfDevice);
-    if (OC_STACK_OK != res)
+
+    if(PDM_DEVICE_STALE == state)
     {
-        rollback();
-        OIC_LOG(ERROR, TAG, "unable to update links");
-        return res;
+        res = updateLinkForStaleDevice(uuid);
+        if (OC_STACK_OK != res)
+        {
+            rollback();
+            OIC_LOG(ERROR, TAG, "unable to update links");
+            return res;
+        }
     }
-    res = updateDeviceState(uuidOfDevice, PDM_STALE_STATE);
+
+    res = updateDeviceState(uuid, state);
     if (OC_STACK_OK != res)
     {
         rollback();
@@ -931,5 +1223,79 @@ OCStackResult PDMSetDeviceStale(const OicUuid_t* uuidOfDevice)
         return res;
     }
     commit();
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_OK;
+}
+
+OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    if (NULL == uuid || NULL == result)
+    {
+        OIC_LOG(ERROR, TAG, "UUID or result is NULL");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    sqlite3_stmt *stmt = 0;
+    int res = 0;
+    char sqlStat[PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1 + HEX_UUID_STR_LENGTH];
+    char hexUUID[HEX_UUID_STR_LENGTH];
+
+    memset(sqlStat, 0, sizeof(sqlStat));
+    strncpy(sqlStat, PDM_SQLITE_GET_DEVICE_STATUS, PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1);
+    memset(hexUUID, 0, sizeof(hexUUID));
+
+    if (!convertUuidToHexString(uuid, hexUUID))
+    {
+        return OC_STACK_ERROR;
+    }
+
+    strncpy(sqlStat + PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
+    res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
+
+    *result = PDM_DEVICE_UNKNOWN;
+    while(SQLITE_ROW == sqlite3_step(stmt))
+    {
+        int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
+        OIC_LOG_V(DEBUG, TAG, "Device state is %d", tempStaleStateFromDb);
+        *result = (PdmDeviceState_t)tempStaleStateFromDb;
+    }
+
+    sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return OC_STACK_OK;
+}
+
+OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    CHECK_PDM_INIT(TAG);
+    if (PDM_DEVICE_ACTIVE != state && PDM_DEVICE_STALE != state &&
+        PDM_DEVICE_INIT != state && PDM_DEVICE_UNKNOWN != state)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    sqlite3_stmt *stmt = 0;
+    int res =0;
+    res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE_WITH_STATE,
+                              strlen(PDM_SQLITE_DELETE_DEVICE_WITH_STATE) + 1, &stmt, NULL);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
+
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
+    PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
+
+    if (SQLITE_DONE != sqlite3_step(stmt))
+    {
+        OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
+        sqlite3_finalize(stmt);
+        return OC_STACK_ERROR;
+    }
+    sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }