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_DELETE_DEVICE_WITH_STATE "DELETE FROM T_DEVICE_LIST WHERE STATE= ?"
70 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ? WHERE ID = ? and ID2 = ?"
71 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
72 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
73 #define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
74 (ID = ? or ID2 = ?) and state = 0"
75 #define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
76 ID = ? and ID2 = ? and state = 0"
77 #define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ? WHERE UUID like ?"
78 #define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID like ?"
79 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
80 WHERE ID = ? or ID2 = ?"
82 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
83 { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
85 #define CHECK_PDM_INIT(tag) do{if(true != gInit)\
86 { OIC_LOG(ERROR, (tag), "PDB is not initialized"); \
87 return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
89 static sqlite3 *g_db = NULL;
90 static bool gInit = false; /* Only if we can open sqlite db successfully, gInit is true. */
93 * function to create DB in case DB doesn't exists
95 static OCStackResult createDB(const char* path)
97 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
100 result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
101 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
103 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LIST, NULL, NULL, NULL);
104 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
106 OIC_LOG(INFO, TAG, "Created T_DEVICE_LIST");
107 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LINK, NULL, NULL, NULL);
108 PDM_VERIFY_SQLITE_OK(TAG, result, ERROR, OC_STACK_ERROR);
110 OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
113 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
120 * Function to begin any transaction
122 static OCStackResult begin()
125 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
126 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
131 * Function to commit any transaction
133 static OCStackResult commit()
136 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
137 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
142 * Function to rollback any transaction
144 static OCStackResult rollback()
147 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
148 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
153 * Error log callback called by SQLite stack in case of error
155 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
160 OIC_LOG_V(DEBUG,TAG, "%s : (%d) %s", __func__, iErrCode, zMsg);
163 OCStackResult PDMInit(const char *path)
165 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
168 const char *dbPath = NULL;
169 if (SQLITE_OK != sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
171 OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
174 if (NULL == path || !*path)
182 rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE, NULL);
185 OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
187 OCStackResult ret = createDB(dbPath);
188 if (OC_STACK_OK != ret)
197 * Remove PDM_DEVICE_INIT status devices.
198 * PDM_DEVICE_INIT means that the OTM process is in progress.
199 * PDM_DEVICE_INIT state device can be existed when the program is terminated during the OTM process in progress.
200 * For this reason, PDM_DEVICE_INIT devices should be removed at PDM initialization time.
202 if(OC_STACK_OK != PDMDeleteDeviceWithState(PDM_DEVICE_INIT))
204 OIC_LOG_V(WARNING, TAG, "Failed to delete init state devices.");
207 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
213 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
215 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
220 return OC_STACK_INVALID_PARAM;
223 sqlite3_stmt *stmt = 0;
225 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
226 strlen(PDM_SQLITE_INSERT_T_DEVICE_LIST) + 1, &stmt, NULL);
227 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
229 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
230 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
232 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_INIT);
233 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
235 res = sqlite3_step(stmt);
236 if (SQLITE_DONE != res)
238 if (SQLITE_CONSTRAINT == res)
240 //new OCStack result code
241 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
242 sqlite3_finalize(stmt);
243 return OC_STACK_DUPLICATE_UUID;
245 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
246 sqlite3_finalize(stmt);
247 return OC_STACK_ERROR;
249 sqlite3_finalize(stmt);
251 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
256 *function to get Id for given UUID
258 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
260 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
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 while (SQLITE_ROW == sqlite3_step(stmt))
273 int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
274 OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
276 sqlite3_finalize(stmt);
277 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
280 sqlite3_finalize(stmt);
281 return OC_STACK_INVALID_PARAM;
285 * Function to check duplication of device's Device ID.
287 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
289 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
292 if (NULL == UUID || NULL == result)
294 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
295 return OC_STACK_INVALID_PARAM;
297 sqlite3_stmt *stmt = 0;
299 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
300 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
302 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
303 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
305 OIC_LOG(DEBUG, TAG, "Binding Done");
306 bool retValue = false;
307 while(SQLITE_ROW == sqlite3_step(stmt))
309 OIC_LOG(INFO, TAG, "Duplicated UUID");
313 sqlite3_finalize(stmt);
316 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
321 * Function to add link in sqlite
323 static OCStackResult addlink(int id1, int id2)
325 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
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_DEVICE_ACTIVE);
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);
349 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
353 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
355 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
358 if (NULL == UUID1 || NULL == UUID2)
360 OIC_LOG(ERROR, TAG, "Invalid PARAM");
361 return OC_STACK_INVALID_PARAM;
364 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
365 if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
367 OIC_LOG(ERROR, TAG, "Internal error occured");
368 return OC_STACK_ERROR;
370 if (PDM_DEVICE_ACTIVE != state)
372 OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
373 return OC_STACK_INVALID_PARAM;
376 state = PDM_DEVICE_UNKNOWN;
377 if (OC_STACK_OK != PDMGetDeviceState(UUID2, &state))
379 OIC_LOG(ERROR, TAG, "Internal error occured");
380 return OC_STACK_ERROR;
382 if (PDM_DEVICE_ACTIVE != state)
384 OIC_LOG_V(ERROR, TAG, "UUID2: Device state is not active : %d", state);
385 return OC_STACK_INVALID_PARAM;
389 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
391 OIC_LOG(ERROR, TAG, "Requested value not found");
392 return OC_STACK_INVALID_PARAM;
395 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
397 OIC_LOG(ERROR, TAG, "Requested value not found");
398 return OC_STACK_INVALID_PARAM;
401 ASCENDING_ORDER(id1, id2);
402 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
403 return addlink(id1, id2);
407 * Function to remove created link
409 static OCStackResult removeLink(int id1, int id2)
411 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
414 sqlite3_stmt *stmt = 0;
415 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK, strlen(PDM_SQLITE_DELETE_LINK) + 1, &stmt, NULL);
416 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
418 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
419 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
421 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
422 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
424 if (SQLITE_DONE != sqlite3_step(stmt))
426 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
427 sqlite3_finalize(stmt);
428 return OC_STACK_ERROR;
430 sqlite3_finalize(stmt);
431 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
435 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
437 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
440 if (NULL == UUID1 || NULL == UUID2)
442 OIC_LOG(ERROR, TAG, "Invalid PARAM");
443 return OC_STACK_INVALID_PARAM;
447 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
449 OIC_LOG(ERROR, TAG, "Requested value not found");
450 return OC_STACK_INVALID_PARAM;
454 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
456 OIC_LOG(ERROR, TAG, "Requested value not found");
457 return OC_STACK_INVALID_PARAM;
459 ASCENDING_ORDER(id1, id2);
460 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
461 return removeLink(id1, id2);
464 static OCStackResult removeFromDeviceList(int id)
466 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
468 sqlite3_stmt *stmt = 0;
470 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
471 strlen(PDM_SQLITE_DELETE_DEVICE) + 1, &stmt, NULL);
472 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
474 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
475 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
477 if (sqlite3_step(stmt) != SQLITE_DONE)
479 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
480 sqlite3_finalize(stmt);
481 return OC_STACK_ERROR;
483 sqlite3_finalize(stmt);
484 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
488 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
490 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
495 return OC_STACK_INVALID_PARAM;
498 if (OC_STACK_OK != getIdForUUID(UUID, &id))
500 OIC_LOG(ERROR, TAG, "Requested value not found");
501 return OC_STACK_INVALID_PARAM;
504 if(OC_STACK_OK != removeFromDeviceList(id))
507 OIC_LOG(ERROR, TAG, "Requested value not found");
508 return OC_STACK_ERROR;
511 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
516 static OCStackResult updateLinkState(int id1, int id2, int state)
518 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
520 sqlite3_stmt *stmt = 0;
522 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
523 strlen(PDM_SQLITE_UPDATE_LINK) + 1, &stmt, NULL);
524 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
526 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
527 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
529 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
530 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
532 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
533 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
535 if (SQLITE_DONE != sqlite3_step(stmt))
537 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
538 sqlite3_finalize(stmt);
539 return OC_STACK_ERROR;
541 sqlite3_finalize(stmt);
542 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
546 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
548 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
551 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
553 OIC_LOG(ERROR, TAG, "Invalid PARAM");
554 return OC_STACK_INVALID_PARAM;
558 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
560 OIC_LOG(ERROR, TAG, "Requested value not found");
561 return OC_STACK_INVALID_PARAM;
565 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
567 OIC_LOG(ERROR, TAG, "Requested value not found");
568 return OC_STACK_INVALID_PARAM;
570 ASCENDING_ORDER(id1, id2);
571 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
572 return updateLinkState(id1, id2, PDM_DEVICE_STALE);
575 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
577 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
580 if (NULL != *uuidList)
582 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
583 return OC_STACK_INVALID_PARAM;
585 sqlite3_stmt *stmt = 0;
587 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
588 strlen(PDM_SQLITE_LIST_ALL_UUID) + 1, &stmt, NULL);
589 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
592 while (SQLITE_ROW == sqlite3_step(stmt))
594 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
595 OicUuid_t *uid = (OicUuid_t *)ptr;
596 OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
599 OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
600 sqlite3_finalize(stmt);
601 return OC_STACK_NO_MEMORY;
603 memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
604 LL_PREPEND(*uuidList,temp);
607 *numOfDevices = counter;
608 sqlite3_finalize(stmt);
609 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
613 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
615 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
617 sqlite3_stmt *stmt = 0;
619 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
620 strlen(PDM_SQLITE_GET_UUID) + 1, &stmt, NULL);
621 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
623 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
624 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
626 while (SQLITE_ROW == sqlite3_step(stmt))
628 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
629 memcpy(uid, ptr, sizeof(OicUuid_t));
631 int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
632 if(PDM_DEVICE_STALE == temp)
646 sqlite3_finalize(stmt);
649 sqlite3_finalize(stmt);
650 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
651 return OC_STACK_INVALID_PARAM;
654 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
656 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
659 if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
661 return OC_STACK_INVALID_PARAM;
663 if (NULL != *UUIDLIST )
665 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
666 return OC_STACK_INVALID_PARAM;
668 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
669 OCStackResult ret = PDMGetDeviceState(UUID, &state);
670 if (OC_STACK_OK != ret)
672 OIC_LOG(ERROR, TAG, "Internal error occured");
673 return OC_STACK_ERROR;
675 if (PDM_DEVICE_ACTIVE != state)
677 OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
678 return OC_STACK_INVALID_PARAM;
681 if (OC_STACK_OK != getIdForUUID(UUID, &id))
683 OIC_LOG(ERROR, TAG, "Requested value not found");
684 return OC_STACK_INVALID_PARAM;
688 sqlite3_stmt *stmt = 0;
690 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
691 strlen(PDM_SQLITE_GET_LINKED_DEVICES) + 1, &stmt, NULL);
692 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
694 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
695 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
697 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
698 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
701 while (SQLITE_ROW == sqlite3_step(stmt))
703 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
704 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
706 OicUuid_t temp = {{0,}};
709 getUUIDforId(i1, &temp, NULL);
713 getUUIDforId(i2, &temp, NULL);
716 OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
717 if (NULL == tempNode)
719 OIC_LOG(ERROR, TAG, "No Memory");
720 sqlite3_finalize(stmt);
721 return OC_STACK_NO_MEMORY;
723 memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
724 LL_PREPEND(*UUIDLIST,tempNode);
727 *numOfDevices = counter;
728 sqlite3_finalize(stmt);
729 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
733 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
735 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
738 if (NULL != *staleDevList)
740 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
741 return OC_STACK_INVALID_PARAM;
744 sqlite3_stmt *stmt = 0;
746 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
747 strlen(PDM_SQLITE_GET_STALE_INFO) + 1, &stmt, NULL);
748 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
750 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_DEVICE_STALE);
751 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
754 while (SQLITE_ROW == sqlite3_step(stmt))
756 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
757 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
758 OicUuid_t temp1 = {{0,}};
759 OicUuid_t temp2 = {{0,}};;
760 getUUIDforId(i1, &temp1, NULL);
761 getUUIDforId(i2, &temp2, NULL);
763 OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
764 if (NULL == tempNode)
766 OIC_LOG(ERROR, TAG, "No Memory");
767 sqlite3_finalize(stmt);
768 return OC_STACK_NO_MEMORY;
770 memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
771 memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
772 LL_PREPEND(*staleDevList, tempNode);
775 *numOfDevices = counter;
776 sqlite3_finalize(stmt);
777 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
781 OCStackResult PDMClose()
783 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
787 res = sqlite3_close(g_db);
788 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
789 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
793 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
795 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
799 OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
800 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
802 LL_DELETE(ptr, tmp1);
807 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
810 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
812 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
816 OCPairList_t *tmp1 = NULL,*tmp2=NULL;
817 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
819 LL_DELETE(ptr, tmp1);
824 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
827 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
830 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
833 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
835 return OC_STACK_INVALID_PARAM;
839 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
841 OIC_LOG(ERROR, TAG, "Requested value not found");
842 return OC_STACK_INVALID_PARAM;
845 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
847 OIC_LOG(ERROR, TAG, "Requested value not found");
848 return OC_STACK_INVALID_PARAM;
851 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
852 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
854 OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
855 return OC_STACK_ERROR;
857 if (PDM_DEVICE_ACTIVE != state)
859 OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
860 return OC_STACK_INVALID_PARAM;
863 state = PDM_DEVICE_UNKNOWN;
864 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
866 OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
867 return OC_STACK_ERROR;
869 if (PDM_DEVICE_ACTIVE != state)
871 OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
872 return OC_STACK_INVALID_PARAM;
875 ASCENDING_ORDER(id1, id2);
877 sqlite3_stmt *stmt = 0;
879 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
880 strlen(PDM_SQLITE_GET_DEVICE_LINKS) + 1, &stmt, NULL);
881 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
883 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
884 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
886 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
887 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
890 while(SQLITE_ROW == sqlite3_step(stmt))
892 OIC_LOG(INFO, TAG, "Link already exists between devices");
895 sqlite3_finalize(stmt);
897 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
901 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
903 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
905 sqlite3_stmt *stmt = 0;
907 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_DEVICE,
908 strlen(PDM_SQLITE_UPDATE_DEVICE) + 1, &stmt, NULL);
909 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
911 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
912 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
914 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, uuid, UUID_LENGTH, SQLITE_STATIC);
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);
924 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
928 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
930 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
932 sqlite3_stmt *stmt = 0;
936 if (OC_STACK_OK != getIdForUUID(devUuid, &id))
938 OIC_LOG(ERROR, TAG, "Requested value not found");
939 return OC_STACK_INVALID_PARAM;
942 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
943 strlen(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE) + 1,
945 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
947 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
948 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
950 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
951 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
953 if (SQLITE_DONE != sqlite3_step(stmt))
955 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
956 sqlite3_finalize(stmt);
957 return OC_STACK_ERROR;
959 sqlite3_finalize(stmt);
960 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
964 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
966 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
968 OCStackResult res = OC_STACK_ERROR;
973 OIC_LOG(ERROR, TAG, "Invalid PARAM");
974 return OC_STACK_INVALID_PARAM;
978 if(PDM_DEVICE_STALE == state)
980 res = updateLinkForStaleDevice(uuid);
981 if (OC_STACK_OK != res)
984 OIC_LOG(ERROR, TAG, "unable to update links");
989 res = updateDeviceState(uuid, state);
990 if (OC_STACK_OK != res)
993 OIC_LOG(ERROR, TAG, "unable to update device state");
997 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1001 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
1003 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1005 if (NULL == uuid || NULL == result)
1007 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
1008 return OC_STACK_INVALID_PARAM;
1011 sqlite3_stmt *stmt = 0;
1013 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_STATUS, strlen(PDM_SQLITE_GET_DEVICE_STATUS) + 1,
1015 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1017 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, uuid, UUID_LENGTH, SQLITE_STATIC);
1018 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1020 *result = PDM_DEVICE_UNKNOWN;
1021 while(SQLITE_ROW == sqlite3_step(stmt))
1023 int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
1024 OIC_LOG_V(DEBUG, TAG, "Device state is %d", tempStaleStateFromDb);
1025 *result = (PdmDeviceState_t)tempStaleStateFromDb;
1027 sqlite3_finalize(stmt);
1028 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1032 OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state)
1034 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1036 CHECK_PDM_INIT(TAG);
1037 if (PDM_DEVICE_ACTIVE != state && PDM_DEVICE_STALE != state &&
1038 PDM_DEVICE_INIT != state && PDM_DEVICE_UNKNOWN != state)
1040 return OC_STACK_INVALID_PARAM;
1043 sqlite3_stmt *stmt = 0;
1045 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE_WITH_STATE,
1046 strlen(PDM_SQLITE_DELETE_DEVICE_WITH_STATE) + 1, &stmt, NULL);
1047 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1049 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
1050 PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1052 if (SQLITE_DONE != sqlite3_step(stmt))
1054 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1055 sqlite3_finalize(stmt);
1056 return OC_STACK_ERROR;
1058 sqlite3_finalize(stmt);
1059 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);