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, stmt, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
56 { OIC_LOG_V((logLevel), tag, "Error in " #arg ", Error Message: %s", \
57 sqlite3_errmsg(g_db)); sqlite3_finalize(stmt); 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;"
63 #define PDM_SQLITE_GET_STALE_INFO "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE STATE = ?"
64 #define PDM_SQLITE_INSERT_T_DEVICE_LIST "INSERT INTO T_DEVICE_LIST VALUES(?,?,?)"
65 #define PDM_SQLITE_GET_ID "SELECT ID FROM T_DEVICE_LIST WHERE UUID like ?"
66 #define PDM_SQLITE_INSERT_LINK_DATA "INSERT INTO T_DEVICE_LINK_STATE VALUES(?,?,?)"
67 #define PDM_SQLITE_DELETE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? and ID2 = ?"
68 #define PDM_SQLITE_DELETE_DEVICE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? or ID2 = ?"
69 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST WHERE ID = ?"
70 #define PDM_SQLITE_DELETE_DEVICE_WITH_STATE "DELETE FROM T_DEVICE_LIST WHERE STATE= ?"
71 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ? WHERE ID = ? and ID2 = ?"
72 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
73 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
74 #define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
75 (ID = ? or ID2 = ?) and state = 0"
76 #define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
77 ID = ? and ID2 = ? and state = 0"
78 #define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ? WHERE UUID like ?"
79 #define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID like ?"
80 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
81 WHERE ID = ? or ID2 = ?"
83 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
84 { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
86 #define CHECK_PDM_INIT(tag) do{if(true != gInit)\
87 { OIC_LOG(ERROR, (tag), "PDB is not initialized"); \
88 return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
90 static sqlite3 *g_db = NULL;
91 static bool gInit = false; /* Only if we can open sqlite db successfully, gInit is true. */
94 * function to create DB in case DB doesn't exists
96 static OCStackResult createDB(const char* path)
98 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
101 result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
102 PDM_VERIFY_SQLITE_OK(TAG, result, NULL, 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, NULL, 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, NULL, ERROR, OC_STACK_ERROR);
111 OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
114 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
121 * Function to begin any transaction
123 static OCStackResult begin()
126 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
127 PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
132 * Function to commit any transaction
134 static OCStackResult commit()
137 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
138 PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
143 * Function to rollback any transaction
145 static OCStackResult rollback()
148 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
149 PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
154 * Error log callback called by SQLite stack in case of error
156 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
161 OIC_LOG_V(DEBUG,TAG, "%s : (%d) %s", __func__, iErrCode, zMsg);
164 OCStackResult PDMInit(const char *path)
166 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
169 const char *dbPath = NULL;
170 if (SQLITE_OK != sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
172 OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
175 if (NULL == path || !*path)
183 rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE, NULL);
186 OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
188 OCStackResult ret = createDB(dbPath);
189 if (OC_STACK_OK != ret)
198 * Remove PDM_DEVICE_INIT status devices.
199 * PDM_DEVICE_INIT means that the OTM process is in progress.
200 * PDM_DEVICE_INIT state device can be existed when the program is terminated during the OTM process in progress.
201 * For this reason, PDM_DEVICE_INIT devices should be removed at PDM initialization time.
203 if(OC_STACK_OK != PDMDeleteDeviceWithState(PDM_DEVICE_INIT))
205 OIC_LOG_V(WARNING, TAG, "Failed to delete init state devices.");
208 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
214 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
216 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
221 return OC_STACK_INVALID_PARAM;
224 sqlite3_stmt *stmt = 0;
226 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
227 strlen(PDM_SQLITE_INSERT_T_DEVICE_LIST) + 1, &stmt, NULL);
228 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
230 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
231 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
233 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_INIT);
234 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
236 res = sqlite3_step(stmt);
237 if (SQLITE_DONE != res)
239 if (SQLITE_CONSTRAINT == res)
241 //new OCStack result code
242 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
243 sqlite3_finalize(stmt);
244 return OC_STACK_DUPLICATE_UUID;
246 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
247 sqlite3_finalize(stmt);
248 return OC_STACK_ERROR;
250 sqlite3_finalize(stmt);
252 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
257 *function to get Id for given UUID
259 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
261 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
263 sqlite3_stmt *stmt = 0;
265 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
266 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
268 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
269 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
271 OIC_LOG(DEBUG, TAG, "Binding Done");
272 while (SQLITE_ROW == sqlite3_step(stmt))
274 int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
275 OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
277 sqlite3_finalize(stmt);
278 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
281 sqlite3_finalize(stmt);
282 return OC_STACK_INVALID_PARAM;
286 * Function to check duplication of device's Device ID.
288 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
290 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
293 if (NULL == UUID || NULL == result)
295 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
296 return OC_STACK_INVALID_PARAM;
298 sqlite3_stmt *stmt = 0;
300 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
301 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
303 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
304 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
306 OIC_LOG(DEBUG, TAG, "Binding Done");
307 bool retValue = false;
308 while(SQLITE_ROW == sqlite3_step(stmt))
310 OIC_LOG(INFO, TAG, "Duplicated UUID");
314 sqlite3_finalize(stmt);
317 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
322 * Function to add link in sqlite
324 static OCStackResult addlink(int id1, int id2)
326 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
328 sqlite3_stmt *stmt = 0;
330 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
331 strlen(PDM_SQLITE_INSERT_LINK_DATA) + 1, &stmt, NULL);
332 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
334 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
335 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
337 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
338 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
340 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_ACTIVE);
341 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
343 if (sqlite3_step(stmt) != SQLITE_DONE)
345 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
346 sqlite3_finalize(stmt);
347 return OC_STACK_ERROR;
349 sqlite3_finalize(stmt);
350 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
354 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
356 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
359 if (NULL == UUID1 || NULL == UUID2)
361 OIC_LOG(ERROR, TAG, "Invalid PARAM");
362 return OC_STACK_INVALID_PARAM;
365 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
366 if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
368 OIC_LOG(ERROR, TAG, "Internal error occured");
369 return OC_STACK_ERROR;
371 if (PDM_DEVICE_ACTIVE != state)
373 OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
374 return OC_STACK_INVALID_PARAM;
377 state = PDM_DEVICE_UNKNOWN;
378 if (OC_STACK_OK != PDMGetDeviceState(UUID2, &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, "UUID2: Device state is not active : %d", state);
386 return OC_STACK_INVALID_PARAM;
390 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
392 OIC_LOG(ERROR, TAG, "Requested value not found");
393 return OC_STACK_INVALID_PARAM;
396 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
398 OIC_LOG(ERROR, TAG, "Requested value not found");
399 return OC_STACK_INVALID_PARAM;
402 ASCENDING_ORDER(id1, id2);
403 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
404 return addlink(id1, id2);
408 * Function to remove created link
410 static OCStackResult removeLink(int id1, int id2)
412 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
415 sqlite3_stmt *stmt = 0;
416 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK, strlen(PDM_SQLITE_DELETE_LINK) + 1, &stmt, NULL);
417 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
419 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
420 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
422 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
423 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
425 if (SQLITE_DONE != sqlite3_step(stmt))
427 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
428 sqlite3_finalize(stmt);
429 return OC_STACK_ERROR;
431 sqlite3_finalize(stmt);
432 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
436 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
438 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
441 if (NULL == UUID1 || NULL == UUID2)
443 OIC_LOG(ERROR, TAG, "Invalid PARAM");
444 return OC_STACK_INVALID_PARAM;
448 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
450 OIC_LOG(ERROR, TAG, "Requested value not found");
451 return OC_STACK_INVALID_PARAM;
455 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
457 OIC_LOG(ERROR, TAG, "Requested value not found");
458 return OC_STACK_INVALID_PARAM;
460 ASCENDING_ORDER(id1, id2);
461 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
462 return removeLink(id1, id2);
465 static OCStackResult removeFromDeviceList(int id)
467 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
469 sqlite3_stmt *stmt = 0;
471 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
472 strlen(PDM_SQLITE_DELETE_DEVICE) + 1, &stmt, NULL);
473 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
475 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
476 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
478 if (sqlite3_step(stmt) != SQLITE_DONE)
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);
485 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
489 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
491 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
496 return OC_STACK_INVALID_PARAM;
499 if (OC_STACK_OK != getIdForUUID(UUID, &id))
501 OIC_LOG(ERROR, TAG, "Requested value not found");
502 return OC_STACK_INVALID_PARAM;
505 if(OC_STACK_OK != removeFromDeviceList(id))
508 OIC_LOG(ERROR, TAG, "Requested value not found");
509 return OC_STACK_ERROR;
512 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
517 static OCStackResult updateLinkState(int id1, int id2, int state)
519 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
521 sqlite3_stmt *stmt = 0;
523 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
524 strlen(PDM_SQLITE_UPDATE_LINK) + 1, &stmt, NULL);
525 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
527 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
528 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
530 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
531 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
533 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
534 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
536 if (SQLITE_DONE != sqlite3_step(stmt))
538 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
539 sqlite3_finalize(stmt);
540 return OC_STACK_ERROR;
542 sqlite3_finalize(stmt);
543 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
547 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
549 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
552 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
554 OIC_LOG(ERROR, TAG, "Invalid PARAM");
555 return OC_STACK_INVALID_PARAM;
559 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
561 OIC_LOG(ERROR, TAG, "Requested value not found");
562 return OC_STACK_INVALID_PARAM;
566 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
568 OIC_LOG(ERROR, TAG, "Requested value not found");
569 return OC_STACK_INVALID_PARAM;
571 ASCENDING_ORDER(id1, id2);
572 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
573 return updateLinkState(id1, id2, PDM_DEVICE_STALE);
576 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
578 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
581 if (NULL != *uuidList)
583 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
584 return OC_STACK_INVALID_PARAM;
586 sqlite3_stmt *stmt = 0;
588 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
589 strlen(PDM_SQLITE_LIST_ALL_UUID) + 1, &stmt, NULL);
590 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
593 while (SQLITE_ROW == sqlite3_step(stmt))
595 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
596 OicUuid_t *uid = (OicUuid_t *)ptr;
597 OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
600 OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
601 sqlite3_finalize(stmt);
602 return OC_STACK_NO_MEMORY;
604 memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
605 LL_PREPEND(*uuidList,temp);
608 *numOfDevices = counter;
609 sqlite3_finalize(stmt);
610 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
614 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
616 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
618 sqlite3_stmt *stmt = 0;
620 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
621 strlen(PDM_SQLITE_GET_UUID) + 1, &stmt, NULL);
622 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
624 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
625 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
627 while (SQLITE_ROW == sqlite3_step(stmt))
629 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
630 memcpy(uid, ptr, sizeof(OicUuid_t));
632 int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
633 if(PDM_DEVICE_STALE == temp)
647 sqlite3_finalize(stmt);
650 sqlite3_finalize(stmt);
651 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
652 return OC_STACK_INVALID_PARAM;
655 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
657 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
660 if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
662 return OC_STACK_INVALID_PARAM;
664 if (NULL != *UUIDLIST )
666 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
667 return OC_STACK_INVALID_PARAM;
669 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
670 OCStackResult ret = PDMGetDeviceState(UUID, &state);
671 if (OC_STACK_OK != ret)
673 OIC_LOG(ERROR, TAG, "Internal error occured");
674 return OC_STACK_ERROR;
676 if (PDM_DEVICE_ACTIVE != state)
678 OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
679 return OC_STACK_INVALID_PARAM;
682 if (OC_STACK_OK != getIdForUUID(UUID, &id))
684 OIC_LOG(ERROR, TAG, "Requested value not found");
685 return OC_STACK_INVALID_PARAM;
689 sqlite3_stmt *stmt = 0;
691 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
692 strlen(PDM_SQLITE_GET_LINKED_DEVICES) + 1, &stmt, NULL);
693 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
695 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
696 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
698 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
699 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
702 while (SQLITE_ROW == sqlite3_step(stmt))
704 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
705 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
707 OicUuid_t temp = {{0,}};
710 getUUIDforId(i1, &temp, NULL);
714 getUUIDforId(i2, &temp, NULL);
717 OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
718 if (NULL == tempNode)
720 OIC_LOG(ERROR, TAG, "No Memory");
721 sqlite3_finalize(stmt);
722 return OC_STACK_NO_MEMORY;
724 memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
725 LL_PREPEND(*UUIDLIST,tempNode);
728 *numOfDevices = counter;
729 sqlite3_finalize(stmt);
730 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
734 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
736 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
739 if (NULL != *staleDevList)
741 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
742 return OC_STACK_INVALID_PARAM;
745 sqlite3_stmt *stmt = 0;
747 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
748 strlen(PDM_SQLITE_GET_STALE_INFO) + 1, &stmt, NULL);
749 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
751 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_DEVICE_STALE);
752 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
755 while (SQLITE_ROW == sqlite3_step(stmt))
757 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
758 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
759 OicUuid_t temp1 = {{0,}};
760 OicUuid_t temp2 = {{0,}};;
761 getUUIDforId(i1, &temp1, NULL);
762 getUUIDforId(i2, &temp2, NULL);
764 OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
765 if (NULL == tempNode)
767 OIC_LOG(ERROR, TAG, "No Memory");
768 sqlite3_finalize(stmt);
769 return OC_STACK_NO_MEMORY;
771 memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
772 memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
773 LL_PREPEND(*staleDevList, tempNode);
776 *numOfDevices = counter;
777 sqlite3_finalize(stmt);
778 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
782 OCStackResult PDMClose()
784 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
788 res = sqlite3_close(g_db);
789 PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
790 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
794 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
796 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
800 OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
801 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
803 LL_DELETE(ptr, tmp1);
808 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
811 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
813 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
817 OCPairList_t *tmp1 = NULL,*tmp2=NULL;
818 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
820 LL_DELETE(ptr, tmp1);
825 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
828 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
831 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
834 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
836 return OC_STACK_INVALID_PARAM;
840 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
842 OIC_LOG(ERROR, TAG, "Requested value not found");
843 return OC_STACK_INVALID_PARAM;
846 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
848 OIC_LOG(ERROR, TAG, "Requested value not found");
849 return OC_STACK_INVALID_PARAM;
852 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
853 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
855 OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
856 return OC_STACK_ERROR;
858 if (PDM_DEVICE_ACTIVE != state)
860 OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
861 return OC_STACK_INVALID_PARAM;
864 state = PDM_DEVICE_UNKNOWN;
865 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
867 OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
868 return OC_STACK_ERROR;
870 if (PDM_DEVICE_ACTIVE != state)
872 OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
873 return OC_STACK_INVALID_PARAM;
876 ASCENDING_ORDER(id1, id2);
878 sqlite3_stmt *stmt = 0;
880 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
881 strlen(PDM_SQLITE_GET_DEVICE_LINKS) + 1, &stmt, NULL);
882 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
884 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
885 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
887 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
888 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
891 while(SQLITE_ROW == sqlite3_step(stmt))
893 OIC_LOG(INFO, TAG, "Link already exists between devices");
896 sqlite3_finalize(stmt);
898 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
902 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
904 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
906 sqlite3_stmt *stmt = 0;
908 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_DEVICE,
909 strlen(PDM_SQLITE_UPDATE_DEVICE) + 1, &stmt, NULL);
910 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
912 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
913 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
915 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, uuid, UUID_LENGTH, SQLITE_STATIC);
916 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
918 if (SQLITE_DONE != sqlite3_step(stmt))
920 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
921 sqlite3_finalize(stmt);
922 return OC_STACK_ERROR;
924 sqlite3_finalize(stmt);
925 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
929 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
931 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
933 sqlite3_stmt *stmt = 0;
937 if (OC_STACK_OK != getIdForUUID(devUuid, &id))
939 OIC_LOG(ERROR, TAG, "Requested value not found");
940 return OC_STACK_INVALID_PARAM;
943 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
944 strlen(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE) + 1,
946 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
948 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
949 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
951 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
952 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
954 if (SQLITE_DONE != sqlite3_step(stmt))
956 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
957 sqlite3_finalize(stmt);
958 return OC_STACK_ERROR;
960 sqlite3_finalize(stmt);
961 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
965 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
967 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
969 OCStackResult res = OC_STACK_ERROR;
974 OIC_LOG(ERROR, TAG, "Invalid PARAM");
975 return OC_STACK_INVALID_PARAM;
979 if(PDM_DEVICE_STALE == state)
981 res = updateLinkForStaleDevice(uuid);
982 if (OC_STACK_OK != res)
985 OIC_LOG(ERROR, TAG, "unable to update links");
990 res = updateDeviceState(uuid, state);
991 if (OC_STACK_OK != res)
994 OIC_LOG(ERROR, TAG, "unable to update device state");
998 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1002 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
1004 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1006 if (NULL == uuid || NULL == result)
1008 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
1009 return OC_STACK_INVALID_PARAM;
1012 sqlite3_stmt *stmt = 0;
1014 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_STATUS, strlen(PDM_SQLITE_GET_DEVICE_STATUS) + 1,
1016 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1018 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, uuid, UUID_LENGTH, SQLITE_STATIC);
1019 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1021 *result = PDM_DEVICE_UNKNOWN;
1022 while(SQLITE_ROW == sqlite3_step(stmt))
1024 int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
1025 OIC_LOG_V(DEBUG, TAG, "Device state is %d", tempStaleStateFromDb);
1026 *result = (PdmDeviceState_t)tempStaleStateFromDb;
1028 sqlite3_finalize(stmt);
1029 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1033 OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state)
1035 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1037 CHECK_PDM_INIT(TAG);
1038 if (PDM_DEVICE_ACTIVE != state && PDM_DEVICE_STALE != state &&
1039 PDM_DEVICE_INIT != state && PDM_DEVICE_UNKNOWN != state)
1041 return OC_STACK_INVALID_PARAM;
1044 sqlite3_stmt *stmt = 0;
1046 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE_WITH_STATE,
1047 strlen(PDM_SQLITE_DELETE_DEVICE_WITH_STATE) + 1, &stmt, NULL);
1048 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1050 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
1051 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1053 if (SQLITE_DONE != sqlite3_step(stmt))
1055 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1056 sqlite3_finalize(stmt);
1057 return OC_STACK_ERROR;
1059 sqlite3_finalize(stmt);
1060 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);