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"
33 #include "srmutility.h"
36 #define DB_FILE "PDM.db"
40 #define PDM_FIRST_INDEX 0
41 #define PDM_SECOND_INDEX 1
43 #define PDM_BIND_INDEX_FIRST 1
44 #define PDM_BIND_INDEX_SECOND 2
45 #define PDM_BIND_INDEX_THIRD 3
47 #define HEX_UUID_STR_LENGTH (UUID_LENGTH*2 + 4)
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, stmt, logLevel, retValue) do{ if (SQLITE_OK != (arg)) \
59 { OIC_LOG_V((logLevel), tag, "Error in " #arg ", Error Message: %s", \
60 sqlite3_errmsg(g_db)); sqlite3_finalize(stmt); return retValue; }}while(0)
63 #define PDM_SQLITE_TRANSACTION_BEGIN "BEGIN TRANSACTION;"
64 #define PDM_SQLITE_TRANSACTION_COMMIT "COMMIT;"
65 #define PDM_SQLITE_TRANSACTION_ROLLBACK "ROLLBACK;"
66 #define PDM_SQLITE_GET_STALE_INFO "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE STATE = ?"
67 #define PDM_SQLITE_INSERT_T_DEVICE_LIST "INSERT INTO T_DEVICE_LIST VALUES(?,?,?)"
68 #define PDM_SQLITE_GET_ID "SELECT ID FROM T_DEVICE_LIST WHERE UUID = "
69 #define PDM_SQLITE_GET_ID_SIZE (int)sizeof(PDM_SQLITE_GET_ID)
70 #define PDM_SQLITE_INSERT_LINK_DATA "INSERT INTO T_DEVICE_LINK_STATE VALUES(?,?,?)"
71 #define PDM_SQLITE_DELETE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? and ID2 = ?"
72 #define PDM_SQLITE_DELETE_DEVICE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? or ID2 = ?"
73 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST WHERE ID = ?"
74 #define PDM_SQLITE_DELETE_DEVICE_WITH_STATE "DELETE FROM T_DEVICE_LIST WHERE STATE= ?"
75 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ? WHERE ID = ? and ID2 = ?"
76 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
77 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
78 #define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
79 (ID = ? or ID2 = ?) and state = 0"
80 #define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
81 ID = ? and ID2 = ? and state = 0"
82 #define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ? WHERE UUID = "
83 #define PDM_SQLITE_UPDATE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_UPDATE_DEVICE)
84 #define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID = "
85 #define PDM_SQLITE_GET_DEVICE_STATUS_SIZE (int)sizeof(PDM_SQLITE_GET_DEVICE_STATUS)
86 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
87 WHERE ID = ? or ID2 = ?"
89 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
90 { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
92 #define CHECK_PDM_INIT(tag) do{if(true != gInit)\
93 { OIC_LOG(ERROR, (tag), "PDB is not initialized"); \
94 return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
96 static sqlite3 *g_db = NULL;
97 static bool gInit = false; /* Only if we can open sqlite db successfully, gInit is true. */
100 * function to create DB in case DB doesn't exists
102 static OCStackResult createDB(const char* path)
104 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
107 result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
108 PDM_VERIFY_SQLITE_OK(TAG, result, NULL, ERROR, OC_STACK_ERROR);
110 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LIST, NULL, NULL, NULL);
111 PDM_VERIFY_SQLITE_OK(TAG, result, NULL, ERROR, OC_STACK_ERROR);
113 OIC_LOG(INFO, TAG, "Created T_DEVICE_LIST");
114 result = sqlite3_exec(g_db, PDM_CREATE_T_DEVICE_LINK, NULL, NULL, NULL);
115 PDM_VERIFY_SQLITE_OK(TAG, result, NULL, ERROR, OC_STACK_ERROR);
117 OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
120 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
127 * Function to begin any transaction
129 static OCStackResult begin()
132 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
133 PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
138 * Function to commit any transaction
140 static OCStackResult commit()
143 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
144 PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
149 * Function to rollback any transaction
151 static OCStackResult rollback()
154 res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
155 PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
160 * Function to convert UUID into hex representation
162 static bool convertUuidToHexString(const OicUuid_t* uuidOfDevice, char* uuidHexString)
164 if(NULL == uuidOfDevice || NULL == uuidHexString)
166 OIC_LOG(ERROR, TAG, "convertUuidToHexString : Invalid param");
170 char *strUUID = NULL;
171 OCStackResult ret = ConvertUuidToStr(uuidOfDevice, &strUUID);
172 if(OC_STACK_OK != ret)
174 OIC_LOG(ERROR, TAG, "SendDeleteCredentialRequest : Failed to canonical UUID encoding");
175 return OC_STACK_ERROR;
178 char* headPtr = strUUID;
179 strncat(uuidHexString, "x'",2);
180 while(('\0' != *headPtr))
185 strncat(uuidHexString, &tmp,1);
189 strncat(uuidHexString, "'",1);
196 * Error log callback called by SQLite stack in case of error
198 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
203 OIC_LOG_V(DEBUG,TAG, "%s : (%d) %s", __func__, iErrCode, zMsg);
206 OCStackResult PDMInit(const char *path)
208 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
211 const char *dbPath = NULL;
212 if (SQLITE_OK != sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
214 OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
217 if (NULL == path || !*path)
225 rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE, NULL);
228 OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
230 OCStackResult ret = createDB(dbPath);
231 if (OC_STACK_OK != ret)
240 * Remove PDM_DEVICE_INIT status devices.
241 * PDM_DEVICE_INIT means that the OTM process is in progress.
242 * PDM_DEVICE_INIT state device can be existed when the program is terminated during the OTM process in progress.
243 * For this reason, PDM_DEVICE_INIT devices should be removed at PDM initialization time.
245 if(OC_STACK_OK != PDMDeleteDeviceWithState(PDM_DEVICE_INIT))
247 OIC_LOG_V(WARNING, TAG, "Failed to delete init state devices.");
250 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
256 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
258 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
263 return OC_STACK_INVALID_PARAM;
266 sqlite3_stmt *stmt = 0;
268 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
269 strlen(PDM_SQLITE_INSERT_T_DEVICE_LIST) + 1, &stmt, NULL);
270 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
272 res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
273 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
275 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_INIT);
276 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
278 res = sqlite3_step(stmt);
279 if (SQLITE_DONE != res)
281 if (SQLITE_CONSTRAINT == res)
283 //new OCStack result code
284 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
285 sqlite3_finalize(stmt);
286 return OC_STACK_DUPLICATE_UUID;
288 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
289 sqlite3_finalize(stmt);
290 return OC_STACK_ERROR;
292 sqlite3_finalize(stmt);
294 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
299 *function to get Id for given UUID
301 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
303 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
305 sqlite3_stmt *stmt = 0;
307 char sqlStat[PDM_SQLITE_GET_ID_SIZE - 1 + HEX_UUID_STR_LENGTH];
308 char hexUUID[HEX_UUID_STR_LENGTH];
310 memset(sqlStat, 0, sizeof(sqlStat));
311 strncpy(sqlStat, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE - 1);
312 memset(hexUUID, 0, sizeof(hexUUID));
314 if (!convertUuidToHexString(UUID, hexUUID))
316 return OC_STACK_ERROR;
319 strncpy(sqlStat + PDM_SQLITE_GET_ID_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
320 res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
321 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
323 while (SQLITE_ROW == sqlite3_step(stmt))
325 int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
326 OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
328 sqlite3_finalize(stmt);
329 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
333 sqlite3_finalize(stmt);
334 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
336 return OC_STACK_INVALID_PARAM;
340 * Function to check duplication of device's Device ID.
342 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
344 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
347 if (NULL == UUID || NULL == result)
349 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
350 return OC_STACK_INVALID_PARAM;
352 sqlite3_stmt *stmt = 0;
354 char sqlStat[PDM_SQLITE_GET_ID_SIZE - 1 + HEX_UUID_STR_LENGTH];
355 char hexUUID[HEX_UUID_STR_LENGTH];
357 memset(sqlStat, 0, sizeof(sqlStat));
358 strncpy(sqlStat, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE - 1);
359 memset(hexUUID, 0, sizeof(hexUUID));
361 if (!convertUuidToHexString(UUID, hexUUID))
363 return OC_STACK_ERROR;
366 strncpy(sqlStat + PDM_SQLITE_GET_ID_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
367 res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
368 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
370 bool retValue = false;
371 while(SQLITE_ROW == sqlite3_step(stmt))
373 OIC_LOG(INFO, TAG, "Duplicated UUID");
377 sqlite3_finalize(stmt);
380 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
385 * Function to add link in sqlite
387 static OCStackResult addlink(int id1, int id2)
389 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
391 sqlite3_stmt *stmt = 0;
393 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
394 strlen(PDM_SQLITE_INSERT_LINK_DATA) + 1, &stmt, NULL);
395 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
397 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
398 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
400 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
401 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
403 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_ACTIVE);
404 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
406 if (sqlite3_step(stmt) != SQLITE_DONE)
408 OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
409 sqlite3_finalize(stmt);
410 return OC_STACK_ERROR;
412 sqlite3_finalize(stmt);
413 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
417 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
419 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
422 if (NULL == UUID1 || NULL == UUID2)
424 OIC_LOG(ERROR, TAG, "Invalid PARAM");
425 return OC_STACK_INVALID_PARAM;
428 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
429 if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
431 OIC_LOG(ERROR, TAG, "Internal error occured");
432 return OC_STACK_ERROR;
434 if (PDM_DEVICE_ACTIVE != state)
436 OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
437 return OC_STACK_INVALID_PARAM;
440 state = PDM_DEVICE_UNKNOWN;
441 if (OC_STACK_OK != PDMGetDeviceState(UUID2, &state))
443 OIC_LOG(ERROR, TAG, "Internal error occured");
444 return OC_STACK_ERROR;
446 if (PDM_DEVICE_ACTIVE != state)
448 OIC_LOG_V(ERROR, TAG, "UUID2: Device state is not active : %d", state);
449 return OC_STACK_INVALID_PARAM;
453 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
455 OIC_LOG(ERROR, TAG, "Requested value not found");
456 return OC_STACK_INVALID_PARAM;
459 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
461 OIC_LOG(ERROR, TAG, "Requested value not found");
462 return OC_STACK_INVALID_PARAM;
465 ASCENDING_ORDER(id1, id2);
466 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
467 return addlink(id1, id2);
471 * Function to remove created link
473 static OCStackResult removeLink(int id1, int id2)
475 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
478 sqlite3_stmt *stmt = 0;
479 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK, strlen(PDM_SQLITE_DELETE_LINK) + 1, &stmt, NULL);
480 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
482 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
483 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
485 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
486 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
488 if (SQLITE_DONE != sqlite3_step(stmt))
490 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
491 sqlite3_finalize(stmt);
492 return OC_STACK_ERROR;
494 sqlite3_finalize(stmt);
495 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
499 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
501 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
504 if (NULL == UUID1 || NULL == UUID2)
506 OIC_LOG(ERROR, TAG, "Invalid PARAM");
507 return OC_STACK_INVALID_PARAM;
511 if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
513 OIC_LOG(ERROR, TAG, "Requested value not found");
514 return OC_STACK_INVALID_PARAM;
518 if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
520 OIC_LOG(ERROR, TAG, "Requested value not found");
521 return OC_STACK_INVALID_PARAM;
523 ASCENDING_ORDER(id1, id2);
524 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
525 return removeLink(id1, id2);
528 static OCStackResult removeFromDeviceList(int id)
530 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
532 sqlite3_stmt *stmt = 0;
534 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
535 strlen(PDM_SQLITE_DELETE_DEVICE) + 1, &stmt, NULL);
536 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
538 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
539 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
541 if (sqlite3_step(stmt) != SQLITE_DONE)
543 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
544 sqlite3_finalize(stmt);
545 return OC_STACK_ERROR;
547 sqlite3_finalize(stmt);
548 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
552 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
554 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
559 return OC_STACK_INVALID_PARAM;
562 if (OC_STACK_OK != getIdForUUID(UUID, &id))
564 OIC_LOG(ERROR, TAG, "Requested value not found");
565 return OC_STACK_INVALID_PARAM;
568 if(OC_STACK_OK != removeFromDeviceList(id))
571 OIC_LOG(ERROR, TAG, "Requested value not found");
572 return OC_STACK_ERROR;
575 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
580 static OCStackResult updateLinkState(int id1, int id2, int state)
582 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
584 sqlite3_stmt *stmt = 0;
586 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
587 strlen(PDM_SQLITE_UPDATE_LINK) + 1, &stmt, NULL);
588 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
590 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
591 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
593 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
594 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
596 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
597 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
599 if (SQLITE_DONE != sqlite3_step(stmt))
601 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
602 sqlite3_finalize(stmt);
603 return OC_STACK_ERROR;
605 sqlite3_finalize(stmt);
606 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
610 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
612 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
615 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
617 OIC_LOG(ERROR, TAG, "Invalid PARAM");
618 return OC_STACK_INVALID_PARAM;
622 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
624 OIC_LOG(ERROR, TAG, "Requested value not found");
625 return OC_STACK_INVALID_PARAM;
629 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
631 OIC_LOG(ERROR, TAG, "Requested value not found");
632 return OC_STACK_INVALID_PARAM;
634 ASCENDING_ORDER(id1, id2);
635 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
636 return updateLinkState(id1, id2, PDM_DEVICE_STALE);
639 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
641 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
644 if (NULL != *uuidList)
646 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
647 return OC_STACK_INVALID_PARAM;
649 sqlite3_stmt *stmt = 0;
651 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
652 strlen(PDM_SQLITE_LIST_ALL_UUID) + 1, &stmt, NULL);
653 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
656 while (SQLITE_ROW == sqlite3_step(stmt))
658 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
659 OicUuid_t *uid = (OicUuid_t *)ptr;
660 OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
663 OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
664 sqlite3_finalize(stmt);
665 return OC_STACK_NO_MEMORY;
667 memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
668 LL_PREPEND(*uuidList,temp);
671 *numOfDevices = counter;
672 sqlite3_finalize(stmt);
673 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
677 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
679 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
681 sqlite3_stmt *stmt = 0;
683 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
684 strlen(PDM_SQLITE_GET_UUID) + 1, &stmt, NULL);
685 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
687 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
688 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
690 while (SQLITE_ROW == sqlite3_step(stmt))
692 const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
693 memcpy(uid, ptr, sizeof(OicUuid_t));
695 int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
696 if(PDM_DEVICE_STALE == temp)
710 sqlite3_finalize(stmt);
713 sqlite3_finalize(stmt);
714 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
715 return OC_STACK_INVALID_PARAM;
718 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
720 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
723 if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
725 return OC_STACK_INVALID_PARAM;
727 if (NULL != *UUIDLIST )
729 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
730 return OC_STACK_INVALID_PARAM;
732 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
733 OCStackResult ret = PDMGetDeviceState(UUID, &state);
734 if (OC_STACK_OK != ret)
736 OIC_LOG(ERROR, TAG, "Internal error occured");
737 return OC_STACK_ERROR;
739 if (PDM_DEVICE_ACTIVE != state)
741 OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
742 return OC_STACK_INVALID_PARAM;
745 if (OC_STACK_OK != getIdForUUID(UUID, &id))
747 OIC_LOG(ERROR, TAG, "Requested value not found");
748 return OC_STACK_INVALID_PARAM;
752 sqlite3_stmt *stmt = 0;
754 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
755 strlen(PDM_SQLITE_GET_LINKED_DEVICES) + 1, &stmt, NULL);
756 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
758 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
759 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
761 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
762 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
765 while (SQLITE_ROW == sqlite3_step(stmt))
767 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
768 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
770 OicUuid_t temp = {{0,}};
773 getUUIDforId(i1, &temp, NULL);
777 getUUIDforId(i2, &temp, NULL);
780 OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
781 if (NULL == tempNode)
783 OIC_LOG(ERROR, TAG, "No Memory");
784 sqlite3_finalize(stmt);
785 return OC_STACK_NO_MEMORY;
787 memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
788 LL_PREPEND(*UUIDLIST,tempNode);
791 *numOfDevices = counter;
792 sqlite3_finalize(stmt);
793 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
797 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
799 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
802 if (NULL != *staleDevList)
804 OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
805 return OC_STACK_INVALID_PARAM;
808 sqlite3_stmt *stmt = 0;
810 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
811 strlen(PDM_SQLITE_GET_STALE_INFO) + 1, &stmt, NULL);
812 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
814 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_DEVICE_STALE);
815 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
818 while (SQLITE_ROW == sqlite3_step(stmt))
820 int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
821 int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
822 OicUuid_t temp1 = {{0,}};
823 OicUuid_t temp2 = {{0,}};;
824 getUUIDforId(i1, &temp1, NULL);
825 getUUIDforId(i2, &temp2, NULL);
827 OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
828 if (NULL == tempNode)
830 OIC_LOG(ERROR, TAG, "No Memory");
831 sqlite3_finalize(stmt);
832 return OC_STACK_NO_MEMORY;
834 memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
835 memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
836 LL_PREPEND(*staleDevList, tempNode);
839 *numOfDevices = counter;
840 sqlite3_finalize(stmt);
841 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
845 OCStackResult PDMClose()
847 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
851 res = sqlite3_close(g_db);
852 PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
853 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
857 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
859 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
863 OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
864 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
866 LL_DELETE(ptr, tmp1);
871 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
874 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
876 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
880 OCPairList_t *tmp1 = NULL,*tmp2=NULL;
881 LL_FOREACH_SAFE(ptr, tmp1, tmp2)
883 LL_DELETE(ptr, tmp1);
888 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
891 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
894 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
897 if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
899 return OC_STACK_INVALID_PARAM;
903 if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
905 OIC_LOG(ERROR, TAG, "Requested value not found");
906 return OC_STACK_INVALID_PARAM;
909 if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
911 OIC_LOG(ERROR, TAG, "Requested value not found");
912 return OC_STACK_INVALID_PARAM;
915 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
916 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
918 OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
919 return OC_STACK_ERROR;
921 if (PDM_DEVICE_ACTIVE != state)
923 OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
924 return OC_STACK_INVALID_PARAM;
927 state = PDM_DEVICE_UNKNOWN;
928 if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
930 OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
931 return OC_STACK_ERROR;
933 if (PDM_DEVICE_ACTIVE != state)
935 OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
936 return OC_STACK_INVALID_PARAM;
939 ASCENDING_ORDER(id1, id2);
941 sqlite3_stmt *stmt = 0;
943 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
944 strlen(PDM_SQLITE_GET_DEVICE_LINKS) + 1, &stmt, NULL);
945 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
947 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
948 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
950 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
951 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
954 while(SQLITE_ROW == sqlite3_step(stmt))
956 OIC_LOG(INFO, TAG, "Link already exists between devices");
959 sqlite3_finalize(stmt);
961 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
965 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
967 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
968 OIC_LOG_V(WARNING, TAG, "UUID is: %s", (char*) uuid);
970 sqlite3_stmt *stmt = 0;
972 char sqlStat[PDM_SQLITE_UPDATE_DEVICE_SIZE - 1 + HEX_UUID_STR_LENGTH];
973 char hexUUID[HEX_UUID_STR_LENGTH];
975 memset(sqlStat, 0, sizeof(sqlStat));
976 strncpy(sqlStat, PDM_SQLITE_UPDATE_DEVICE, PDM_SQLITE_UPDATE_DEVICE_SIZE - 1);
977 memset(hexUUID, 0, sizeof(hexUUID));
979 if (!convertUuidToHexString(uuid, hexUUID))
981 return OC_STACK_ERROR;
984 strncpy(sqlStat + PDM_SQLITE_UPDATE_DEVICE_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
985 res = sqlite3_prepare_v2(g_db, sqlStat,
986 (int)sizeof(sqlStat), &stmt, NULL);
988 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
989 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
990 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
992 if (SQLITE_DONE != sqlite3_step(stmt))
994 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
995 sqlite3_finalize(stmt);
996 return OC_STACK_ERROR;
998 sqlite3_finalize(stmt);
999 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1003 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
1005 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1007 sqlite3_stmt *stmt = 0;
1011 if (OC_STACK_OK != getIdForUUID(devUuid, &id))
1013 OIC_LOG(ERROR, TAG, "Requested value not found");
1014 return OC_STACK_INVALID_PARAM;
1017 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
1018 strlen(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE) + 1,
1020 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1022 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
1023 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1025 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
1026 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1028 if (SQLITE_DONE != sqlite3_step(stmt))
1030 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1031 sqlite3_finalize(stmt);
1032 return OC_STACK_ERROR;
1034 sqlite3_finalize(stmt);
1035 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1039 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
1041 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1043 OCStackResult res = OC_STACK_ERROR;
1045 CHECK_PDM_INIT(TAG);
1048 OIC_LOG(ERROR, TAG, "Invalid PARAM");
1049 return OC_STACK_INVALID_PARAM;
1053 if(PDM_DEVICE_STALE == state)
1055 res = updateLinkForStaleDevice(uuid);
1056 if (OC_STACK_OK != res)
1059 OIC_LOG(ERROR, TAG, "unable to update links");
1064 res = updateDeviceState(uuid, state);
1065 if (OC_STACK_OK != res)
1068 OIC_LOG(ERROR, TAG, "unable to update device state");
1072 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1076 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
1078 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1080 if (NULL == uuid || NULL == result)
1082 OIC_LOG(ERROR, TAG, "UUID or result is NULL");
1083 return OC_STACK_INVALID_PARAM;
1086 sqlite3_stmt *stmt = 0;
1088 char sqlStat[PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1 + HEX_UUID_STR_LENGTH];
1089 char hexUUID[HEX_UUID_STR_LENGTH];
1091 memset(sqlStat, 0, sizeof(sqlStat));
1092 strncpy(sqlStat, PDM_SQLITE_GET_DEVICE_STATUS, PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1);
1093 memset(hexUUID, 0, sizeof(hexUUID));
1095 if (!convertUuidToHexString(uuid, hexUUID))
1097 return OC_STACK_ERROR;
1100 strncpy(sqlStat + PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
1101 res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
1102 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1104 *result = PDM_DEVICE_UNKNOWN;
1105 while(SQLITE_ROW == sqlite3_step(stmt))
1107 int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
1108 OIC_LOG_V(DEBUG, TAG, "Device state is %d", tempStaleStateFromDb);
1109 *result = (PdmDeviceState_t)tempStaleStateFromDb;
1112 sqlite3_finalize(stmt);
1113 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1118 OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state)
1120 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1122 CHECK_PDM_INIT(TAG);
1123 if (PDM_DEVICE_ACTIVE != state && PDM_DEVICE_STALE != state &&
1124 PDM_DEVICE_INIT != state && PDM_DEVICE_UNKNOWN != state)
1126 return OC_STACK_INVALID_PARAM;
1129 sqlite3_stmt *stmt = 0;
1131 res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE_WITH_STATE,
1132 strlen(PDM_SQLITE_DELETE_DEVICE_WITH_STATE) + 1, &stmt, NULL);
1133 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1135 res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
1136 PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1138 if (SQLITE_DONE != sqlite3_step(stmt))
1140 OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1141 sqlite3_finalize(stmt);
1142 return OC_STACK_ERROR;
1144 sqlite3_finalize(stmt);
1145 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);