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 * *****************************************************************/
28 #include "oic_malloc.h"
29 #include "provisioningdatabasemanager.h"
30 #include "pmutility.h"
31 #include "oic_string.h"
35 #define DB_FILE "PDM.db"
39 #define PDM_STALE_STATE 1
40 #define PDM_ACTIVE_STATE 0
42 #define PDM_FIRST_INDEX 0
43 #define PDM_SECOND_INDEX 1
45 #define PDM_BIND_INDEX_FIRST 1
46 #define PDM_BIND_INDEX_SECOND 2
47 #define PDM_BIND_INDEX_THIRD 3
49 #define PDM_CREATE_T_DEVICE_LIST "create table T_DEVICE_LIST(ID INTEGER PRIMARY KEY AUTOINCREMENT,\
50 UUID BLOB NOT NULL UNIQUE, STATE INT NOT NULL);"
52 #define PDM_CREATE_T_DEVICE_LINK "create table T_DEVICE_LINK_STATE(ID INT NOT NULL, ID2 INT NOT \
53 NULL,STATE INT NOT NULL, PRIMARY KEY (ID, ID2));"
55 * Macro to verify sqlite success.
56 * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
58 #define PDM_VERIFY_SQLITE_OK(tag, arg, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
59 { OIC_LOG_V((logLevel), tag, "Error in " #arg ", Error Message: %s", \
60 sqlite3_errmsg(g_db)); return retValue; }}while(0)
62 #define PDM_SQLITE_TRANSACTION_BEGIN "BEGIN TRANSACTION;"
63 #define PDM_SQLITE_TRANSACTION_COMMIT "COMMIT;"
64 #define PDM_SQLITE_TRANSACTION_ROLLBACK "ROLLBACK;"
65 #define PDM_SQLITE_GET_STALE_INFO "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE STATE = ?"
66 #define PDM_SQLITE_INSERT_T_DEVICE_LIST "INSERT INTO T_DEVICE_LIST VALUES(?,?,?)"
67 #define PDM_SQLITE_GET_ID "SELECT ID FROM T_DEVICE_LIST WHERE UUID like ?"
68 #define PDM_SQLITE_INSERT_LINK_DATA "INSERT INTO T_DEVICE_LINK_STATE VALUES(?,?,?)"
69 #define PDM_SQLITE_DELETE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? and ID2 = ?"
70 #define PDM_SQLITE_DELETE_DEVICE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? or ID2 = ?"
71 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST WHERE ID = ?"
72 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ? WHERE ID = ? and ID2 = ?"
73 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
74 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
75 #define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
76 (ID = ? or ID2 = ?) and state = 0"
77 #define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
78 ID = ? and ID2 = ? and state = 0"
79 #define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ? WHERE UUID like ?"
80 #define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID like ?"
81 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
82 WHERE ID = ? or ID2 = ?"
84 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
85 { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
87 #define CHECK_PDM_INIT(tag) do{if(true != gInit)\
88 { OIC_LOG(ERROR, (tag), "PDB is not initialized"); \
89 return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
91 static sqlite3 *g_db = NULL;
92 static bool gInit = false; /* Only if we can open sqlite db successfully, gInit is true. */
95 * function to create DB in case DB doesn't exists
97 static OCStackResult createDB(const char* path)
101 result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
102 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
104 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LIST, NULL, NULL, NULL);
105 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
107 OIC_LOG(INFO, TAG, "Created T_DEVICE_LIST");
108 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LINK, NULL, NULL, NULL);
109 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
111 OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
118 * Function to begin any transaction
120 static OCStackResult begin()
123 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
124 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
129 * Function to commit any transaction
131 static OCStackResult commit()
134 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
135 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
140 * Function to rollback any transaction
142 static OCStackResult rollback()
145 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
146 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
151 * Error log callback called by SQLite stack in case of error
153 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
158 OIC_LOG_V(DEBUG,TAG, "(%d) %s", iErrCode, zMsg);
161 OCStackResult PDMInit(const char *path)
164 const char *dbPath = NULL;
165 if (SQLITE_OK != sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
167 OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
170 if (NULL == path || !*path)
178 rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE, NULL);
181 OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
182 return createDB(dbPath);
189 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
194 return OC_STACK_INVALID_PARAM;
197 sqlite3_stmt *stmt = 0;
199 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
200 strlen(PDM_SQLITE_INSERT_T_DEVICE_LIST) + 1, &stmt, NULL);
201 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
203 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
204 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
206 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_ACTIVE_STATE);
207 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
209 res = sqlite3_step(stmt);
210 if (SQLITE_DONE != res)
212 if (SQLITE_CONSTRAINT == res)
214 //new OCStack result code
215 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
216 sqlite3_finalize(stmt);
217 return OC_STACK_DUPLICATE_UUID;
219 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
220 sqlite3_finalize(stmt);
221 return OC_STACK_ERROR;
223 sqlite3_finalize(stmt);
228 * Function to check whether device is stale or not
230 OCStackResult PDMIsDeviceStale(const OicUuid_t *uuid, bool *result)
232 if (NULL == uuid || NULL == result)
234 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
235 return OC_STACK_INVALID_PARAM;
238 sqlite3_stmt *stmt = 0;
240 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_STATUS, strlen(PDM_SQLITE_GET_DEVICE_STATUS) + 1,
242 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
244 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, uuid, UUID_LENGTH, SQLITE_STATIC);
245 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
247 bool retValue = false;
248 while(SQLITE_ROW == sqlite3_step(stmt))
250 int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
251 OIC_LOG_V(DEBUG, TAG, "Stale state is %d", tempStaleStateFromDb);
252 if (PDM_STALE_STATE == tempStaleStateFromDb)
254 OIC_LOG(INFO, TAG, "Device is stale");
259 sqlite3_finalize(stmt);
264 *function to get Id for given UUID
266 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
268 sqlite3_stmt *stmt = 0;
270 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
271 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
273 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
274 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
276 OIC_LOG(DEBUG, TAG, "Binding Done");
277 while (SQLITE_ROW == sqlite3_step(stmt))
279 int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
280 OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
282 sqlite3_finalize(stmt);
285 sqlite3_finalize(stmt);
286 return OC_STACK_INVALID_PARAM;
290 * Function to check duplication of device's Device ID.
292 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
296 if (NULL == UUID || NULL == result)
298 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
299 return OC_STACK_INVALID_PARAM;
301 sqlite3_stmt *stmt = 0;
303 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
304 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
306 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
307 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
309 OIC_LOG(DEBUG, TAG, "Binding Done");
310 bool retValue = false;
311 while(SQLITE_ROW == sqlite3_step(stmt))
313 OIC_LOG(INFO, TAG, "Duplicated UUID");
317 sqlite3_finalize(stmt);
323 * Function to add link in sqlite
325 static OCStackResult addlink(int id1, int id2)
327 sqlite3_stmt *stmt = 0;
329 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
330 strlen(PDM_SQLITE_INSERT_LINK_DATA) + 1, &stmt, NULL);
331 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
333 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
334 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
336 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
337 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
339 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_ACTIVE_STATE);
340 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
342 if (sqlite3_step(stmt) != SQLITE_DONE)
344 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
345 sqlite3_finalize(stmt);
346 return OC_STACK_ERROR;
348 sqlite3_finalize(stmt);
352 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
355 if (NULL == UUID1 || NULL == UUID2)
357 OIC_LOG(ERROR, TAG, "Invalid PARAM");
358 return OC_STACK_INVALID_PARAM;
362 if (OC_STACK_OK != PDMIsDeviceStale(UUID1, &result))
364 OIC_LOG(ERROR, TAG, "Internal error occured");
365 return OC_STACK_ERROR;
369 OIC_LOG(ERROR, TAG, "UUID1:Stale device");
370 return OC_STACK_INVALID_PARAM;
373 if (OC_STACK_OK != PDMIsDeviceStale(UUID2, &result))
375 OIC_LOG(ERROR, TAG, "Internal error occured");
376 return OC_STACK_ERROR;
380 OIC_LOG(ERROR, TAG, "UUID2:Stale device");
381 return OC_STACK_INVALID_PARAM;
385 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
387 OIC_LOG(ERROR, TAG, "Requested value not found");
388 return OC_STACK_INVALID_PARAM;
391 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
393 OIC_LOG(ERROR, TAG, "Requested value not found");
394 return OC_STACK_INVALID_PARAM;
397 ASCENDING_ORDER(id1, id2);
398 return addlink(id1, id2);
402 * Function to remove created link
404 static OCStackResult removeLink(int id1, int id2)
407 sqlite3_stmt *stmt = 0;
408 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK, strlen(PDM_SQLITE_DELETE_LINK) + 1, &stmt, NULL);
409 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
411 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
412 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
414 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
415 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
417 if (SQLITE_DONE != sqlite3_step(stmt))
419 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
420 sqlite3_finalize(stmt);
421 return OC_STACK_ERROR;
423 sqlite3_finalize(stmt);
427 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
430 if (NULL == UUID1 || NULL == UUID2)
432 OIC_LOG(ERROR, TAG, "Invalid PARAM");
433 return OC_STACK_INVALID_PARAM;
437 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
439 OIC_LOG(ERROR, TAG, "Requested value not found");
440 return OC_STACK_INVALID_PARAM;
444 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
446 OIC_LOG(ERROR, TAG, "Requested value not found");
447 return OC_STACK_INVALID_PARAM;
449 ASCENDING_ORDER(id1, id2);
450 return removeLink(id1, id2);
453 static OCStackResult removeFromDeviceList(int id)
455 sqlite3_stmt *stmt = 0;
457 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
458 strlen(PDM_SQLITE_DELETE_DEVICE) + 1, &stmt, NULL);
459 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
461 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
462 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
464 if (sqlite3_step(stmt) != SQLITE_DONE)
466 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
467 sqlite3_finalize(stmt);
468 return OC_STACK_ERROR;
470 sqlite3_finalize(stmt);
474 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
479 return OC_STACK_INVALID_PARAM;
482 if (OC_STACK_OK != getIdForUUID(UUID, &id))
484 OIC_LOG(ERROR, TAG, "Requested value not found");
485 return OC_STACK_INVALID_PARAM;
488 if(OC_STACK_OK != removeFromDeviceList(id))
491 OIC_LOG(ERROR, TAG, "Requested value not found");
492 return OC_STACK_ERROR;
499 static OCStackResult updateLinkState(int id1, int id2, int state)
501 sqlite3_stmt *stmt = 0;
503 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
504 strlen(PDM_SQLITE_UPDATE_LINK) + 1, &stmt, NULL);
505 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
507 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
508 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
510 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
511 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
513 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
514 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
516 if (SQLITE_DONE != sqlite3_step(stmt))
518 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
519 sqlite3_finalize(stmt);
520 return OC_STACK_ERROR;
522 sqlite3_finalize(stmt);
526 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
529 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
531 OIC_LOG(ERROR, TAG, "Invalid PARAM");
532 return OC_STACK_INVALID_PARAM;
536 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
538 OIC_LOG(ERROR, TAG, "Requested value not found");
539 return OC_STACK_INVALID_PARAM;
543 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
545 OIC_LOG(ERROR, TAG, "Requested value not found");
546 return OC_STACK_INVALID_PARAM;
548 ASCENDING_ORDER(id1, id2);
549 return updateLinkState(id1, id2, PDM_STALE_STATE);
553 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
556 if (NULL != *uuidList)
558 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
559 return OC_STACK_INVALID_PARAM;
561 sqlite3_stmt *stmt = 0;
563 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
564 strlen(PDM_SQLITE_LIST_ALL_UUID) + 1, &stmt, NULL);
565 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
568 while (SQLITE_ROW == sqlite3_step(stmt))
570 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
571 OicUuid_t *uid = (OicUuid_t *)ptr;
572 OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
575 OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
576 sqlite3_finalize(stmt);
577 return OC_STACK_NO_MEMORY;
579 memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
580 LL_PREPEND(*uuidList,temp);
583 *numOfDevices = counter;
584 sqlite3_finalize(stmt);
588 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
590 sqlite3_stmt *stmt = 0;
592 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
593 strlen(PDM_SQLITE_GET_UUID) + 1, &stmt, NULL);
594 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
596 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
597 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
599 while (SQLITE_ROW == sqlite3_step(stmt))
601 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
602 memcpy(uid, ptr, sizeof(OicUuid_t));
604 int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
605 if(PDM_STALE_STATE == temp)
619 sqlite3_finalize(stmt);
622 sqlite3_finalize(stmt);
623 return OC_STACK_INVALID_PARAM;
626 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
629 if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
631 return OC_STACK_INVALID_PARAM;
633 if (NULL != *UUIDLIST )
635 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
636 return OC_STACK_INVALID_PARAM;
639 OCStackResult ret = PDMIsDeviceStale(UUID, &result);
640 if (OC_STACK_OK != ret)
642 OIC_LOG(ERROR, TAG, "Internal error occured");
643 return OC_STACK_ERROR;
647 OIC_LOG(ERROR, TAG, "Device is stale");
648 return OC_STACK_INVALID_PARAM;
651 if (OC_STACK_OK != getIdForUUID(UUID, &id))
653 OIC_LOG(ERROR, TAG, "Requested value not found");
654 return OC_STACK_INVALID_PARAM;
658 sqlite3_stmt *stmt = 0;
660 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
661 strlen(PDM_SQLITE_GET_LINKED_DEVICES) + 1, &stmt, NULL);
662 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
664 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
665 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
667 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
668 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
671 while (SQLITE_ROW == sqlite3_step(stmt))
673 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
674 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
676 OicUuid_t temp = {{0,}};
679 getUUIDforId(i1, &temp, NULL);
683 getUUIDforId(i2, &temp, NULL);
686 OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
687 if (NULL == tempNode)
689 OIC_LOG(ERROR, TAG, "No Memory");
690 sqlite3_finalize(stmt);
691 return OC_STACK_NO_MEMORY;
693 memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
694 LL_PREPEND(*UUIDLIST,tempNode);
697 *numOfDevices = counter;
698 sqlite3_finalize(stmt);
702 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
705 if (NULL != *staleDevList)
707 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
708 return OC_STACK_INVALID_PARAM;
711 sqlite3_stmt *stmt = 0;
713 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
714 strlen(PDM_SQLITE_GET_STALE_INFO) + 1, &stmt, NULL);
715 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
717 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_STALE_STATE);
718 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
721 while (SQLITE_ROW == sqlite3_step(stmt))
723 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
724 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
725 OicUuid_t temp1 = {{0,}};
726 OicUuid_t temp2 = {{0,}};;
727 getUUIDforId(i1, &temp1, NULL);
728 getUUIDforId(i2, &temp2, NULL);
730 OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
731 if (NULL == tempNode)
733 OIC_LOG(ERROR, TAG, "No Memory");
734 sqlite3_finalize(stmt);
735 return OC_STACK_NO_MEMORY;
737 memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
738 memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
739 LL_PREPEND(*staleDevList, tempNode);
742 *numOfDevices = counter;
743 sqlite3_finalize(stmt);
747 OCStackResult PDMClose()
751 res = sqlite3_close(g_db);
752 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
756 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
760 OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
761 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
763 LL_DELETE(ptr, tmp1);
769 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
773 OCPairList_t *tmp1 = NULL,*tmp2=NULL;
774 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
776 LL_DELETE(ptr, tmp1);
782 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
786 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
788 return OC_STACK_INVALID_PARAM;
792 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
794 OIC_LOG(ERROR, TAG, "Requested value not found");
795 return OC_STACK_INVALID_PARAM;
798 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
800 OIC_LOG(ERROR, TAG, "Requested value not found");
801 return OC_STACK_INVALID_PARAM;
804 bool isStale = false;
805 if (OC_STACK_OK != PDMIsDeviceStale(uuidOfDevice1, &isStale))
807 OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
808 return OC_STACK_ERROR;
812 OIC_LOG(ERROR, TAG, "uuidOfDevice1:Device is stale");
813 return OC_STACK_INVALID_PARAM;
817 if (OC_STACK_OK != PDMIsDeviceStale(uuidOfDevice2, &isStale))
819 OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
820 return OC_STACK_ERROR;
824 OIC_LOG(ERROR, TAG, "uuidOfDevice2:Device is stale");
825 return OC_STACK_INVALID_PARAM;
828 ASCENDING_ORDER(id1, id2);
830 sqlite3_stmt *stmt = 0;
832 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
833 strlen(PDM_SQLITE_GET_DEVICE_LINKS) + 1, &stmt, NULL);
834 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
836 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
837 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
839 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
840 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
843 while(SQLITE_ROW == sqlite3_step(stmt))
845 OIC_LOG(INFO, TAG, "Link already exists between devices");
848 sqlite3_finalize(stmt);
853 static OCStackResult updateDeviceState(const OicUuid_t *uuid, int state)
855 sqlite3_stmt *stmt = 0;
857 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_DEVICE,
858 strlen(PDM_SQLITE_UPDATE_DEVICE) + 1, &stmt, NULL);
859 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
861 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
862 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
864 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, uuid, UUID_LENGTH, SQLITE_STATIC);
865 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
867 if (SQLITE_DONE != sqlite3_step(stmt))
869 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
870 sqlite3_finalize(stmt);
871 return OC_STACK_ERROR;
873 sqlite3_finalize(stmt);
877 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
879 sqlite3_stmt *stmt = 0;
883 if (OC_STACK_OK != getIdForUUID(devUuid, &id))
885 OIC_LOG(ERROR, TAG, "Requested value not found");
886 return OC_STACK_INVALID_PARAM;
889 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
890 strlen(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE) + 1,
892 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
894 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
895 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
897 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
898 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
900 if (SQLITE_DONE != sqlite3_step(stmt))
902 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
903 sqlite3_finalize(stmt);
904 return OC_STACK_ERROR;
906 sqlite3_finalize(stmt);
910 OCStackResult PDMSetDeviceStale(const OicUuid_t* uuidOfDevice)
913 if (NULL == uuidOfDevice)
915 OIC_LOG(ERROR, TAG, "Invalid PARAM");
916 return OC_STACK_INVALID_PARAM;
919 OCStackResult res = updateLinkForStaleDevice(uuidOfDevice);
920 if (OC_STACK_OK != res)
923 OIC_LOG(ERROR, TAG, "unable to update links");
926 res = updateDeviceState(uuidOfDevice, PDM_STALE_STATE);
927 if (OC_STACK_OK != res)
930 OIC_LOG(ERROR, TAG, "unable to update device state");