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