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_FIRST_INDEX 0
40 #define PDM_SECOND_INDEX 1
42 #define PDM_BIND_INDEX_FIRST 1
43 #define PDM_BIND_INDEX_SECOND 2
44 #define PDM_BIND_INDEX_THIRD 3
46 #define PDM_CREATE_T_DEVICE_LIST "create table T_DEVICE_LIST(ID INTEGER PRIMARY KEY AUTOINCREMENT,\
47 UUID BLOB NOT NULL UNIQUE, STATE INT NOT NULL);"
49 #define PDM_CREATE_T_DEVICE_LINK "create table T_DEVICE_LINK_STATE(ID INT NOT NULL, ID2 INT NOT \
50 NULL,STATE INT NOT NULL, PRIMARY KEY (ID, ID2));"
52 * Macro to verify sqlite success.
53 * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
55 #define PDM_VERIFY_SQLITE_OK(tag, arg, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
56 { OIC_LOG_V((logLevel), tag, "Error in " #arg ", Error Message: %s", \
57 sqlite3_errmsg(g_db)); return retValue; }}while(0)
59 #define PDM_SQLITE_TRANSACTION_BEGIN "BEGIN TRANSACTION;"
60 #define PDM_SQLITE_TRANSACTION_COMMIT "COMMIT;"
61 #define PDM_SQLITE_TRANSACTION_ROLLBACK "ROLLBACK;"
62 #define PDM_SQLITE_GET_STALE_INFO "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE STATE = ?"
63 #define PDM_SQLITE_INSERT_T_DEVICE_LIST "INSERT INTO T_DEVICE_LIST VALUES(?,?,?)"
64 #define PDM_SQLITE_GET_ID "SELECT ID FROM T_DEVICE_LIST WHERE UUID like ?"
65 #define PDM_SQLITE_INSERT_LINK_DATA "INSERT INTO T_DEVICE_LINK_STATE VALUES(?,?,?)"
66 #define PDM_SQLITE_DELETE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? and ID2 = ?"
67 #define PDM_SQLITE_DELETE_DEVICE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? or ID2 = ?"
68 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST WHERE ID = ?"
69 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ? WHERE ID = ? and ID2 = ?"
70 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
71 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
72 #define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
73 (ID = ? or ID2 = ?) and state = 0"
74 #define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
75 ID = ? and ID2 = ? and state = 0"
76 #define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ? WHERE UUID like ?"
77 #define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID like ?"
78 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
79 WHERE ID = ? or ID2 = ?"
81 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
82 { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
84 #define CHECK_PDM_INIT(tag) do{if(true != gInit)\
85 { OIC_LOG(ERROR, (tag), "PDB is not initialized"); \
86 return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
88 static sqlite3 *g_db = NULL;
89 static bool gInit = false; /* Only if we can open sqlite db successfully, gInit is true. */
92 * function to create DB in case DB doesn't exists
94 static OCStackResult createDB(const char* path)
98 result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
99 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
101 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LIST, NULL, NULL, NULL);
102 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
104 OIC_LOG(INFO, TAG, "Created T_DEVICE_LIST");
105 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LINK, NULL, NULL, NULL);
106 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
108 OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
115 * Function to begin any transaction
117 static OCStackResult begin()
120 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
121 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
126 * Function to commit any transaction
128 static OCStackResult commit()
131 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
132 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
137 * Function to rollback any transaction
139 static OCStackResult rollback()
142 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
143 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
148 * Error log callback called by SQLite stack in case of error
150 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
155 OIC_LOG_V(DEBUG,TAG, "(%d) %s", iErrCode, zMsg);
158 OCStackResult PDMInit(const char *path)
161 const char *dbPath = NULL;
162 if (SQLITE_OK != sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
164 OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
167 if (NULL == path || !*path)
175 rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE, NULL);
178 OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
179 return createDB(dbPath);
186 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
191 return OC_STACK_INVALID_PARAM;
194 sqlite3_stmt *stmt = 0;
196 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
197 strlen(PDM_SQLITE_INSERT_T_DEVICE_LIST) + 1, &stmt, NULL);
198 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
200 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
201 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
203 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_INIT);
204 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
206 res = sqlite3_step(stmt);
207 if (SQLITE_DONE != res)
209 if (SQLITE_CONSTRAINT == res)
211 //new OCStack result code
212 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
213 sqlite3_finalize(stmt);
214 return OC_STACK_DUPLICATE_UUID;
216 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
217 sqlite3_finalize(stmt);
218 return OC_STACK_ERROR;
220 sqlite3_finalize(stmt);
225 *function to get Id for given UUID
227 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
229 sqlite3_stmt *stmt = 0;
231 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
232 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
234 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
235 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
237 OIC_LOG(DEBUG, TAG, "Binding Done");
238 while (SQLITE_ROW == sqlite3_step(stmt))
240 int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
241 OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
243 sqlite3_finalize(stmt);
246 sqlite3_finalize(stmt);
247 return OC_STACK_INVALID_PARAM;
251 * Function to check duplication of device's Device ID.
253 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
257 if (NULL == UUID || NULL == result)
259 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
260 return OC_STACK_INVALID_PARAM;
262 sqlite3_stmt *stmt = 0;
264 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
265 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
267 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
268 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
270 OIC_LOG(DEBUG, TAG, "Binding Done");
271 bool retValue = false;
272 while(SQLITE_ROW == sqlite3_step(stmt))
274 OIC_LOG(INFO, TAG, "Duplicated UUID");
278 sqlite3_finalize(stmt);
284 * Function to add link in sqlite
286 static OCStackResult addlink(int id1, int id2)
288 sqlite3_stmt *stmt = 0;
290 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
291 strlen(PDM_SQLITE_INSERT_LINK_DATA) + 1, &stmt, NULL);
292 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
294 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
295 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
297 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
298 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
300 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_ACTIVE);
301 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
303 if (sqlite3_step(stmt) != SQLITE_DONE)
305 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
306 sqlite3_finalize(stmt);
307 return OC_STACK_ERROR;
309 sqlite3_finalize(stmt);
313 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
316 if (NULL == UUID1 || NULL == UUID2)
318 OIC_LOG(ERROR, TAG, "Invalid PARAM");
319 return OC_STACK_INVALID_PARAM;
322 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
323 if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
325 OIC_LOG(ERROR, TAG, "Internal error occured");
326 return OC_STACK_ERROR;
328 if (PDM_DEVICE_ACTIVE != state)
330 OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
331 return OC_STACK_INVALID_PARAM;
334 state = PDM_DEVICE_UNKNOWN;
335 if (OC_STACK_OK != PDMGetDeviceState(UUID2, &state))
337 OIC_LOG(ERROR, TAG, "Internal error occured");
338 return OC_STACK_ERROR;
340 if (PDM_DEVICE_ACTIVE != state)
342 OIC_LOG_V(ERROR, TAG, "UUID2: Device state is not active : %d", state);
343 return OC_STACK_INVALID_PARAM;
347 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
349 OIC_LOG(ERROR, TAG, "Requested value not found");
350 return OC_STACK_INVALID_PARAM;
353 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
355 OIC_LOG(ERROR, TAG, "Requested value not found");
356 return OC_STACK_INVALID_PARAM;
359 ASCENDING_ORDER(id1, id2);
360 return addlink(id1, id2);
364 * Function to remove created link
366 static OCStackResult removeLink(int id1, int id2)
369 sqlite3_stmt *stmt = 0;
370 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK, strlen(PDM_SQLITE_DELETE_LINK) + 1, &stmt, NULL);
371 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
373 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
374 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
376 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
377 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
379 if (SQLITE_DONE != sqlite3_step(stmt))
381 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
382 sqlite3_finalize(stmt);
383 return OC_STACK_ERROR;
385 sqlite3_finalize(stmt);
389 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
392 if (NULL == UUID1 || NULL == UUID2)
394 OIC_LOG(ERROR, TAG, "Invalid PARAM");
395 return OC_STACK_INVALID_PARAM;
399 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
401 OIC_LOG(ERROR, TAG, "Requested value not found");
402 return OC_STACK_INVALID_PARAM;
406 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
408 OIC_LOG(ERROR, TAG, "Requested value not found");
409 return OC_STACK_INVALID_PARAM;
411 ASCENDING_ORDER(id1, id2);
412 return removeLink(id1, id2);
415 static OCStackResult removeFromDeviceList(int id)
417 sqlite3_stmt *stmt = 0;
419 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
420 strlen(PDM_SQLITE_DELETE_DEVICE) + 1, &stmt, NULL);
421 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
423 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
424 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
426 if (sqlite3_step(stmt) != SQLITE_DONE)
428 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
429 sqlite3_finalize(stmt);
430 return OC_STACK_ERROR;
432 sqlite3_finalize(stmt);
436 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
441 return OC_STACK_INVALID_PARAM;
444 if (OC_STACK_OK != getIdForUUID(UUID, &id))
446 OIC_LOG(ERROR, TAG, "Requested value not found");
447 return OC_STACK_INVALID_PARAM;
450 if(OC_STACK_OK != removeFromDeviceList(id))
453 OIC_LOG(ERROR, TAG, "Requested value not found");
454 return OC_STACK_ERROR;
461 static OCStackResult updateLinkState(int id1, int id2, int state)
463 sqlite3_stmt *stmt = 0;
465 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
466 strlen(PDM_SQLITE_UPDATE_LINK) + 1, &stmt, NULL);
467 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
469 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
470 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
472 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
473 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
475 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
476 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
478 if (SQLITE_DONE != sqlite3_step(stmt))
480 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
481 sqlite3_finalize(stmt);
482 return OC_STACK_ERROR;
484 sqlite3_finalize(stmt);
488 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
491 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
493 OIC_LOG(ERROR, TAG, "Invalid PARAM");
494 return OC_STACK_INVALID_PARAM;
498 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
500 OIC_LOG(ERROR, TAG, "Requested value not found");
501 return OC_STACK_INVALID_PARAM;
505 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
507 OIC_LOG(ERROR, TAG, "Requested value not found");
508 return OC_STACK_INVALID_PARAM;
510 ASCENDING_ORDER(id1, id2);
511 return updateLinkState(id1, id2, PDM_DEVICE_STALE);
514 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
517 if (NULL != *uuidList)
519 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
520 return OC_STACK_INVALID_PARAM;
522 sqlite3_stmt *stmt = 0;
524 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
525 strlen(PDM_SQLITE_LIST_ALL_UUID) + 1, &stmt, NULL);
526 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
529 while (SQLITE_ROW == sqlite3_step(stmt))
531 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
532 OicUuid_t *uid = (OicUuid_t *)ptr;
533 OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
536 OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
537 sqlite3_finalize(stmt);
538 return OC_STACK_NO_MEMORY;
540 memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
541 LL_PREPEND(*uuidList,temp);
544 *numOfDevices = counter;
545 sqlite3_finalize(stmt);
549 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
551 sqlite3_stmt *stmt = 0;
553 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
554 strlen(PDM_SQLITE_GET_UUID) + 1, &stmt, NULL);
555 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
557 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
558 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
560 while (SQLITE_ROW == sqlite3_step(stmt))
562 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
563 memcpy(uid, ptr, sizeof(OicUuid_t));
565 int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
566 if(PDM_DEVICE_STALE == temp)
580 sqlite3_finalize(stmt);
583 sqlite3_finalize(stmt);
584 return OC_STACK_INVALID_PARAM;
587 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
590 if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
592 return OC_STACK_INVALID_PARAM;
594 if (NULL != *UUIDLIST )
596 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
597 return OC_STACK_INVALID_PARAM;
599 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
600 OCStackResult ret = PDMGetDeviceState(UUID, &state);
601 if (OC_STACK_OK != ret)
603 OIC_LOG(ERROR, TAG, "Internal error occured");
604 return OC_STACK_ERROR;
606 if (PDM_DEVICE_ACTIVE != state)
608 OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
609 return OC_STACK_INVALID_PARAM;
612 if (OC_STACK_OK != getIdForUUID(UUID, &id))
614 OIC_LOG(ERROR, TAG, "Requested value not found");
615 return OC_STACK_INVALID_PARAM;
619 sqlite3_stmt *stmt = 0;
621 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
622 strlen(PDM_SQLITE_GET_LINKED_DEVICES) + 1, &stmt, NULL);
623 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
625 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
626 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
628 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
629 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
632 while (SQLITE_ROW == sqlite3_step(stmt))
634 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
635 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
637 OicUuid_t temp = {{0,}};
640 getUUIDforId(i1, &temp, NULL);
644 getUUIDforId(i2, &temp, NULL);
647 OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
648 if (NULL == tempNode)
650 OIC_LOG(ERROR, TAG, "No Memory");
651 sqlite3_finalize(stmt);
652 return OC_STACK_NO_MEMORY;
654 memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
655 LL_PREPEND(*UUIDLIST,tempNode);
658 *numOfDevices = counter;
659 sqlite3_finalize(stmt);
663 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
666 if (NULL != *staleDevList)
668 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
669 return OC_STACK_INVALID_PARAM;
672 sqlite3_stmt *stmt = 0;
674 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
675 strlen(PDM_SQLITE_GET_STALE_INFO) + 1, &stmt, NULL);
676 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
678 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_DEVICE_STALE);
679 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
682 while (SQLITE_ROW == sqlite3_step(stmt))
684 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
685 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
686 OicUuid_t temp1 = {{0,}};
687 OicUuid_t temp2 = {{0,}};;
688 getUUIDforId(i1, &temp1, NULL);
689 getUUIDforId(i2, &temp2, NULL);
691 OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
692 if (NULL == tempNode)
694 OIC_LOG(ERROR, TAG, "No Memory");
695 sqlite3_finalize(stmt);
696 return OC_STACK_NO_MEMORY;
698 memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
699 memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
700 LL_PREPEND(*staleDevList, tempNode);
703 *numOfDevices = counter;
704 sqlite3_finalize(stmt);
708 OCStackResult PDMClose()
712 res = sqlite3_close(g_db);
713 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
717 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
721 OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
722 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
724 LL_DELETE(ptr, tmp1);
730 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
734 OCPairList_t *tmp1 = NULL,*tmp2=NULL;
735 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
737 LL_DELETE(ptr, tmp1);
743 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
747 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
749 return OC_STACK_INVALID_PARAM;
753 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
755 OIC_LOG(ERROR, TAG, "Requested value not found");
756 return OC_STACK_INVALID_PARAM;
759 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
761 OIC_LOG(ERROR, TAG, "Requested value not found");
762 return OC_STACK_INVALID_PARAM;
765 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
766 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
768 OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
769 return OC_STACK_ERROR;
771 if (PDM_DEVICE_ACTIVE != state)
773 OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
774 return OC_STACK_INVALID_PARAM;
777 state = PDM_DEVICE_UNKNOWN;
778 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
780 OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
781 return OC_STACK_ERROR;
783 if (PDM_DEVICE_ACTIVE != state)
785 OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
786 return OC_STACK_INVALID_PARAM;
789 ASCENDING_ORDER(id1, id2);
791 sqlite3_stmt *stmt = 0;
793 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
794 strlen(PDM_SQLITE_GET_DEVICE_LINKS) + 1, &stmt, NULL);
795 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
797 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
798 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
800 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
801 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
804 while(SQLITE_ROW == sqlite3_step(stmt))
806 OIC_LOG(INFO, TAG, "Link already exists between devices");
809 sqlite3_finalize(stmt);
814 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
816 sqlite3_stmt *stmt = 0;
818 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_DEVICE,
819 strlen(PDM_SQLITE_UPDATE_DEVICE) + 1, &stmt, NULL);
820 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
822 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
823 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
825 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, uuid, UUID_LENGTH, SQLITE_STATIC);
826 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
828 if (SQLITE_DONE != sqlite3_step(stmt))
830 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
831 sqlite3_finalize(stmt);
832 return OC_STACK_ERROR;
834 sqlite3_finalize(stmt);
838 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
840 sqlite3_stmt *stmt = 0;
844 if (OC_STACK_OK != getIdForUUID(devUuid, &id))
846 OIC_LOG(ERROR, TAG, "Requested value not found");
847 return OC_STACK_INVALID_PARAM;
850 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
851 strlen(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE) + 1,
853 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
855 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
856 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
858 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
859 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
861 if (SQLITE_DONE != sqlite3_step(stmt))
863 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
864 sqlite3_finalize(stmt);
865 return OC_STACK_ERROR;
867 sqlite3_finalize(stmt);
871 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
873 OCStackResult res = OC_STACK_ERROR;
878 OIC_LOG(ERROR, TAG, "Invalid PARAM");
879 return OC_STACK_INVALID_PARAM;
883 if(PDM_DEVICE_STALE == state)
885 res = updateLinkForStaleDevice(uuid);
886 if (OC_STACK_OK != res)
889 OIC_LOG(ERROR, TAG, "unable to update links");
894 res = updateDeviceState(uuid, state);
895 if (OC_STACK_OK != res)
898 OIC_LOG(ERROR, TAG, "unable to update device state");
905 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
907 if (NULL == uuid || NULL == result)
909 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
910 return OC_STACK_INVALID_PARAM;
913 sqlite3_stmt *stmt = 0;
915 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_STATUS, strlen(PDM_SQLITE_GET_DEVICE_STATUS) + 1,
917 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
919 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, uuid, UUID_LENGTH, SQLITE_STATIC);
920 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
922 *result = PDM_DEVICE_UNKNOWN;
923 while(SQLITE_ROW == sqlite3_step(stmt))
925 int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
926 OIC_LOG_V(DEBUG, TAG, "Device state is %d", tempStaleStateFromDb);
927 *result = (PdmDeviceState_t)tempStaleStateFromDb;
929 sqlite3_finalize(stmt);