1 /* *****************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * *****************************************************************/
29 #include "oic_malloc.h"
30 #include "provisioningdatabasemanager.h"
31 #include "pmutility.h"
32 #include "oic_string.h"
36 #define DB_FILE "PDM.db"
40 #define PDM_FIRST_INDEX 0
41 #define PDM_SECOND_INDEX 1
43 #define PDM_BIND_INDEX_FIRST 1
44 #define PDM_BIND_INDEX_SECOND 2
45 #define PDM_BIND_INDEX_THIRD 3
47 #define PDM_CREATE_T_DEVICE_LIST "create table T_DEVICE_LIST(ID INTEGER PRIMARY KEY AUTOINCREMENT,\
48 UUID BLOB NOT NULL UNIQUE, STATE INT NOT NULL);"
50 #define PDM_CREATE_T_DEVICE_LINK "create table T_DEVICE_LINK_STATE(ID INT NOT NULL, ID2 INT NOT \
51 NULL,STATE INT NOT NULL, PRIMARY KEY (ID, ID2));"
53 * Macro to verify sqlite success.
54 * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
56 #define PDM_VERIFY_SQLITE_OK(tag, arg, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
57 { OIC_LOG_V((logLevel), tag, "Error in " #arg ", Error Message: %s", \
58 sqlite3_errmsg(g_db)); return retValue; }}while(0)
60 #define PDM_SQLITE_TRANSACTION_BEGIN "BEGIN TRANSACTION;"
61 #define PDM_SQLITE_TRANSACTION_COMMIT "COMMIT;"
62 #define PDM_SQLITE_TRANSACTION_ROLLBACK "ROLLBACK;"
65 #if ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6))
66 #define static_assert(value, message) _Static_assert((value) ? 1 : 0, message)
68 #define static_assert(value, message)
71 #define PDM_VERIFY_STATEMENT_SIZE(stmt) \
72 static_assert(sizeof(stmt) < INT_MAX, #stmt " must be shorter than INT_MAX.")
74 #define PDM_SQLITE_GET_STALE_INFO "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE STATE = ?"
75 #define PDM_SQLITE_GET_STALE_INFO_SIZE (int)sizeof(PDM_SQLITE_GET_STALE_INFO)
76 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_STALE_INFO);
78 #define PDM_SQLITE_INSERT_T_DEVICE_LIST "INSERT INTO T_DEVICE_LIST VALUES(?,?,?)"
79 #define PDM_SQLITE_INSERT_T_DEVICE_LIST_SIZE (int)sizeof(PDM_SQLITE_INSERT_T_DEVICE_LIST)
80 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_INSERT_T_DEVICE_LIST);
82 #define PDM_SQLITE_GET_ID "SELECT ID FROM T_DEVICE_LIST WHERE UUID like ?"
83 #define PDM_SQLITE_GET_ID_SIZE (int)sizeof(PDM_SQLITE_GET_ID)
84 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_ID);
86 #define PDM_SQLITE_INSERT_LINK_DATA "INSERT INTO T_DEVICE_LINK_STATE VALUES(?,?,?)"
87 #define PDM_SQLITE_INSERT_LINK_DATA_SIZE (int)sizeof(PDM_SQLITE_INSERT_LINK_DATA)
88 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_INSERT_LINK_DATA);
90 #define PDM_SQLITE_DELETE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? and ID2 = ?"
91 #define PDM_SQLITE_DELETE_LINK_SIZE (int)sizeof(PDM_SQLITE_DELETE_LINK)
92 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_DELETE_LINK);
94 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST WHERE ID = ?"
95 #define PDM_SQLITE_DELETE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_DELETE_DEVICE)
96 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_DELETE_DEVICE);
98 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ? WHERE ID = ? and ID2 = ?"
99 #define PDM_SQLITE_UPDATE_LINK_SIZE (int)sizeof(PDM_SQLITE_UPDATE_LINK)
100 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_UPDATE_LINK);
102 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
103 #define PDM_SQLITE_LIST_ALL_UUID_SIZE (int)sizeof(PDM_SQLITE_LIST_ALL_UUID)
104 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_LIST_ALL_UUID);
106 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
107 #define PDM_SQLITE_GET_UUID_SIZE (int)sizeof(PDM_SQLITE_GET_UUID)
108 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_UUID);
110 #define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
111 (ID = ? or ID2 = ?) and state = 0"
112 #define PDM_SQLITE_GET_LINKED_DEVICES_SIZE (int)sizeof(PDM_SQLITE_GET_LINKED_DEVICES)
113 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_LINKED_DEVICES);
115 #define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
116 ID = ? and ID2 = ? and state = 0"
117 #define PDM_SQLITE_GET_DEVICE_LINKS_SIZE (int)sizeof(PDM_SQLITE_GET_DEVICE_LINKS)
118 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_DEVICE_LINKS);
120 #define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ? WHERE UUID like ?"
121 #define PDM_SQLITE_UPDATE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_UPDATE_DEVICE)
122 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_UPDATE_DEVICE);
124 #define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID like ?"
125 #define PDM_SQLITE_GET_DEVICE_STATUS_SIZE (int)sizeof(PDM_SQLITE_GET_DEVICE_STATUS)
126 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_DEVICE_STATUS);
128 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
129 WHERE ID = ? or ID2 = ?"
130 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE)
131 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE);
134 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
135 { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
137 #define CHECK_PDM_INIT(tag) do{if(true != gInit)\
138 { OIC_LOG(ERROR, (tag), "PDB is not initialized"); \
139 return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
141 static sqlite3 *g_db = NULL;
142 static bool gInit = false; /* Only if we can open sqlite db successfully, gInit is true. */
145 * function to create DB in case DB doesn't exists
147 static OCStackResult createDB(const char* path)
151 result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
152 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
154 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LIST, NULL, NULL, NULL);
155 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
157 OIC_LOG(INFO, TAG, "Created T_DEVICE_LIST");
158 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LINK, NULL, NULL, NULL);
159 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
161 OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
168 * Function to begin any transaction
170 static OCStackResult begin()
173 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
174 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
179 * Function to commit any transaction
181 static OCStackResult commit()
184 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
185 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
190 * Function to rollback any transaction
192 static OCStackResult rollback()
195 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
196 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
201 * Error log callback called by SQLite stack in case of error
203 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
208 OIC_LOG_V(DEBUG,TAG, "(%d) %s", iErrCode, zMsg);
211 OCStackResult PDMInit(const char *path)
214 const char *dbPath = NULL;
215 if (SQLITE_OK != sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
217 OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
220 if (NULL == path || !*path)
228 rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE, NULL);
231 OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
232 return createDB(dbPath);
239 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
244 return OC_STACK_INVALID_PARAM;
247 sqlite3_stmt *stmt = 0;
249 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
250 PDM_SQLITE_INSERT_T_DEVICE_LIST_SIZE, &stmt, NULL);
251 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
253 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
254 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
256 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_INIT);
257 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
259 res = sqlite3_step(stmt);
260 if (SQLITE_DONE != res)
262 if (SQLITE_CONSTRAINT == res)
264 //new OCStack result code
265 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
266 sqlite3_finalize(stmt);
267 return OC_STACK_DUPLICATE_UUID;
269 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
270 sqlite3_finalize(stmt);
271 return OC_STACK_ERROR;
273 sqlite3_finalize(stmt);
278 *function to get Id for given UUID
280 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
282 sqlite3_stmt *stmt = 0;
284 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE,
286 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
288 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
289 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
291 OIC_LOG(DEBUG, TAG, "Binding Done");
292 while (SQLITE_ROW == sqlite3_step(stmt))
294 int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
295 OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
297 sqlite3_finalize(stmt);
300 sqlite3_finalize(stmt);
301 return OC_STACK_INVALID_PARAM;
305 * Function to check duplication of device's Device ID.
307 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
311 if (NULL == UUID || NULL == result)
313 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
314 return OC_STACK_INVALID_PARAM;
316 sqlite3_stmt *stmt = 0;
318 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE,
320 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
322 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
323 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
325 OIC_LOG(DEBUG, TAG, "Binding Done");
326 bool retValue = false;
327 while(SQLITE_ROW == sqlite3_step(stmt))
329 OIC_LOG(INFO, TAG, "Duplicated UUID");
333 sqlite3_finalize(stmt);
339 * Function to add link in sqlite
341 static OCStackResult addlink(int id1, int id2)
343 sqlite3_stmt *stmt = 0;
345 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
346 PDM_SQLITE_INSERT_LINK_DATA_SIZE, &stmt, NULL);
347 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
349 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
350 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
352 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
353 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
355 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_ACTIVE);
356 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
358 if (sqlite3_step(stmt) != SQLITE_DONE)
360 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
361 sqlite3_finalize(stmt);
362 return OC_STACK_ERROR;
364 sqlite3_finalize(stmt);
368 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
371 if (NULL == UUID1 || NULL == UUID2)
373 OIC_LOG(ERROR, TAG, "Invalid PARAM");
374 return OC_STACK_INVALID_PARAM;
377 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
378 if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
380 OIC_LOG(ERROR, TAG, "Internal error occured");
381 return OC_STACK_ERROR;
383 if (PDM_DEVICE_ACTIVE != state)
385 OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
386 return OC_STACK_INVALID_PARAM;
389 state = PDM_DEVICE_UNKNOWN;
390 if (OC_STACK_OK != PDMGetDeviceState(UUID2, &state))
392 OIC_LOG(ERROR, TAG, "Internal error occured");
393 return OC_STACK_ERROR;
395 if (PDM_DEVICE_ACTIVE != state)
397 OIC_LOG_V(ERROR, TAG, "UUID2: Device state is not active : %d", state);
398 return OC_STACK_INVALID_PARAM;
402 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
404 OIC_LOG(ERROR, TAG, "Requested value not found");
405 return OC_STACK_INVALID_PARAM;
408 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
410 OIC_LOG(ERROR, TAG, "Requested value not found");
411 return OC_STACK_INVALID_PARAM;
414 ASCENDING_ORDER(id1, id2);
415 return addlink(id1, id2);
419 * Function to remove created link
421 static OCStackResult removeLink(int id1, int id2)
424 sqlite3_stmt *stmt = 0;
425 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK,
426 PDM_SQLITE_DELETE_LINK_SIZE, &stmt, NULL);
427 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
429 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
430 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
432 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
433 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
435 if (SQLITE_DONE != sqlite3_step(stmt))
437 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
438 sqlite3_finalize(stmt);
439 return OC_STACK_ERROR;
441 sqlite3_finalize(stmt);
445 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
448 if (NULL == UUID1 || NULL == UUID2)
450 OIC_LOG(ERROR, TAG, "Invalid PARAM");
451 return OC_STACK_INVALID_PARAM;
455 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
457 OIC_LOG(ERROR, TAG, "Requested value not found");
458 return OC_STACK_INVALID_PARAM;
462 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
464 OIC_LOG(ERROR, TAG, "Requested value not found");
465 return OC_STACK_INVALID_PARAM;
467 ASCENDING_ORDER(id1, id2);
468 return removeLink(id1, id2);
471 static OCStackResult removeFromDeviceList(int id)
473 sqlite3_stmt *stmt = 0;
475 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
476 PDM_SQLITE_DELETE_DEVICE_SIZE, &stmt, NULL);
477 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
479 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
480 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
482 if (sqlite3_step(stmt) != SQLITE_DONE)
484 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
485 sqlite3_finalize(stmt);
486 return OC_STACK_ERROR;
488 sqlite3_finalize(stmt);
492 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
497 return OC_STACK_INVALID_PARAM;
500 if (OC_STACK_OK != getIdForUUID(UUID, &id))
502 OIC_LOG(ERROR, TAG, "Requested value not found");
503 return OC_STACK_INVALID_PARAM;
506 if(OC_STACK_OK != removeFromDeviceList(id))
509 OIC_LOG(ERROR, TAG, "Requested value not found");
510 return OC_STACK_ERROR;
517 static OCStackResult updateLinkState(int id1, int id2, int state)
519 sqlite3_stmt *stmt = 0;
521 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
522 PDM_SQLITE_UPDATE_LINK_SIZE, &stmt, NULL);
523 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
525 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
526 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
528 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
529 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
531 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
532 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
534 if (SQLITE_DONE != sqlite3_step(stmt))
536 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
537 sqlite3_finalize(stmt);
538 return OC_STACK_ERROR;
540 sqlite3_finalize(stmt);
544 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
547 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
549 OIC_LOG(ERROR, TAG, "Invalid PARAM");
550 return OC_STACK_INVALID_PARAM;
554 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
556 OIC_LOG(ERROR, TAG, "Requested value not found");
557 return OC_STACK_INVALID_PARAM;
561 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
563 OIC_LOG(ERROR, TAG, "Requested value not found");
564 return OC_STACK_INVALID_PARAM;
566 ASCENDING_ORDER(id1, id2);
567 return updateLinkState(id1, id2, PDM_DEVICE_STALE);
570 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
573 if (NULL != *uuidList)
575 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
576 return OC_STACK_INVALID_PARAM;
578 sqlite3_stmt *stmt = 0;
580 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
581 PDM_SQLITE_LIST_ALL_UUID_SIZE, &stmt, NULL);
582 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
585 while (SQLITE_ROW == sqlite3_step(stmt))
587 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
588 OicUuid_t *uid = (OicUuid_t *)ptr;
589 OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
592 OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
593 sqlite3_finalize(stmt);
594 return OC_STACK_NO_MEMORY;
596 memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
597 LL_PREPEND(*uuidList,temp);
600 *numOfDevices = counter;
601 sqlite3_finalize(stmt);
605 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
607 sqlite3_stmt *stmt = 0;
609 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
610 PDM_SQLITE_GET_UUID_SIZE, &stmt, NULL);
611 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
613 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
614 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
616 while (SQLITE_ROW == sqlite3_step(stmt))
618 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
619 memcpy(uid, ptr, sizeof(OicUuid_t));
621 int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
622 if(PDM_DEVICE_STALE == temp)
636 sqlite3_finalize(stmt);
639 sqlite3_finalize(stmt);
640 return OC_STACK_INVALID_PARAM;
643 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
646 if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
648 return OC_STACK_INVALID_PARAM;
650 if (NULL != *UUIDLIST )
652 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
653 return OC_STACK_INVALID_PARAM;
655 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
656 OCStackResult ret = PDMGetDeviceState(UUID, &state);
657 if (OC_STACK_OK != ret)
659 OIC_LOG(ERROR, TAG, "Internal error occured");
660 return OC_STACK_ERROR;
662 if (PDM_DEVICE_ACTIVE != state)
664 OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
665 return OC_STACK_INVALID_PARAM;
668 if (OC_STACK_OK != getIdForUUID(UUID, &id))
670 OIC_LOG(ERROR, TAG, "Requested value not found");
671 return OC_STACK_INVALID_PARAM;
675 sqlite3_stmt *stmt = 0;
677 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
678 PDM_SQLITE_GET_LINKED_DEVICES_SIZE, &stmt, NULL);
679 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
681 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
682 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
684 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
685 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
688 while (SQLITE_ROW == sqlite3_step(stmt))
690 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
691 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
693 OicUuid_t temp = {{0,}};
696 getUUIDforId(i1, &temp, NULL);
700 getUUIDforId(i2, &temp, NULL);
703 OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
704 if (NULL == tempNode)
706 OIC_LOG(ERROR, TAG, "No Memory");
707 sqlite3_finalize(stmt);
708 return OC_STACK_NO_MEMORY;
710 memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
711 LL_PREPEND(*UUIDLIST,tempNode);
714 *numOfDevices = counter;
715 sqlite3_finalize(stmt);
719 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
722 if (NULL != *staleDevList)
724 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
725 return OC_STACK_INVALID_PARAM;
728 sqlite3_stmt *stmt = 0;
730 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
731 PDM_SQLITE_GET_STALE_INFO_SIZE, &stmt, NULL);
732 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
734 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_DEVICE_STALE);
735 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
738 while (SQLITE_ROW == sqlite3_step(stmt))
740 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
741 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
742 OicUuid_t temp1 = {{0,}};
743 OicUuid_t temp2 = {{0,}};;
744 getUUIDforId(i1, &temp1, NULL);
745 getUUIDforId(i2, &temp2, NULL);
747 OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
748 if (NULL == tempNode)
750 OIC_LOG(ERROR, TAG, "No Memory");
751 sqlite3_finalize(stmt);
752 return OC_STACK_NO_MEMORY;
754 memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
755 memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
756 LL_PREPEND(*staleDevList, tempNode);
759 *numOfDevices = counter;
760 sqlite3_finalize(stmt);
764 OCStackResult PDMClose()
768 res = sqlite3_close(g_db);
769 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
773 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
777 OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
778 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
780 LL_DELETE(ptr, tmp1);
786 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
790 OCPairList_t *tmp1 = NULL,*tmp2=NULL;
791 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
793 LL_DELETE(ptr, tmp1);
799 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
803 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
805 return OC_STACK_INVALID_PARAM;
809 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
811 OIC_LOG(ERROR, TAG, "Requested value not found");
812 return OC_STACK_INVALID_PARAM;
815 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
817 OIC_LOG(ERROR, TAG, "Requested value not found");
818 return OC_STACK_INVALID_PARAM;
821 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
822 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
824 OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
825 return OC_STACK_ERROR;
827 if (PDM_DEVICE_ACTIVE != state)
829 OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
830 return OC_STACK_INVALID_PARAM;
833 state = PDM_DEVICE_UNKNOWN;
834 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
836 OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
837 return OC_STACK_ERROR;
839 if (PDM_DEVICE_ACTIVE != state)
841 OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
842 return OC_STACK_INVALID_PARAM;
845 ASCENDING_ORDER(id1, id2);
847 sqlite3_stmt *stmt = 0;
849 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
850 PDM_SQLITE_GET_DEVICE_LINKS_SIZE, &stmt, NULL);
851 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
853 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
854 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
856 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
857 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
860 while(SQLITE_ROW == sqlite3_step(stmt))
862 OIC_LOG(INFO, TAG, "Link already exists between devices");
865 sqlite3_finalize(stmt);
870 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
872 sqlite3_stmt *stmt = 0;
874 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_DEVICE,
875 PDM_SQLITE_UPDATE_DEVICE_SIZE, &stmt, NULL);
876 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
878 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
879 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
881 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, uuid, UUID_LENGTH, SQLITE_STATIC);
882 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
884 if (SQLITE_DONE != sqlite3_step(stmt))
886 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
887 sqlite3_finalize(stmt);
888 return OC_STACK_ERROR;
890 sqlite3_finalize(stmt);
894 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
896 sqlite3_stmt *stmt = 0;
900 if (OC_STACK_OK != getIdForUUID(devUuid, &id))
902 OIC_LOG(ERROR, TAG, "Requested value not found");
903 return OC_STACK_INVALID_PARAM;
906 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
907 PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE_SIZE,
909 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
911 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
912 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
914 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
915 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
917 if (SQLITE_DONE != sqlite3_step(stmt))
919 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
920 sqlite3_finalize(stmt);
921 return OC_STACK_ERROR;
923 sqlite3_finalize(stmt);
927 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
929 OCStackResult res = OC_STACK_ERROR;
934 OIC_LOG(ERROR, TAG, "Invalid PARAM");
935 return OC_STACK_INVALID_PARAM;
939 if(PDM_DEVICE_STALE == state)
941 res = updateLinkForStaleDevice(uuid);
942 if (OC_STACK_OK != res)
945 OIC_LOG(ERROR, TAG, "unable to update links");
950 res = updateDeviceState(uuid, state);
951 if (OC_STACK_OK != res)
954 OIC_LOG(ERROR, TAG, "unable to update device state");
961 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
963 if (NULL == uuid || NULL == result)
965 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
966 return OC_STACK_INVALID_PARAM;
969 sqlite3_stmt *stmt = 0;
971 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_STATUS, PDM_SQLITE_GET_DEVICE_STATUS_SIZE,
973 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
975 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, uuid, UUID_LENGTH, SQLITE_STATIC);
976 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
978 *result = PDM_DEVICE_UNKNOWN;
979 while(SQLITE_ROW == sqlite3_step(stmt))
981 int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
982 OIC_LOG_V(DEBUG, TAG, "Device state is %d", tempStaleStateFromDb);
983 *result = (PdmDeviceState_t)tempStaleStateFromDb;
985 sqlite3_finalize(stmt);