PDMClose and createDb change
[iotivity.git] / resource / csdk / security / provisioning / src / provisioningdatabasemanager.c
1 /* *****************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  * *****************************************************************/
20
21 #include <stdio.h>
22 #include <stdbool.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <limits.h>
26
27 #include <sqlite3.h>
28 #include "experimental/logger.h"
29 #include "oic_malloc.h"
30 #include "provisioningdatabasemanager.h"
31 #include "pmutility.h"
32 #include "oic_string.h"
33 #include "utlist.h"
34 #include "srmutility.h"
35
36 #define DB_FILE "PDM.db"
37
38 #define TAG "OIC_PDM"
39
40 #define PDM_FIRST_INDEX 0
41 #define PDM_SECOND_INDEX 1
42
43 #define PDM_BIND_INDEX_FIRST 1
44 #define PDM_BIND_INDEX_SECOND 2
45 #define PDM_BIND_INDEX_THIRD 3
46
47 #define PDM_CREATE_DB "CREATE TABLE IF NOT EXISTS T_DEVICE_LIST(ID INTEGER PRIMARY KEY AUTOINCREMENT,\
48                                   UUID BLOB NOT NULL UNIQUE, STATE INT NOT NULL);\
49                        CREATE TABLE IF NOT EXISTS T_DEVICE_LINK_STATE(ID INT NOT NULL, ID2 INT NOT \
50                                     NULL,STATE INT NOT NULL, PRIMARY KEY (ID, ID2));"
51 /**
52  * Macro to verify sqlite success.
53  * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
54  */
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)
58
59 #define PDM_SQLITE_TRANSACTION_BEGIN "BEGIN TRANSACTION;"
60 #define PDM_SQLITE_TRANSACTION_COMMIT "COMMIT;"
61 #define PDM_SQLITE_TRANSACTION_ROLLBACK "ROLLBACK;"
62
63 #ifdef __GNUC__
64 #if ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6))
65 #define static_assert(value, message) _Static_assert((value) ? 1 : 0, message)
66 #else
67 #define static_assert(value, message)
68 #endif
69 #endif
70 #define PDM_VERIFY_STATEMENT_SIZE(stmt) \
71     static_assert(sizeof(stmt) < INT_MAX, #stmt " must be shorter than INT_MAX.")
72
73 #define PDM_SQLITE_GET_STALE_INFO "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE STATE = ?"
74 #define PDM_SQLITE_GET_STALE_INFO_SIZE (int)sizeof(PDM_SQLITE_GET_STALE_INFO)
75 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_STALE_INFO);
76
77 #define PDM_SQLITE_INSERT_T_DEVICE_LIST "INSERT INTO T_DEVICE_LIST VALUES(?,?,?)"
78 #define PDM_SQLITE_INSERT_T_DEVICE_LIST_SIZE (int)sizeof(PDM_SQLITE_INSERT_T_DEVICE_LIST)
79 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_INSERT_T_DEVICE_LIST);
80
81 #define PDM_SQLITE_GET_ID "SELECT ID FROM T_DEVICE_LIST WHERE UUID like ?"
82 #define PDM_SQLITE_GET_ID_SIZE (int)sizeof(PDM_SQLITE_GET_ID)
83 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_ID);
84
85 #define PDM_SQLITE_INSERT_LINK_DATA "INSERT INTO T_DEVICE_LINK_STATE VALUES(?,?,?)"
86 #define PDM_SQLITE_INSERT_LINK_DATA_SIZE (int)sizeof(PDM_SQLITE_INSERT_LINK_DATA)
87 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_INSERT_LINK_DATA);
88
89 #define PDM_SQLITE_DELETE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? and ID2 = ?"
90 #define PDM_SQLITE_DELETE_LINK_SIZE (int)sizeof(PDM_SQLITE_DELETE_LINK)
91 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_DELETE_LINK);
92
93 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST  WHERE ID = ?"
94 #define PDM_SQLITE_DELETE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_DELETE_DEVICE)
95 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_DELETE_DEVICE);
96 #define PDM_SQLITE_DELETE_DEVICE_WITH_STATE "DELETE FROM T_DEVICE_LIST  WHERE STATE= ?"
97 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ?  WHERE ID = ? and ID2 = ?"
98 #define PDM_SQLITE_UPDATE_LINK_SIZE (int)sizeof(PDM_SQLITE_UPDATE_LINK)
99 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_UPDATE_LINK);
100
101 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
102 #define PDM_SQLITE_LIST_ALL_UUID_SIZE (int)sizeof(PDM_SQLITE_LIST_ALL_UUID)
103 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_LIST_ALL_UUID);
104
105 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
106 #define PDM_SQLITE_GET_UUID_SIZE (int)sizeof(PDM_SQLITE_GET_UUID)
107 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_UUID);
108
109 #define PDM_SQLITE_GET_LINKED_DEVICES "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
110                                            (ID = ? or ID2 = ?) and state = 0"
111 #define PDM_SQLITE_GET_LINKED_DEVICES_SIZE (int)sizeof(PDM_SQLITE_GET_LINKED_DEVICES)
112 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_LINKED_DEVICES);
113
114 #define PDM_SQLITE_GET_DEVICE_LINKS "SELECT ID,ID2 FROM T_DEVICE_LINK_STATE WHERE \
115                                           ID = ? and ID2 = ? and state = 0"
116 #define PDM_SQLITE_GET_DEVICE_LINKS_SIZE (int)sizeof(PDM_SQLITE_GET_DEVICE_LINKS)
117 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_DEVICE_LINKS);
118
119 #define PDM_SQLITE_UPDATE_DEVICE "UPDATE T_DEVICE_LIST SET STATE = ?  WHERE UUID like ?"
120 #define PDM_SQLITE_UPDATE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_UPDATE_DEVICE)
121 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_UPDATE_DEVICE);
122
123 #define PDM_SQLITE_GET_DEVICE_STATUS "SELECT STATE FROM T_DEVICE_LIST WHERE UUID like ?"
124 #define PDM_SQLITE_GET_DEVICE_STATUS_SIZE (int)sizeof(PDM_SQLITE_GET_DEVICE_STATUS)
125 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_GET_DEVICE_STATUS);
126
127 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE "UPDATE T_DEVICE_LINK_STATE SET STATE = 1\
128                                                           WHERE ID = ? or ID2 = ?"
129 #define PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE_SIZE (int)sizeof(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE)
130 PDM_VERIFY_STATEMENT_SIZE(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE);
131
132
133 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
134   { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
135
136 #define CHECK_PDM_INIT() do{if(true != gInit || !g_db)\
137   { OIC_LOG(ERROR, TAG, "PDB is not initialized"); \
138     return OC_STACK_PDM_IS_NOT_INITIALIZED; }}while(0)
139
140 static sqlite3 *g_db = NULL;
141 static bool gInit = false;  /* Only if we can open sqlite db successfully, gInit is true. */
142
143 /**
144  * Function to begin any transaction
145  */
146 static OCStackResult begin(void)
147 {
148     CHECK_PDM_INIT();
149     int res = 0;
150     res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_BEGIN, NULL, NULL, NULL);
151     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
152     return OC_STACK_OK;
153 }
154
155 /**
156  * Function to commit any transaction
157  */
158 static OCStackResult commit(void)
159 {
160     CHECK_PDM_INIT();
161     int res = 0;
162     res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_COMMIT, NULL, NULL, NULL);
163     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
164     return OC_STACK_OK;
165 }
166
167 /**
168  * Function to rollback any transaction
169  */
170 static OCStackResult rollback(void)
171 {
172     CHECK_PDM_INIT();
173     int res = 0;
174     res = sqlite3_exec(g_db, PDM_SQLITE_TRANSACTION_ROLLBACK, NULL, NULL, NULL);
175     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
176     return OC_STACK_OK;
177 }
178
179 /**
180  * Error log callback called by SQLite stack in case of error
181  */
182 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
183 {
184     (void) pArg;
185     (void) iErrCode;
186     (void) zMsg;
187     OIC_LOG_V(DEBUG,TAG, "%s : (%d) %s", __func__, iErrCode, zMsg);
188 }
189
190 OCStackResult PDMInit(const char *path)
191 {
192     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
193
194     if (NULL != g_db)
195     {
196         OIC_LOG_V(DEBUG, TAG, "OUT %s: the database already has been created", __func__);
197         return OC_STACK_OK;
198     }
199
200     int rc;
201     const char *dbPath = NULL;
202     if (SQLITE_OK !=  sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
203     {
204         OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
205     }
206
207     if (NULL == path || !*path)
208     {
209         dbPath = DB_FILE;
210     }
211     else
212     {
213         dbPath = path;
214     }
215     rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
216     if (SQLITE_OK != rc)
217     {
218         OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
219         return OC_STACK_ERROR;
220     }
221     //create DB in case DB doesn't exists
222     rc = sqlite3_exec(g_db, PDM_CREATE_DB, NULL, NULL, NULL);
223     if (SQLITE_OK != rc)
224     {
225         OIC_LOG_V(INFO, TAG, "ERROR: Can't create the database: %s", sqlite3_errmsg(g_db));
226         return OC_STACK_ERROR;
227     }
228
229     gInit = true;
230
231     /*
232      * Remove PDM_DEVICE_INIT status devices.
233      * PDM_DEVICE_INIT means that the OTM process is in progress.
234      * PDM_DEVICE_INIT state device can be existed when the program is terminated during the OTM process in progress.
235      * For this reason, PDM_DEVICE_INIT devices should be removed at PDM initialization time.
236      */
237     if(OC_STACK_OK != PDMDeleteDeviceWithState(PDM_DEVICE_INIT))
238     {
239         OIC_LOG_V(WARNING, TAG, "Failed to delete init state devices.");
240     }
241
242     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
243
244     return OC_STACK_OK;
245 }
246
247
248 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
249 {
250     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
251
252     CHECK_PDM_INIT();
253
254     if (NULL == UUID)
255     {
256         return OC_STACK_INVALID_PARAM;
257     }
258
259     sqlite3_stmt *stmt = 0;
260     int res =0;
261     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
262                               PDM_SQLITE_INSERT_T_DEVICE_LIST_SIZE, &stmt, NULL);
263     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
264
265     res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
266     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
267
268     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_INIT);
269     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
270
271     res = sqlite3_step(stmt);
272     if (SQLITE_DONE != res)
273     {
274         if (SQLITE_CONSTRAINT == res)
275         {
276             //new OCStack result code
277             OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
278             sqlite3_finalize(stmt);
279             return OC_STACK_DUPLICATE_UUID;
280         }
281         OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
282         sqlite3_finalize(stmt);
283         return OC_STACK_ERROR;
284     }
285     sqlite3_finalize(stmt);
286
287     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
288     return OC_STACK_OK;
289 }
290
291 /**
292  *function to get Id for given UUID
293  */
294 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
295 {
296     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
297
298     CHECK_PDM_INIT();
299
300     sqlite3_stmt *stmt = 0;
301     int res = 0;
302     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE,
303                              &stmt, NULL);
304     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
305
306     res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
307     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
308
309     OIC_LOG(DEBUG, TAG, "Binding Done");
310     while (SQLITE_ROW == sqlite3_step(stmt))
311     {
312         int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
313         OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
314         *id = tempId;
315         sqlite3_finalize(stmt);
316         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
317         return OC_STACK_OK;
318     }
319     sqlite3_finalize(stmt);
320     return OC_STACK_INVALID_PARAM;
321 }
322
323 /**
324  * Function to check duplication of device's Device ID.
325  */
326 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
327 {
328     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
329
330     CHECK_PDM_INIT();
331     if (NULL == UUID || NULL == result)
332     {
333         OIC_LOG(ERROR, TAG, "UUID or result is NULL");
334         return OC_STACK_INVALID_PARAM;
335     }
336     sqlite3_stmt *stmt = 0;
337     int res = 0;
338     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE,
339                              &stmt, NULL);
340     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
341
342     res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, UUID, UUID_LENGTH, SQLITE_STATIC);
343     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
344
345     OIC_LOG(DEBUG, TAG, "Binding Done");
346     bool retValue = false;
347     while(SQLITE_ROW == sqlite3_step(stmt))
348     {
349         OIC_LOG(INFO, TAG, "Duplicated UUID");
350         retValue = true;
351     }
352
353     sqlite3_finalize(stmt);
354     *result = retValue;
355
356     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
357     return OC_STACK_OK;
358 }
359
360 /**
361  * Function to add link in sqlite
362  */
363 static OCStackResult addlink(int id1, int id2)
364 {
365     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
366
367     CHECK_PDM_INIT();
368
369     sqlite3_stmt *stmt = 0;
370     int res = 0;
371     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
372                               PDM_SQLITE_INSERT_LINK_DATA_SIZE, &stmt, NULL);
373     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
374
375     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
376     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
377
378     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
379     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
380
381     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_ACTIVE);
382     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
383
384     if (sqlite3_step(stmt) != SQLITE_DONE)
385     {
386         OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
387         sqlite3_finalize(stmt);
388         return OC_STACK_ERROR;
389     }
390     sqlite3_finalize(stmt);
391     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
392     return OC_STACK_OK;
393 }
394
395 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
396 {
397     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
398
399     CHECK_PDM_INIT();
400     if (NULL == UUID1 || NULL == UUID2)
401     {
402         OIC_LOG(ERROR, TAG, "Invalid PARAM");
403         return  OC_STACK_INVALID_PARAM;
404     }
405
406     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
407     if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
408     {
409         OIC_LOG(ERROR, TAG, "Internal error occured");
410         return OC_STACK_ERROR;
411     }
412     if (PDM_DEVICE_ACTIVE != state)
413     {
414         OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
415         return OC_STACK_INVALID_PARAM;
416     }
417
418     state = PDM_DEVICE_UNKNOWN;
419     if (OC_STACK_OK != PDMGetDeviceState(UUID2, &state))
420     {
421         OIC_LOG(ERROR, TAG, "Internal error occured");
422         return OC_STACK_ERROR;
423     }
424     if (PDM_DEVICE_ACTIVE != state)
425     {
426         OIC_LOG_V(ERROR, TAG, "UUID2: Device state is not active : %d", state);
427         return OC_STACK_INVALID_PARAM;
428     }
429
430     int id1 = 0;
431     if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
432     {
433         OIC_LOG(ERROR, TAG, "Requested value not found");
434         return OC_STACK_INVALID_PARAM;
435     }
436     int id2 = 0;
437     if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
438     {
439         OIC_LOG(ERROR, TAG, "Requested value not found");
440         return OC_STACK_INVALID_PARAM;
441     }
442
443     ASCENDING_ORDER(id1, id2);
444     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
445     return addlink(id1, id2);
446 }
447
448 /**
449  * Function to remove created link
450  */
451 static OCStackResult removeLink(int id1, int id2)
452 {
453     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
454
455     CHECK_PDM_INIT();
456
457     int res = 0;
458     sqlite3_stmt *stmt = 0;
459     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK,
460                              PDM_SQLITE_DELETE_LINK_SIZE, &stmt, NULL);
461     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
462
463     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
464     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
465
466     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
467     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
468
469     if (SQLITE_DONE != sqlite3_step(stmt))
470     {
471         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
472         sqlite3_finalize(stmt);
473         return OC_STACK_ERROR;
474     }
475     sqlite3_finalize(stmt);
476     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
477     return OC_STACK_OK;
478 }
479
480 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
481 {
482     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
483
484     CHECK_PDM_INIT();
485     if (NULL == UUID1 || NULL == UUID2)
486     {
487         OIC_LOG(ERROR, TAG, "Invalid PARAM");
488         return  OC_STACK_INVALID_PARAM;
489     }
490
491     int id1 = 0;
492     if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
493     {
494         OIC_LOG(ERROR, TAG, "Requested value not found");
495         return OC_STACK_INVALID_PARAM;
496     }
497
498     int id2 = 0;
499     if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
500     {
501         OIC_LOG(ERROR, TAG, "Requested value not found");
502         return OC_STACK_INVALID_PARAM;
503     }
504     ASCENDING_ORDER(id1, id2);
505     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
506     return removeLink(id1, id2);
507 }
508
509 static OCStackResult removeFromDeviceList(int id)
510 {
511     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
512
513     CHECK_PDM_INIT();
514
515     sqlite3_stmt *stmt = 0;
516     int res = 0;
517     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
518                               PDM_SQLITE_DELETE_DEVICE_SIZE, &stmt, NULL);
519     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
520
521     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
522     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
523
524     if (sqlite3_step(stmt) != SQLITE_DONE)
525     {
526         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
527         sqlite3_finalize(stmt);
528         return OC_STACK_ERROR;
529     }
530     sqlite3_finalize(stmt);
531     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
532     return OC_STACK_OK;
533 }
534
535 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
536 {
537     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
538
539     CHECK_PDM_INIT();
540     if (NULL == UUID)
541     {
542         return OC_STACK_INVALID_PARAM;
543     }
544     int id = 0;
545     if (OC_STACK_OK != getIdForUUID(UUID, &id))
546     {
547         OIC_LOG(ERROR, TAG, "Requested value not found");
548         return OC_STACK_INVALID_PARAM;
549     }
550     begin();
551     if(OC_STACK_OK != removeFromDeviceList(id))
552     {
553         rollback();
554         OIC_LOG(ERROR, TAG, "Requested value not found");
555         return OC_STACK_ERROR;
556     }
557     commit();
558     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
559     return OC_STACK_OK;
560 }
561
562
563 static OCStackResult updateLinkState(int id1, int id2, int state)
564 {
565     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
566
567     CHECK_PDM_INIT();
568
569     sqlite3_stmt *stmt = 0;
570     int res = 0 ;
571     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
572                               PDM_SQLITE_UPDATE_LINK_SIZE, &stmt, NULL);
573     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
574
575     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
576     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
577
578     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
579     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
580
581     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
582     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
583
584     if (SQLITE_DONE != sqlite3_step(stmt))
585     {
586         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
587         sqlite3_finalize(stmt);
588         return OC_STACK_ERROR;
589     }
590     sqlite3_finalize(stmt);
591     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
592     return OC_STACK_OK;
593 }
594
595 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
596 {
597     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
598
599     CHECK_PDM_INIT();
600     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
601     {
602         OIC_LOG(ERROR, TAG, "Invalid PARAM");
603         return  OC_STACK_INVALID_PARAM;
604     }
605
606     int id1 = 0;
607     if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
608     {
609         OIC_LOG(ERROR, TAG, "Requested value not found");
610         return OC_STACK_INVALID_PARAM;
611     }
612
613     int id2 = 0;
614     if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
615     {
616         OIC_LOG(ERROR, TAG, "Requested value not found");
617         return OC_STACK_INVALID_PARAM;
618     }
619     ASCENDING_ORDER(id1, id2);
620     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
621     return updateLinkState(id1, id2, PDM_DEVICE_STALE);
622 }
623
624 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
625 {
626     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
627
628     CHECK_PDM_INIT();
629     if (NULL != *uuidList)
630     {
631         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
632         return OC_STACK_INVALID_PARAM;
633     }
634     sqlite3_stmt *stmt = 0;
635     int res = 0;
636     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
637                               PDM_SQLITE_LIST_ALL_UUID_SIZE, &stmt, NULL);
638     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
639
640     size_t counter  = 0;
641     while (SQLITE_ROW == sqlite3_step(stmt))
642     {
643         const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
644         OicUuid_t *uid = (OicUuid_t *)ptr;
645         OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
646         if (NULL == temp)
647         {
648             OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
649             sqlite3_finalize(stmt);
650             return OC_STACK_NO_MEMORY;
651         }
652         memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
653         LL_PREPEND(*uuidList,temp);
654         ++counter;
655     }
656     *numOfDevices = counter;
657     sqlite3_finalize(stmt);
658     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
659     return OC_STACK_OK;
660 }
661
662 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
663 {
664     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
665
666     CHECK_PDM_INIT();
667
668     sqlite3_stmt *stmt = 0;
669     int res = 0;
670     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
671                               PDM_SQLITE_GET_UUID_SIZE, &stmt, NULL);
672     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
673
674     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
675     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
676
677     while (SQLITE_ROW == sqlite3_step(stmt))
678     {
679         const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
680         memcpy(uid, ptr, sizeof(OicUuid_t));
681
682         int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
683         if(PDM_DEVICE_STALE == temp)
684         {
685             if(result)
686             {
687                 *result = true;
688             }
689         }
690         else
691         {
692             if(result)
693             {
694                 *result = false;
695             }
696         }
697         sqlite3_finalize(stmt);
698         return OC_STACK_OK;
699     }
700     sqlite3_finalize(stmt);
701     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
702     return OC_STACK_INVALID_PARAM;
703 }
704
705 void PDMFreeLinkedDevices(OCUuidList_t *uuidList)
706 {
707     OCUuidList_t *p1 = NULL;
708     OCUuidList_t *p2 = NULL;
709     LL_FOREACH_SAFE(uuidList, p1, p2)
710     {
711         LL_DELETE(uuidList, p1);
712         OICFree(p1);
713     }
714 }
715
716 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
717 {
718     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
719
720     CHECK_PDM_INIT();
721     if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
722     {
723         return OC_STACK_INVALID_PARAM;
724     }
725     if (NULL != *UUIDLIST )
726     {
727         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
728         return OC_STACK_INVALID_PARAM;
729     }
730     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
731     OCStackResult ret = PDMGetDeviceState(UUID, &state);
732     if (OC_STACK_OK != ret)
733     {
734         OIC_LOG(ERROR, TAG, "Internal error occured");
735         return OC_STACK_ERROR;
736     }
737     if (PDM_DEVICE_ACTIVE != state)
738     {
739         OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
740         return OC_STACK_INVALID_PARAM;
741     }
742     int id = 0;
743     if (OC_STACK_OK != getIdForUUID(UUID, &id))
744     {
745         OIC_LOG(ERROR, TAG, "Requested value not found");
746         return OC_STACK_INVALID_PARAM;
747     }
748
749
750     sqlite3_stmt *stmt = 0;
751     int res = 0;
752     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
753                               PDM_SQLITE_GET_LINKED_DEVICES_SIZE, &stmt, NULL);
754     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
755
756     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
757     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
758
759     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
760     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
761
762     size_t counter  = 0;
763     while (SQLITE_ROW == sqlite3_step(stmt))
764     {
765         int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
766         int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
767
768         OicUuid_t temp = {{0,}};
769         if (i1 != id)
770         {
771             getUUIDforId(i1, &temp, NULL);
772         }
773         if (i2 != id)
774         {
775             getUUIDforId(i2, &temp, NULL);
776         }
777
778         OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
779         if (NULL == tempNode)
780         {
781             OIC_LOG(ERROR, TAG, "No Memory");
782             sqlite3_finalize(stmt);
783             return OC_STACK_NO_MEMORY;
784         }
785         memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
786         LL_PREPEND(*UUIDLIST,tempNode);
787         ++counter;
788     }
789     *numOfDevices = counter;
790      sqlite3_finalize(stmt);
791      OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
792      return OC_STACK_OK;
793 }
794
795 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
796 {
797     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
798
799     CHECK_PDM_INIT();
800     if (NULL != *staleDevList)
801     {
802         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
803         return OC_STACK_INVALID_PARAM;
804     }
805
806     sqlite3_stmt *stmt = 0;
807     int res = 0;
808     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
809                               PDM_SQLITE_GET_STALE_INFO_SIZE, &stmt, NULL);
810     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
811
812     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_DEVICE_STALE);
813     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
814
815     size_t counter  = 0;
816     while (SQLITE_ROW == sqlite3_step(stmt))
817     {
818         int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
819         int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
820         OicUuid_t temp1 = {{0,}};
821         OicUuid_t temp2 = {{0,}};;
822         getUUIDforId(i1, &temp1, NULL);
823         getUUIDforId(i2, &temp2, NULL);
824
825         OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
826         if (NULL == tempNode)
827         {
828             OIC_LOG(ERROR, TAG, "No Memory");
829             sqlite3_finalize(stmt);
830             return OC_STACK_NO_MEMORY;
831         }
832         memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
833         memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
834         LL_PREPEND(*staleDevList, tempNode);
835         ++counter;
836     }
837     *numOfDevices = counter;
838     sqlite3_finalize(stmt);
839     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
840     return OC_STACK_OK;
841 }
842
843 OCStackResult PDMClose(void)
844 {
845     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
846
847     gInit = false;
848
849     if (g_db)
850     {
851         int res = 0;
852         res = sqlite3_close(g_db);
853         g_db = NULL;
854         PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
855     }
856
857     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
858     return OC_STACK_OK;
859 }
860
861 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
862 {
863     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
864
865     if(ptr)
866     {
867         OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
868         LL_FOREACH_SAFE(ptr, tmp1, tmp2)
869         {
870             LL_DELETE(ptr, tmp1);
871             OICFree(tmp1);
872         }
873     }
874
875     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
876 }
877
878 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
879 {
880     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
881
882     if(ptr)
883     {
884         OCPairList_t *tmp1 = NULL,*tmp2=NULL;
885         LL_FOREACH_SAFE(ptr, tmp1, tmp2)
886         {
887             LL_DELETE(ptr, tmp1);
888             OICFree(tmp1);
889         }
890     }
891
892     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
893 }
894
895 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
896                                bool* result)
897 {
898     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
899
900     CHECK_PDM_INIT();
901     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
902     {
903         return OC_STACK_INVALID_PARAM;
904     }
905     int id1 = 0;
906     int id2 = 0;
907     if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
908     {
909         OIC_LOG(ERROR, TAG, "Requested value not found");
910         return OC_STACK_INVALID_PARAM;
911     }
912
913     if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
914     {
915         OIC_LOG(ERROR, TAG, "Requested value not found");
916         return OC_STACK_INVALID_PARAM;
917     }
918
919     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
920     if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
921     {
922         OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
923         return OC_STACK_ERROR;
924     }
925     if (PDM_DEVICE_ACTIVE != state)
926     {
927         OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
928         return OC_STACK_INVALID_PARAM;
929     }
930
931     state = PDM_DEVICE_UNKNOWN;
932     if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
933     {
934         OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
935         return OC_STACK_ERROR;
936     }
937     if (PDM_DEVICE_ACTIVE != state)
938     {
939         OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
940         return OC_STACK_INVALID_PARAM;
941     }
942
943     ASCENDING_ORDER(id1, id2);
944
945     sqlite3_stmt *stmt = 0;
946     int res = 0;
947     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
948                               PDM_SQLITE_GET_DEVICE_LINKS_SIZE, &stmt, NULL);
949     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
950
951     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
952     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
953
954     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
955     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
956
957     bool ret = false;
958     while(SQLITE_ROW == sqlite3_step(stmt))
959     {
960         OIC_LOG(INFO, TAG, "Link already exists between devices");
961         ret = true;
962     }
963     sqlite3_finalize(stmt);
964     *result = ret;
965     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
966     return OC_STACK_OK;
967 }
968
969 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
970 {
971     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
972
973     CHECK_PDM_INIT();
974
975     sqlite3_stmt *stmt = 0;
976     int res = 0 ;
977     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_DEVICE,
978                               PDM_SQLITE_UPDATE_DEVICE_SIZE, &stmt, NULL);
979     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
980
981     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
982     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
983
984     res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, uuid, UUID_LENGTH, SQLITE_STATIC);
985     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
986
987     if (SQLITE_DONE != sqlite3_step(stmt))
988     {
989         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
990         sqlite3_finalize(stmt);
991         return OC_STACK_ERROR;
992     }
993     sqlite3_finalize(stmt);
994     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
995     return OC_STACK_OK;
996 }
997
998 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
999 {
1000     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1001
1002     CHECK_PDM_INIT();
1003
1004     sqlite3_stmt *stmt = 0;
1005     int res = 0 ;
1006
1007     int id = 0;
1008     if (OC_STACK_OK != getIdForUUID(devUuid, &id))
1009     {
1010         OIC_LOG(ERROR, TAG, "Requested value not found");
1011         return OC_STACK_INVALID_PARAM;
1012     }
1013
1014     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
1015                               PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE_SIZE,
1016                                &stmt, NULL);
1017     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1018
1019     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
1020     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1021
1022     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
1023     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1024
1025     if (SQLITE_DONE != sqlite3_step(stmt))
1026     {
1027         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1028         sqlite3_finalize(stmt);
1029         return OC_STACK_ERROR;
1030     }
1031     sqlite3_finalize(stmt);
1032     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1033     return OC_STACK_OK;
1034 }
1035
1036 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
1037 {
1038     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1039
1040     OCStackResult res = OC_STACK_ERROR;
1041
1042     CHECK_PDM_INIT();
1043     if (NULL == uuid)
1044     {
1045         OIC_LOG(ERROR, TAG, "Invalid PARAM");
1046         return  OC_STACK_INVALID_PARAM;
1047     }
1048     begin();
1049
1050     if(PDM_DEVICE_STALE == state)
1051     {
1052         res = updateLinkForStaleDevice(uuid);
1053         if (OC_STACK_OK != res)
1054         {
1055             rollback();
1056             OIC_LOG(ERROR, TAG, "unable to update links");
1057             return res;
1058         }
1059     }
1060
1061     res = updateDeviceState(uuid, state);
1062     if (OC_STACK_OK != res)
1063     {
1064         rollback();
1065         OIC_LOG(ERROR, TAG, "unable to update device state");
1066         return res;
1067     }
1068     commit();
1069     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1070     return OC_STACK_OK;
1071 }
1072
1073 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
1074 {
1075     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1076
1077     CHECK_PDM_INIT();
1078     if (NULL == uuid || NULL == result)
1079     {
1080         OIC_LOG(ERROR, TAG, "UUID or result is NULL");
1081         return OC_STACK_INVALID_PARAM;
1082     }
1083
1084     sqlite3_stmt *stmt = 0;
1085     int res = 0;
1086     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_STATUS, PDM_SQLITE_GET_DEVICE_STATUS_SIZE,
1087                               &stmt, NULL);
1088     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1089
1090     res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_FIRST, uuid, UUID_LENGTH, SQLITE_STATIC);
1091     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1092
1093     *result = PDM_DEVICE_UNKNOWN;
1094     while(SQLITE_ROW == sqlite3_step(stmt))
1095     {
1096         int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
1097         OIC_LOG_V(DEBUG, TAG, "Device state is %d", tempStaleStateFromDb);
1098         *result = (PdmDeviceState_t)tempStaleStateFromDb;
1099     }
1100     sqlite3_finalize(stmt);
1101     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1102     return OC_STACK_OK;
1103 }
1104
1105 OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state)
1106 {
1107     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1108
1109     CHECK_PDM_INIT();
1110     if (PDM_DEVICE_ACTIVE != state && PDM_DEVICE_STALE != state &&
1111         PDM_DEVICE_INIT != state && PDM_DEVICE_UNKNOWN != state)
1112     {
1113         return OC_STACK_INVALID_PARAM;
1114     }
1115
1116     sqlite3_stmt *stmt = 0;
1117     int res =0;
1118     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE_WITH_STATE,
1119                               (int)strlen(PDM_SQLITE_DELETE_DEVICE_WITH_STATE) + 1, &stmt, NULL);
1120     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1121
1122     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
1123     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
1124
1125     if (SQLITE_DONE != sqlite3_step(stmt))
1126     {
1127         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1128         sqlite3_finalize(stmt);
1129         return OC_STACK_ERROR;
1130     }
1131     sqlite3_finalize(stmt);
1132     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1133     return OC_STACK_OK;
1134 }