Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / provisioningdatabasemanager.c
index e50b5f8..80b3eb2 100644 (file)
@@ -47,7 +47,7 @@
 #define PDM_BIND_INDEX_THIRD 3
 
 #define PDM_CREATE_T_DEVICE_LIST "create table T_DEVICE_LIST(ID INTEGER PRIMARY KEY AUTOINCREMENT,\
-                                  UUID BLOB NOT NULL UNIQUE);"
+                                  UUID BLOB NOT NULL UNIQUE, STATE INT NOT NULL);"
 
 #define PDM_CREATE_T_DEVICE_LINK  "create table T_DEVICE_LINK_STATE(ID INT NOT NULL, ID2 INT NOT \
                                    NULL,STATE INT NOT NULL, PRIMARY KEY (ID, ID2));"
  * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
  */
 #define PDM_VERIFY_SQLITE_OK(tag, arg, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
-            { OC_LOG_V((logLevel), tag, "Error in " #arg ", Error Message: %s", \
+            { OIC_LOG_V((logLevel), tag, "Error in " #arg ", Error Message: %s", \
                sqlite3_errmsg(g_db)); 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_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_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_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"
-#define PDM_SQLITE_GET_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE ID = ?"
-#define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE ID = ? or ID2 = ?"
-#define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_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 = ?"
+#define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
+                                           (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_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
+                                                          WHERE ID = ? or ID2 = ?"
 
 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
   { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
 
 #define CHECK_PDM_INIT(tag) do{if(true != gInit)\
-  { OC_LOG(ERROR, (tag), "PDB is not initialized"); \
+  { OIC_LOG(ERROR, (tag), "PDB is not initialized"); \
     return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
 
 static sqlite3 *g_db = NULL;
@@ -98,11 +104,11 @@ static OCStackResult createDB(const char* path)
     result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LIST, NULL, NULL, NULL);
     PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
 
-    OC_LOG(INFO, TAG, "Created T_DEVICE_LIST");
+    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);
 
-    OC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
+    OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
     gInit = true;
     return OC_STACK_OK;
 }
@@ -149,7 +155,7 @@ void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
     (void) pArg;
     (void) iErrCode;
     (void) zMsg;
-    OC_LOG_V(DEBUG,TAG, "(%d) %s", iErrCode, zMsg);
+    OIC_LOG_V(DEBUG,TAG, "(%d) %s", iErrCode, zMsg);
 }
 
 OCStackResult PDMInit(const char *path)
@@ -158,7 +164,7 @@ OCStackResult PDMInit(const char *path)
     const char *dbPath = NULL;
     if (SQLITE_OK !=  sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
     {
-        OC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
+        OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
     }
 
     if (NULL == path || !*path)
@@ -172,7 +178,7 @@ OCStackResult PDMInit(const char *path)
     rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE, NULL);
     if (SQLITE_OK != rc)
     {
-        OC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
+        OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
         return createDB(dbPath);
     }
     gInit = true;
@@ -197,17 +203,20 @@ OCStackResult PDMAddDevice(const OicUuid_t *UUID)
     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_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_ACTIVE_STATE);
+    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+
     res = sqlite3_step(stmt);
     if (SQLITE_DONE != res)
     {
         if (SQLITE_CONSTRAINT == res)
         {
             //new OCStack result code
-            OC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
+            OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
             sqlite3_finalize(stmt);
             return OC_STACK_DUPLICATE_UUID;
         }
-        OC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
+        OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
         sqlite3_finalize(stmt);
         return OC_STACK_ERROR;
     }
@@ -216,6 +225,42 @@ OCStackResult PDMAddDevice(const OicUuid_t *UUID)
 }
 
 /**
+ * Function to check whether device is stale or not
+ */
+static OCStackResult isDeviceStale(const OicUuid_t *uuid, bool *result)
+{
+    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;
+    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);
+
+    res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, uuid, UUID_LENGTH, SQLITE_STATIC);
+    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+
+    bool retValue = false;
+    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)
+        {
+            OIC_LOG(INFO, TAG, "Device is stale");
+            retValue = true;
+        }
+    }
+    *result = retValue;
+    sqlite3_finalize(stmt);
+    return OC_STACK_OK;
+}
+
+/**
  *function to get Id for given UUID
  */
 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
@@ -228,11 +273,11 @@ static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
     res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
 
-    OC_LOG(DEBUG, TAG, "Binding Done");
+    OIC_LOG(DEBUG, TAG, "Binding Done");
     while (SQLITE_ROW == sqlite3_step(stmt))
     {
         int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
-        OC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
+        OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
         *id = tempId;
         sqlite3_finalize(stmt);
         return OC_STACK_OK;
@@ -250,7 +295,7 @@ OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID || NULL == result)
     {
-        OC_LOG(ERROR, TAG, "UUID or result is NULL");
+        OIC_LOG(ERROR, TAG, "UUID or result is NULL");
         return OC_STACK_INVALID_PARAM;
     }
     sqlite3_stmt *stmt = 0;
@@ -261,11 +306,11 @@ OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
     res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
 
-    OC_LOG(DEBUG, TAG, "Binding Done");
+    OIC_LOG(DEBUG, TAG, "Binding Done");
     bool retValue = false;
     while(SQLITE_ROW == sqlite3_step(stmt))
     {
-        OC_LOG(INFO, TAG, "Duplicated UUID");
+        OIC_LOG(INFO, TAG, "Duplicated UUID");
         retValue = true;
     }
 
@@ -296,7 +341,7 @@ static OCStackResult addlink(int id1, int id2)
 
     if (sqlite3_step(stmt) != SQLITE_DONE)
     {
-        OC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
+        OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
         sqlite3_finalize(stmt);
         return OC_STACK_ERROR;
     }
@@ -309,21 +354,46 @@ OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID1 || NULL == UUID2)
     {
-        OC_LOG(ERROR, TAG, "Invalid PARAM");
+        OIC_LOG(ERROR, TAG, "Invalid PARAM");
         return  OC_STACK_INVALID_PARAM;
     }
+
+    bool result = false;
+    if (OC_STACK_OK != isDeviceStale(UUID1, &result))
+    {
+        OIC_LOG(ERROR, TAG, "Internal error occured");
+        return OC_STACK_ERROR;
+    }
+    if (result)
+    {
+        OIC_LOG(ERROR, TAG, "UUID1:Stale device");
+        return OC_STACK_INVALID_PARAM;
+    }
+    result = false;
+    if (OC_STACK_OK != isDeviceStale(UUID2, &result))
+    {
+        OIC_LOG(ERROR, TAG, "Internal error occured");
+        return OC_STACK_ERROR;
+    }
+    if (result)
+    {
+        OIC_LOG(ERROR, TAG, "UUID2:Stale device");
+        return OC_STACK_INVALID_PARAM;
+    }
+
     int id1 = 0;
     if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
     int id2 = 0;
     if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
+
     ASCENDING_ORDER(id1, id2);
     return addlink(id1, id2);
 }
@@ -346,7 +416,7 @@ static OCStackResult removeLink(int id1, int id2)
 
     if (SQLITE_DONE != sqlite3_step(stmt))
     {
-        OC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
+        OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
         sqlite3_finalize(stmt);
         return OC_STACK_ERROR;
     }
@@ -359,21 +429,21 @@ OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID1 || NULL == UUID2)
     {
-        OC_LOG(ERROR, TAG, "Invalid PARAM");
+        OIC_LOG(ERROR, TAG, "Invalid PARAM");
         return  OC_STACK_INVALID_PARAM;
     }
 
     int id1 = 0;
     if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
 
     int id2 = 0;
     if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
     ASCENDING_ORDER(id1, id2);
@@ -393,7 +463,7 @@ static OCStackResult removeFromDeviceList(int id)
 
     if (sqlite3_step(stmt) != SQLITE_DONE)
     {
-        OC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
+        OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
         sqlite3_finalize(stmt);
         return OC_STACK_ERROR;
     }
@@ -411,14 +481,14 @@ OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
     int id = 0;
     if (OC_STACK_OK != getIdForUUID(UUID, &id))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
     begin();
     if(OC_STACK_OK != removeFromDeviceList(id))
     {
         rollback();
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_ERROR;
     }
     commit();
@@ -445,7 +515,7 @@ static OCStackResult updateLinkState(int id1, int id2, int state)
 
     if (SQLITE_DONE != sqlite3_step(stmt))
     {
-        OC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
+        OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
         sqlite3_finalize(stmt);
         return OC_STACK_ERROR;
     }
@@ -458,21 +528,21 @@ OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
     CHECK_PDM_INIT(TAG);
     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
     {
-        OC_LOG(ERROR, TAG, "Invalid PARAM");
+        OIC_LOG(ERROR, TAG, "Invalid PARAM");
         return  OC_STACK_INVALID_PARAM;
     }
 
     int id1 = 0;
     if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
 
     int id2 = 0;
     if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
     ASCENDING_ORDER(id1, id2);
@@ -485,7 +555,7 @@ OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
     CHECK_PDM_INIT(TAG);
     if (NULL != *uuidList)
     {
-        OC_LOG(ERROR, TAG, "Not null list will cause memory leak");
+        OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
         return OC_STACK_INVALID_PARAM;
     }
     sqlite3_stmt *stmt = 0;
@@ -494,16 +564,15 @@ OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
                               strlen(PDM_SQLITE_LIST_ALL_UUID) + 1, &stmt, NULL);
     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
 
-    int counter  = 0;
+    size_t counter  = 0;
     while (SQLITE_ROW == sqlite3_step(stmt))
     {
-
         const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
         OicUuid_t *uid = (OicUuid_t *)ptr;
         OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
         if (NULL == temp)
         {
-            OC_LOG_V(ERROR, TAG, "Memory allocation problem");
+            OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
             sqlite3_finalize(stmt);
             return OC_STACK_NO_MEMORY;
         }
@@ -516,7 +585,7 @@ OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
     return OC_STACK_OK;
 }
 
-static OCStackResult getUUIDforId(int id, OicUuid_t *uid)
+static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
 {
     sqlite3_stmt *stmt = 0;
     int res = 0;
@@ -531,30 +600,61 @@ static OCStackResult getUUIDforId(int id, OicUuid_t *uid)
     {
         const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
         memcpy(uid, ptr, sizeof(OicUuid_t));
+
+        int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
+        if(PDM_STALE_STATE == temp)
+        {
+            if(result)
+            {
+                *result = true;
+            }
+        }
+        else
+        {
+            if(result)
+            {
+                *result = false;
+            }
+        }
+        sqlite3_finalize(stmt);
+        return OC_STACK_OK;
     }
     sqlite3_finalize(stmt);
-    return OC_STACK_OK;
+    return OC_STACK_INVALID_PARAM;
 }
 
 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
 {
     CHECK_PDM_INIT(TAG);
-    if (NULL != *UUIDLIST)
+    if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
     {
-        OC_LOG(ERROR, TAG, "Not null list will cause memory leak");
         return OC_STACK_INVALID_PARAM;
     }
-    if (NULL == UUID)
+    if (NULL != *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);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "Internal error occured");
+        return OC_STACK_ERROR;
+    }
+    if (result)
+    {
+        OIC_LOG(ERROR, TAG, "Device is stale");
         return OC_STACK_INVALID_PARAM;
     }
     int id = 0;
     if (OC_STACK_OK != getIdForUUID(UUID, &id))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
 
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
@@ -567,7 +667,7 @@ OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
 
-    int counter  = 0;
+    size_t counter  = 0;
     while (SQLITE_ROW == sqlite3_step(stmt))
     {
         int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
@@ -576,17 +676,17 @@ OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST
         OicUuid_t temp = {{0,}};
         if (i1 != id)
         {
-            getUUIDforId(i1, &temp);
+            getUUIDforId(i1, &temp, NULL);
         }
         if (i2 != id)
         {
-            getUUIDforId(i2, &temp);
+            getUUIDforId(i2, &temp, NULL);
         }
 
         OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
         if (NULL == tempNode)
         {
-            OC_LOG(ERROR, TAG, "No Memory");
+            OIC_LOG(ERROR, TAG, "No Memory");
             sqlite3_finalize(stmt);
             return OC_STACK_NO_MEMORY;
         }
@@ -604,7 +704,7 @@ OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *num
     CHECK_PDM_INIT(TAG);
     if (NULL != *staleDevList)
     {
-        OC_LOG(ERROR, TAG, "Not null list will cause memory leak");
+        OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -617,20 +717,20 @@ OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *num
     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_STALE_STATE);
     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
 
-    int counter  = 0;
+    size_t counter  = 0;
     while (SQLITE_ROW == sqlite3_step(stmt))
     {
         int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
         int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
         OicUuid_t temp1 = {{0,}};
         OicUuid_t temp2 = {{0,}};;
-        getUUIDforId(i1, &temp1);
-        getUUIDforId(i2, &temp2);
+        getUUIDforId(i1, &temp1, NULL);
+        getUUIDforId(i2, &temp2, NULL);
 
         OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
         if (NULL == tempNode)
         {
-            OC_LOG(ERROR, TAG, "No Memory");
+            OIC_LOG(ERROR, TAG, "No Memory");
             sqlite3_finalize(stmt);
             return OC_STACK_NO_MEMORY;
         }
@@ -691,13 +791,37 @@ OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
     int id2 = 0;
     if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
         return OC_STACK_INVALID_PARAM;
     }
 
     if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
     {
-        OC_LOG(ERROR, TAG, "Requested value not found");
+        OIC_LOG(ERROR, TAG, "Requested value not found");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    bool isStale = false;
+    if (OC_STACK_OK != isDeviceStale(uuidOfDevice1, &isStale))
+    {
+        OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
+        return OC_STACK_ERROR;
+    }
+    if (isStale)
+    {
+        OIC_LOG(ERROR, TAG, "uuidOfDevice1:Device is stale");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    isStale = false;
+    if (OC_STACK_OK != isDeviceStale(uuidOfDevice2, &isStale))
+    {
+        OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
+        return OC_STACK_ERROR;
+    }
+    if (isStale)
+    {
+        OIC_LOG(ERROR, TAG, "uuidOfDevice2:Device is stale");
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -718,10 +842,94 @@ OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
     bool ret = false;
     while(SQLITE_ROW == sqlite3_step(stmt))
     {
-        OC_LOG(INFO, TAG, "Link already exists between devices");
+        OIC_LOG(INFO, TAG, "Link already exists between devices");
         ret = true;
     }
     sqlite3_finalize(stmt);
     *result = ret;
     return OC_STACK_OK;
 }
+
+static OCStackResult updateDeviceState(const OicUuid_t *uuid, int state)
+{
+    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);
+
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
+    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+
+    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 (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);
+    return OC_STACK_OK;
+}
+
+static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
+{
+    sqlite3_stmt *stmt = 0;
+    int res = 0 ;
+
+    int id = 0;
+    if (OC_STACK_OK != getIdForUUID(devUuid, &id))
+    {
+        OIC_LOG(ERROR, TAG, "Requested value not found");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    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);
+
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
+    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
+    PDM_VERIFY_SQLITE_OK(TAG, res, 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);
+    return OC_STACK_OK;
+}
+
+OCStackResult PDMSetDeviceStale(const OicUuid_t* uuidOfDevice)
+{
+    CHECK_PDM_INIT(TAG);
+    if (NULL == uuidOfDevice)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid PARAM");
+        return  OC_STACK_INVALID_PARAM;
+    }
+    begin();
+    OCStackResult res = updateLinkForStaleDevice(uuidOfDevice);
+    if (OC_STACK_OK != res)
+    {
+        rollback();
+        OIC_LOG(ERROR, TAG, "unable to update links");
+        return res;
+    }
+    res = updateDeviceState(uuidOfDevice, PDM_STALE_STATE);
+    if (OC_STACK_OK != res)
+    {
+        rollback();
+        OIC_LOG(ERROR, TAG, "unable to update device state");
+        return res;
+    }
+    commit();
+    return OC_STACK_OK;
+}