Update PDM
authorChul Lee <chuls.lee@samsung.com>
Wed, 8 Mar 2017 23:13:39 +0000 (08:13 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Thu, 9 Mar 2017 03:59:09 +0000 (03:59 +0000)
This patch addresses the following exceptional cases :
 1. The PT terminates unexpectedly.
    - Start the OTM process
    - Device information will be changed to INIT state.
    - PT terminated while OTM.
    - Restart the PT process.
    - Retry the OTM process.
    * OTM start will be failed due to device info already save as INIT state.

  2. Timeout is occured PT side while OTM.
    - Start the OTM process
    - Device information will be changed to INIT state.
    - OTM timeout is occured at the application side.
    - PT retry the OTM.
    * OTM start will be failed due to device info already save as INIT state.

I've added defence code and
added cleanup API that can be used when timeout occurs.

Patch #1 : Initial upload
Patch #2 : Retrigger
Patch #3 : Fix the bug for incorrect PIN inputed while random PIN OxM.
Patch #4-5 : Retrigger
Patch #6 : minor bug fix
Patch #7-8 : Retrigger
Patch #9 : Fix the incorrect log
Patch #10 : Retrigger
Patch #12 : Retrigger

Change-Id: I7781c0d864db6fdac93fa41acbcbf1ac123d15da
Signed-off-by: Chul Lee <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/16187
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/17309

resource/csdk/security/provisioning/include/internal/provisioningdatabasemanager.h
resource/csdk/security/provisioning/include/ocprovisioningmanager.h
resource/csdk/security/provisioning/sample/provisioningclient.c
resource/csdk/security/provisioning/sample/subownerclient.c
resource/csdk/security/provisioning/src/ocprovisioningmanager.c
resource/csdk/security/provisioning/src/ownershiptransfermanager.c [changed mode: 0755->0644]
resource/csdk/security/provisioning/src/provisioningdatabasemanager.c
resource/csdk/stack/octbstack_product_secured.def
resource/include/OCProvisioningManager.hpp
resource/provisioning/src/OCProvisioningManager.cpp

index dd1801b..9e8fbec 100644 (file)
@@ -114,6 +114,15 @@ OCStackResult PDMUnlinkDevices(const OicUuid_t *uuidOfDevice1, const OicUuid_t *
 OCStackResult PDMDeleteDevice(const OicUuid_t *uuidOfDevice);
 
 /**
+ * This method is used by OTM & PDM to remove device information with device state.
+ *
+ * @param[in] state device state to be removed.
+ *
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state);
+
+/**
  * This method is used by provisioning manager to get owned devices' Device IDs.
  *
  * @param[out] uuidList information about the list of owned devices' uuids.
index 9bc129b..1421f39 100644 (file)
@@ -45,6 +45,14 @@ extern "C" {
 OCStackResult OCInitPM(const char* dbPath);\r
 \r
 /**\r
+ * API to cleanup PDM in case of timeout.\r
+ * It will remove the PDM_DEVICE_INIT state devices from PDM.\r
+ *\r
+ * @return OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCPDMCleanupForTimeout();\r
+\r
+/**\r
  * The function is responsible for discovery of owned/unowned device is specified endpoint/deviceID.\r
  * It will return the found device even though timeout is not exceeded.\r
  *\r
index 0824b2f..58fa2be 100644 (file)
@@ -2261,6 +2261,11 @@ static int waitCallbackRet(void)
         }
     }
 
+    if(!g_doneCB)
+    {
+        OCPDMCleanupForTimeout();
+    }
+
     return 0;
 }
 
index ef26f9c..e3e0a66 100644 (file)
@@ -867,6 +867,11 @@ static int waitCallbackRet(void)
         }
     }
 
+    if(!g_doneCB)
+    {
+        OCPDMCleanupForTimeout();
+    }
+
     return 0;
 }
 
index 31df69b..4adc3f6 100644 (file)
@@ -81,6 +81,11 @@ OCStackResult OCInitPM(const char* dbPath)
     return PDMInit(dbPath);
 }
 
+OCStackResult OCPDMCleanupForTimeout()
+{
+    return PDMDeleteDeviceWithState(PDM_DEVICE_INIT);
+}
+
 /**
  * The function is responsible for discovery of owned/unowned device is specified endpoint/deviceID.
  * And this function will only return the specified device's response.
old mode 100755 (executable)
new mode 100644 (file)
index 299496b..9c27e04
@@ -333,6 +333,14 @@ static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
  */
 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
 
+/*
+ * Internal function to setup & cleanup PDM to performing provisioning.
+ *
+ * @param[in] selectedDevice   selected device information to performing provisioning.
+ * @return  OC_STACK_OK on success
+ */
+static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice);
+
 /**
  * Function to update owner transfer mode
  *
@@ -656,6 +664,9 @@ static void OwnershipTransferSessionFailed(const CAEndpoint_t *endpoint,
         newDevDoxm->owned = false;
         otmCtx->attemptCnt++;
 
+        RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
+                         otmCtx->selectedDeviceInfo->securePort);
+
         // In order to re-start ownership transfer, device information should be deleted from PDM.
         OCStackResult res = PDMDeleteDevice(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
         if (OC_STACK_OK != res)
@@ -2109,84 +2120,131 @@ static OCStackResult GetAndVerifyDoxmResource(OTMContext_t* otmCtx)
     return res;
 }
 
-static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
+static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice)
 {
-    OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    char* strUuid = NULL;
     OCStackResult res = OC_STACK_INVALID_PARAM;
 
     VERIFY_NOT_NULL(TAG, selectedDevice, ERROR);
     VERIFY_NOT_NULL(TAG, selectedDevice->doxm, ERROR);
 
-    OTMContext_t* otmCtx = (OTMContext_t*)ctx;
-    otmCtx->selectedDeviceInfo = selectedDevice;
+    PdmDeviceState_t pdmState = PDM_DEVICE_UNKNOWN;
+    res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res);
+        return res;
+    }
 
-    //Checking duplication of Device ID.
-    bool isDuplicate = true;
-    res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
+    bool removeCredReq = false;
+    res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
     if (OC_STACK_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Internal error in PDMIsDuplicateDevice");
+        OIC_LOG(WARNING, TAG, "Failed to covert uuid to string");
         return res;
     }
-    if (isDuplicate)
+
+    if (PDM_DEVICE_UNKNOWN == pdmState && !selectedDevice->doxm->owned)
+    {
+        removeCredReq = true;
+    }
+    else if (PDM_DEVICE_ACTIVE == pdmState && !selectedDevice->doxm->owned)
     {
-        PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
-        res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &state);
+        OIC_LOG_V(WARNING, TAG, "Unowned device[%s] dectected from PDM.", strUuid);
+        OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", strUuid);
+        res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
         if(OC_STACK_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "Internal error in PDMGetDeviceState");
-            SetResult(otmCtx, res);
-            return res;
+            OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", strUuid);
+            goto exit;
         }
 
-        char* strUuid = NULL;
-        res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
-        if(OC_STACK_OK != res)
+        removeCredReq = true;
+    }
+
+    if (removeCredReq)
+    {
+        OIC_LOG_V(WARNING, TAG, "[%s]'s credential will be removed.", strUuid);
+        res = RemoveCredential(&selectedDevice->doxm->deviceID);
+        if (OC_STACK_RESOURCE_DELETED != res)
         {
-            OIC_LOG(ERROR, TAG, "Failed to convert UUID to str");
-            SetResult(otmCtx, res);
-            return res;
+            OIC_LOG_V(WARNING, TAG, "Can not find [%s]'s credential.", strUuid);
         }
+    }
 
-        if(PDM_DEVICE_STALE == state)
+    //Checking duplication of Device ID.
+    bool isDuplicate = true;
+    res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "Internal error in PDMIsDuplicateDevice : %d", res);
+        goto exit;
+    }
+
+    if (isDuplicate)
+    {
+        if (PDM_DEVICE_STALE == pdmState)
         {
             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
                                "device status will revert back to initial status.");
             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
-            if(OC_STACK_OK != res)
+            if (OC_STACK_OK != res)
             {
-                OIC_LOG(ERROR, TAG, "Internal error in PDMSetDeviceState");
-                OICFree(strUuid);
-                SetResult(otmCtx, res);
-                return res;
+                OIC_LOG_V(ERROR, TAG, "Internal error in PDMSetDeviceState : %d", res);
+                goto exit;
             }
         }
-        else if(PDM_DEVICE_INIT == state)
+        else if (PDM_DEVICE_INIT == pdmState)
         {
             OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
-            OICFree(strUuid);
-            SetResult(otmCtx, OC_STACK_DUPLICATE_REQUEST);
-            return OC_STACK_OK;
+            res = OC_STACK_DUPLICATE_REQUEST;
+            goto exit;
         }
         else
         {
             OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
-            OICFree(strUuid);
-            SetResult(otmCtx, OC_STACK_ERROR);
-            return OC_STACK_ERROR;
+            res = OC_STACK_ERROR;
+            goto exit;
         }
     }
     else
     {
         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
-        if(OC_STACK_OK != res)
+        if (OC_STACK_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "Internal error in PDMAddDevice");
-            SetResult(otmCtx, res);
-            return res;
+            OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res);
+            goto exit;
         }
     }
 
+exit:
+    OICFree(strUuid);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return res;
+}
+
+static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
+{
+    OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
+    OCStackResult res = OC_STACK_INVALID_PARAM;
+
+    VERIFY_NOT_NULL(TAG, selectedDevice, ERROR);
+    VERIFY_NOT_NULL(TAG, selectedDevice->doxm, ERROR);
+
+    OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+    otmCtx->selectedDeviceInfo = selectedDevice;
+
+    //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
+    res = SetupPDM(selectedDevice);
+    if(OC_STACK_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
+        SetResult(otmCtx, res);
+        return res;
+    }
+
     //Select the OxM to performing ownership transfer
     res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
                                           selectedDevice->doxm->oxmLen,
@@ -2194,7 +2252,7 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
                                           SUPER_OWNER);
     if(OC_STACK_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
+        OIC_LOG_V(ERROR, TAG, "Failed to select the provisioning method : %d", res);
         SetResult(otmCtx, res);
         return res;
     }
@@ -2219,7 +2277,7 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
     res = PostOwnerTransferModeToResource(otmCtx);
     if(OC_STACK_OK != res)
     {
-        OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
+        OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
         SetResult(otmCtx, res);
         return res;
     }
index 51e0b4d..608b0f3 100644 (file)
@@ -94,7 +94,7 @@ PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_DELETE_LINK);
 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST  WHERE ID = ?"
 #define PDM_SQLITE_DELETE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_DELETE_DEVICE)
 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_DELETE_DEVICE);
-
+#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_UPDATE_LINK_SIZE (int)sizeof(PDM_SQLITE_UPDATE_LINK)
 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_UPDATE_LINK);
@@ -146,6 +146,7 @@ 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);
@@ -160,6 +161,9 @@ static OCStackResult createDB(const char* path)
 
     OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
     gInit = true;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
     return OC_STACK_OK;
 }
 
@@ -205,11 +209,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))
@@ -232,12 +238,28 @@ OCStackResult PDMInit(const char *path)
         return createDB(dbPath);
     }
     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)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID)
     {
@@ -271,6 +293,8 @@ OCStackResult PDMAddDevice(const OicUuid_t *UUID)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
@@ -279,6 +303,8 @@ OCStackResult PDMAddDevice(const OicUuid_t *UUID)
  */
 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, PDM_SQLITE_GET_ID_SIZE,
@@ -295,6 +321,7 @@ static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
         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);
@@ -306,6 +333,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)
@@ -332,6 +360,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;
 }
 
@@ -340,6 +370,8 @@ 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,
@@ -362,11 +394,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)
     {
@@ -412,6 +447,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);
 }
 
@@ -420,6 +456,8 @@ 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,
@@ -439,11 +477,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)
     {
@@ -465,11 +506,14 @@ 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,
@@ -486,11 +530,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)
     {
@@ -510,12 +557,15 @@ 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,
@@ -538,11 +588,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)
     {
@@ -564,11 +617,14 @@ OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
         return OC_STACK_INVALID_PARAM;
     }
     ASCENDING_ORDER(id1, id2);
+    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)
     {
@@ -599,11 +655,14 @@ 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,
@@ -637,11 +696,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)
     {
@@ -713,11 +775,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)
     {
@@ -758,20 +823,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);
+    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;
@@ -781,10 +852,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;
@@ -794,11 +869,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)
     {
@@ -864,11 +943,14 @@ 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, PdmDeviceState_t 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_DEVICE,
@@ -888,11 +970,14 @@ static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t s
         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 ;
 
@@ -921,11 +1006,14 @@ 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 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);
@@ -955,11 +1043,14 @@ OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
         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");
@@ -983,6 +1074,37 @@ OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
         *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,
+                              (int)strlen(PDM_SQLITE_DELETE_DEVICE_WITH_STATE) + 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);
+
+    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;
+}
index 642856d..aa4f1a7 100644 (file)
@@ -28,6 +28,7 @@ OCGetCredResource
 OCGetDevInfoFromNetwork
 OCGetLinkedStatus
 OCInitPM
+OCPDMCleanupForTimeout
 OCProvisionACL
 OCSaveACL
 OCProvisionCredentials
index 0f1ab4d..f7f6bb3 100644 (file)
@@ -486,6 +486,14 @@ namespace OC
             static OCStackResult setVerifyOptionMask(VerifyOptionBitmask_t optionMask);
 
 
+            /**
+             * API to cleanup PDM in case of timeout.
+             * It will remove the PDM_DEVICE_INIT state devices from PDM.
+             *
+             * @return OC_STACK_OK in case of success and other value otherwise.
+             */
+             static OCStackResult pdmCleanupForTimeout();
+
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
             /**
              * API to save Trust certificate chain into Cred of SVR.
index 73e0b3c..8362831 100644 (file)
@@ -971,6 +971,23 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecure::pdmCleanupForTimeout()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            result = OCPDMCleanupForTimeout();
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
 
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
     OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,