--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************/
+#include "iotivity_config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <glib.h>
+#include <gio/gio.h>
+#include <sqlite3.h>
+
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocprovisioningmanager.h"
+
+#include <tzplatform_config.h>
+
+#include "d2ds.h"
+#include "d2ds-log.h"
+#include "d2ds-util.h"
+
+#define MAX_FILE_PATH_LEN 1024
+
+static const char* PRVN_DB_FILE_NAME = "oic_pdm_d2ds.db"; /**< Provisining DB file */
+
+#define UUID_LENGTH 128/8 /**< 128-bit GUID length */
+
+typedef enum PdmDeviceState {
+ PDM_DEVICE_ACTIVE = 0,
+ PDM_DEVICE_STALE = 1,
+ PDM_DEVICE_INIT = 2,
+ PDM_DEVICE_UNKNOWN = 99
+} PdmDeviceState_t;
+
+#define PDM_FIRST_INDEX 0
+#define PDM_SECOND_INDEX 1
+
+#define PDM_BIND_INDEX_FIRST 1
+#define PDM_BIND_INDEX_SECOND 2
+#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, 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));"
+
+#define PDM_VERIFY_SQLITE_OK(arg, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
+ { D2DS_LOGE("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_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_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 = ?"
+#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 CHECK_PDM_INIT() do{if(true != gInit)\
+ { D2DS_LOGE("PDB is not initialized"); \
+ return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
+
+static sqlite3 *g_db = NULL;
+static bool gInit = false; /* Only if we can open sqlite db successfully, gInit is true. */
+
+static OCStackResult begin()
+{
+ int res = 0;
+ res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
+ PDM_VERIFY_SQLITE_OK(res, ERROR, OC_STACK_ERROR);
+ return OC_STACK_OK;
+}
+
+static OCStackResult commit()
+{
+ int res = 0;
+ res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
+ PDM_VERIFY_SQLITE_OK(res, ERROR, OC_STACK_ERROR);
+ return OC_STACK_OK;
+}
+
+static OCStackResult rollback()
+{
+ int res = 0;
+ res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
+ PDM_VERIFY_SQLITE_OK(res, ERROR, OC_STACK_ERROR);
+ return OC_STACK_OK;
+}
+
+int openDB()
+{
+ int result = 0;
+ char path[MAX_FILE_PATH_LEN] = {0,};
+
+ snprintf(path, MAX_FILE_PATH_LEN, "%s/network/%s",
+ tzplatform_getenv(TZ_SYS_GLOBALUSER_DATA), PRVN_DB_FILE_NAME);
+
+ result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE, NULL);
+ PDM_VERIFY_SQLITE_OK(result, ERROR, OC_STACK_ERROR);
+
+ gInit = true;
+
+ return OC_STACK_OK;
+}
+
+int closeDB()
+{
+ CHECK_PDM_INIT();
+ int res = 0;
+ res = sqlite3_close(g_db);
+ PDM_VERIFY_SQLITE_OK(res, ERROR, OC_STACK_ERROR);
+ return OC_STACK_OK;
+}
+
+static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
+{
+ 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(res, ERROR, OC_STACK_ERROR);
+
+ res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
+ PDM_VERIFY_SQLITE_OK(res, ERROR, OC_STACK_ERROR);
+
+ while (SQLITE_ROW == sqlite3_step(stmt))
+ {
+ 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_DEVICE_STALE == temp)
+ {
+ if(result)
+ {
+ *result = true;
+ }
+ }
+ else
+ {
+ if(result)
+ {
+ *result = false;
+ }
+ }
+ sqlite3_finalize(stmt);
+ return OC_STACK_OK;
+ }
+ sqlite3_finalize(stmt);
+
+ return OC_STACK_INVALID_PARAM;
+}
+
+static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
+{
+ 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(res, ERROR, OC_STACK_ERROR);
+
+ res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
+ PDM_VERIFY_SQLITE_OK(res, ERROR, OC_STACK_ERROR);
+
+ D2DS_LOGD("Binding Done");
+ while (SQLITE_ROW == sqlite3_step(stmt))
+ {
+ int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
+ D2DS_LOGD("ID is %d", tempId);
+ *id = tempId;
+ sqlite3_finalize(stmt);
+ return OC_STACK_OK;
+ }
+ sqlite3_finalize(stmt);
+ return OC_STACK_INVALID_PARAM;
+}
+
+static OCStackResult removeFromDeviceList(int id)
+{
+ 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(res, ERROR, OC_STACK_ERROR);
+
+ res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
+ PDM_VERIFY_SQLITE_OK(res, ERROR, OC_STACK_ERROR);
+
+ if (sqlite3_step(stmt) != SQLITE_DONE)
+ {
+ D2DS_LOGE("Error message: %s", sqlite3_errmsg(g_db));
+ sqlite3_finalize(stmt);
+ return OC_STACK_ERROR;
+ }
+ sqlite3_finalize(stmt);
+
+ return OC_STACK_OK;
+}
+
+int delete_mowned_device_db(const OicUuid_t *UUID)
+{
+ CHECK_PDM_INIT();
+ if (NULL == UUID)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ int id = 0;
+ if (OC_STACK_OK != getIdForUUID(UUID, &id))
+ {
+ D2DS_LOGE("Requested value not found");
+ return OC_STACK_INVALID_PARAM;
+ }
+ begin();
+ if(OC_STACK_OK != removeFromDeviceList(id))
+ {
+ rollback();
+ D2DS_LOGE("Requested value not found");
+ return OC_STACK_ERROR;
+ }
+ commit();
+ return OC_STACK_OK;
+}