Tracking OTM state on client side 26/209926/1
authorVitalii Irkha <v.irkha@samsung.com>
Tue, 2 Jul 2019 16:12:27 +0000 (19:12 +0300)
committerSudipto Bal <sudipto.bal@samsung.com>
Fri, 12 Jul 2019 06:46:57 +0000 (12:16 +0530)
Tracking OTM state in DB, to allow only one client start OTM.

https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/531/commits/8d05749742ede4553ab9829fe747fc376672c274
(cherry picked from 8d05749742ede4553ab9829fe747fc376672c274)

Change-Id: Ic8d02209d8de41c5b6f9029daa2d55cd20661e67
Signed-off-by: Vitalii Irkha <v.irkha@samsung.com>
Signed-off-by: Sudipto Bal <sudipto.bal@samsung.com>
resource/csdk/security/provisioning/include/internal/provisioningdatabasemanager.h
resource/csdk/security/provisioning/src/ownershiptransfermanager.c
resource/csdk/security/provisioning/src/provisioningdatabasemanager.c

index 7e41f53c1a69fd235bb46ee5846a31ff048c007c..9d0d2a48219e217bf2525d86a2dad2d330e2649f 100644 (file)
@@ -201,6 +201,44 @@ void PDMDestoryStaleLinkList(OCPairList_t* ptr);
 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
                                 bool *result);
 
+/**
+ * This method put device and owner to otm table when start OTM
+ *
+ * @param[in] uuid - the device uuid
+ * @param[in] owner - the owner uuid
+ *
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OTMStart(const OicUuid_t *uuid, const OicUuid_t *owner);
+
+/**
+ * This method set device state
+ *
+ * @param[in] uuid - the device uuid
+ * @param[in] state - the state
+ *
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OTMSetState(const OicUuid_t *uuid, int state);
+
+/**
+ * This method stop OTM device
+ *
+ * @param[in] uuid - the device uuid
+ *
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OTMStop(const OicUuid_t *uuid);
+
+/**
+ * This method get device state
+ *
+ * @param[in] uuid - the device uuid
+ * @param[out] state - the state
+ *
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OTMGetState(const OicUuid_t *uuid, int *state);
 
 #ifdef __cplusplus
 }
index 781567bae7e9f4d429592da5cd95a36118bc8294..986cadbb635cc56fd8641a3cd5d3a8edd82ff928 100644 (file)
@@ -1524,6 +1524,7 @@ static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle
     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
     {
         OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
+        OTMStop(&otmCtx->selectedDeviceInfo->doxm->deviceID);
         OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
                                               PDM_DEVICE_ACTIVE);
          if (OC_STACK_OK == res)
@@ -2193,6 +2194,19 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
         memcpy(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t));
     }
 
+    OicUuid_t ownerUuid = {0};
+    GetDoxmDevOwnerId(&ownerUuid);
+
+    res = OTMStart(&selectedDevice->doxm->deviceID, &ownerUuid);
+    if(OC_STACK_OK != res)
+    {
+        if(OC_STACK_DUPLICATE_UUID == res)
+        {
+            return res;
+        }
+        OIC_LOG_V(ERROR, TAG, "%s OTMStart error : %d", __func__, res);
+    }
+
     //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
     res = SetupPDM(selectedDevice);
     if(OC_STACK_OK != res)
@@ -2255,6 +2269,19 @@ static OCStackResult StartCustomOwnershipTransfer(void* ctx, OCProvisionDev_t* s
     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
     otmCtx->selectedDeviceInfo = selectedDevice;
 
+    OicUuid_t ownerUuid = {0};
+    GetDoxmDevOwnerId(&ownerUuid);
+
+    res = OTMStart(&selectedDevice->doxm->deviceID, &ownerUuid);
+    if(OC_STACK_OK != res)
+    {
+        if(OC_STACK_DUPLICATE_UUID == res)
+        {
+            return res;
+        }
+        OIC_LOG_V(ERROR, TAG, "%s OTMStart error : %d", __func__, res);
+    }
+
     //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
     res = SetupPDM(selectedDevice);
     if(OC_STACK_OK != res)
index d502fc2938f1a3ac26aa34b056bd8491fd06c276..c774b766cae0aad57b732b2aedcc859362c5c13d 100644 (file)
 #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)
@@ -115,6 +125,10 @@ static OCStackResult createDB(const char* path)
     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__);
@@ -234,6 +248,10 @@ OCStackResult PDMInit(const char *path)
         }
         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;
 
     /*
@@ -252,6 +270,142 @@ OCStackResult PDMInit(const char *path)
     return OC_STACK_OK;
 }
 
+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 || NULL == owner)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    sqlite3_stmt *stmt = 0;
+    int res =0;
+    char *uuidStr = NULL;
+    OCStackResult ret = OC_STACK_OK;
+
+    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);
+
+    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)
+        {
+            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;
+            }
+        }
+        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;
+}
+
+OCStackResult OTMStop(const OicUuid_t *uuid)
+{
+    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)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    sqlite3_stmt *stmt = 0;
+    int res = 0;
+    char *uuidStr = NULL;
+    OCStackResult ret = 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);
+
+    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))
+    {
+        *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)
 {