d502fc2938f1a3ac26aa34b056bd8491fd06c276
[platform/upstream/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
26 #include "sqlite3.h"
27 #include "logger.h"
28 #include "oic_malloc.h"
29 #include "provisioningdatabasemanager.h"
30 #include "pmutility.h"
31 #include "oic_string.h"
32 #include "utlist.h"
33 #include "srmutility.h"
34
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 HEX_UUID_STR_LENGTH (UUID_LENGTH*2 + 4)
48
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);"
51
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));"
54 /**
55  * Macro to verify sqlite success.
56  * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
57  */
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)
61
62
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 = ?"
88
89 #define ASCENDING_ORDER(id1, id2) do{if( (id1) > (id2) )\
90   { int temp; temp = id1; id1 = id2; id2 = temp; }}while(0)
91
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)
95
96 static sqlite3 *g_db = NULL;
97 static bool gInit = false;  /* Only if we can open sqlite db successfully, gInit is true. */
98
99 /**
100  * function to create DB in case DB doesn't exists
101  */
102 static OCStackResult createDB(const char* path)
103 {
104     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
105
106     int result = 0;
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);
109
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);
112
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);
116
117     OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
118     gInit = true;
119
120     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
121
122     return OC_STACK_OK;
123 }
124
125
126 /**
127  * Function to begin any transaction
128  */
129 static OCStackResult begin()
130 {
131     int res = 0;
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);
134     return OC_STACK_OK;
135 }
136
137 /**
138  * Function to commit any transaction
139  */
140 static OCStackResult commit()
141 {
142     int res = 0;
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);
145     return OC_STACK_OK;
146 }
147
148 /**
149  * Function to rollback any transaction
150  */
151 static OCStackResult rollback()
152 {
153     int res = 0;
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);
156     return OC_STACK_OK;
157 }
158
159 /**
160  * Function to convert UUID into hex representation
161  */
162 static bool convertUuidToHexString(const OicUuid_t* uuidOfDevice, char* uuidHexString)
163 {
164     if(NULL == uuidOfDevice || NULL == uuidHexString)
165     {
166         OIC_LOG(ERROR, TAG, "convertUuidToHexString : Invalid param");
167         return false;
168     }
169
170     char *strUUID = NULL;
171     OCStackResult ret = ConvertUuidToStr(uuidOfDevice, &strUUID);
172     if(OC_STACK_OK != ret)
173     {
174         OIC_LOG(ERROR, TAG, "SendDeleteCredentialRequest : Failed to canonical UUID encoding");
175         return OC_STACK_ERROR;
176
177     }
178     char* headPtr = strUUID;
179     strncat(uuidHexString, "x'",2);
180     while(('\0' != *headPtr))
181     {
182         char tmp = *headPtr;
183         if('-' != tmp)
184         {
185             strncat(uuidHexString, &tmp,1);
186         }
187         headPtr++;
188     }
189     strncat(uuidHexString, "'",1);
190
191     OICFree(strUUID);
192     return true;
193 }
194
195 /**
196  * Error log callback called by SQLite stack in case of error
197  */
198 void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
199 {
200     (void) pArg;
201     (void) iErrCode;
202     (void) zMsg;
203     OIC_LOG_V(DEBUG,TAG, "%s : (%d) %s", __func__, iErrCode, zMsg);
204 }
205
206 OCStackResult PDMInit(const char *path)
207 {
208     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
209
210     int rc;
211     const char *dbPath = NULL;
212     if (SQLITE_OK !=  sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
213     {
214         OIC_LOG(INFO, TAG, "Unable to enable debug log of sqlite");
215     }
216
217     if (NULL == path || !*path)
218     {
219         dbPath = DB_FILE;
220     }
221     else
222     {
223         dbPath = path;
224     }
225     rc = sqlite3_open_v2(dbPath, &g_db, SQLITE_OPEN_READWRITE, NULL);
226     if (SQLITE_OK != rc)
227     {
228         OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
229         sqlite3_close(g_db);
230         OCStackResult ret = createDB(dbPath);
231         if (OC_STACK_OK != ret)
232         {
233             sqlite3_close(g_db);
234         }
235         return ret;
236     }
237     gInit = true;
238
239     /*
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.
244      */
245     if(OC_STACK_OK != PDMDeleteDeviceWithState(PDM_DEVICE_INIT))
246     {
247         OIC_LOG_V(WARNING, TAG, "Failed to delete init state devices.");
248     }
249
250     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
251
252     return OC_STACK_OK;
253 }
254
255
256 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
257 {
258     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
259
260     CHECK_PDM_INIT(TAG);
261     if (NULL == UUID)
262     {
263         return OC_STACK_INVALID_PARAM;
264     }
265
266     sqlite3_stmt *stmt = 0;
267     int res =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);
271
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);
274
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);
277
278     res = sqlite3_step(stmt);
279     if (SQLITE_DONE != res)
280     {
281         if (SQLITE_CONSTRAINT == res)
282         {
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;
287         }
288         OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
289         sqlite3_finalize(stmt);
290         return OC_STACK_ERROR;
291     }
292     sqlite3_finalize(stmt);
293
294     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
295     return OC_STACK_OK;
296 }
297
298 /**
299  *function to get Id for given UUID
300  */
301 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
302 {
303     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
304
305     sqlite3_stmt *stmt = 0;
306     int res = 0;
307     char sqlStat[PDM_SQLITE_GET_ID_SIZE - 1 + HEX_UUID_STR_LENGTH];
308     char hexUUID[HEX_UUID_STR_LENGTH];
309
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));
313
314     if (!convertUuidToHexString(UUID, hexUUID))
315     {
316         return OC_STACK_ERROR;
317     }
318
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);
322
323     while (SQLITE_ROW == sqlite3_step(stmt))
324     {
325         int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
326         OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
327         *id = tempId;
328         sqlite3_finalize(stmt);
329         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
330         return OC_STACK_OK;
331     }
332
333     sqlite3_finalize(stmt);
334     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
335
336     return OC_STACK_INVALID_PARAM;
337 }
338
339 /**
340  * Function to check duplication of device's Device ID.
341  */
342 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
343 {
344     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
345
346     CHECK_PDM_INIT(TAG);
347     if (NULL == UUID || NULL == result)
348     {
349         OIC_LOG(ERROR, TAG, "UUID or result is NULL");
350         return OC_STACK_INVALID_PARAM;
351     }
352     sqlite3_stmt *stmt = 0;
353     int res = 0;
354     char sqlStat[PDM_SQLITE_GET_ID_SIZE - 1 + HEX_UUID_STR_LENGTH];
355     char hexUUID[HEX_UUID_STR_LENGTH];
356
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));
360
361     if (!convertUuidToHexString(UUID, hexUUID))
362     {
363         return OC_STACK_ERROR;
364     }
365
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);
369
370     bool retValue = false;
371     while(SQLITE_ROW == sqlite3_step(stmt))
372     {
373         OIC_LOG(INFO, TAG, "Duplicated UUID");
374         retValue = true;
375     }
376
377     sqlite3_finalize(stmt);
378     *result = retValue;
379
380     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
381     return OC_STACK_OK;
382 }
383
384 /**
385  * Function to add link in sqlite
386  */
387 static OCStackResult addlink(int id1, int id2)
388 {
389     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
390
391     sqlite3_stmt *stmt = 0;
392     int res = 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);
396
397     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
398     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
399
400     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
401     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
402
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);
405
406     if (sqlite3_step(stmt) != SQLITE_DONE)
407     {
408         OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
409         sqlite3_finalize(stmt);
410         return OC_STACK_ERROR;
411     }
412     sqlite3_finalize(stmt);
413     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
414     return OC_STACK_OK;
415 }
416
417 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
418 {
419     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
420
421     CHECK_PDM_INIT(TAG);
422     if (NULL == UUID1 || NULL == UUID2)
423     {
424         OIC_LOG(ERROR, TAG, "Invalid PARAM");
425         return  OC_STACK_INVALID_PARAM;
426     }
427
428     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
429     if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
430     {
431         OIC_LOG(ERROR, TAG, "Internal error occured");
432         return OC_STACK_ERROR;
433     }
434     if (PDM_DEVICE_ACTIVE != state)
435     {
436         OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
437         return OC_STACK_INVALID_PARAM;
438     }
439
440     state = PDM_DEVICE_UNKNOWN;
441     if (OC_STACK_OK != PDMGetDeviceState(UUID2, &state))
442     {
443         OIC_LOG(ERROR, TAG, "Internal error occured");
444         return OC_STACK_ERROR;
445     }
446     if (PDM_DEVICE_ACTIVE != state)
447     {
448         OIC_LOG_V(ERROR, TAG, "UUID2: Device state is not active : %d", state);
449         return OC_STACK_INVALID_PARAM;
450     }
451
452     int id1 = 0;
453     if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
454     {
455         OIC_LOG(ERROR, TAG, "Requested value not found");
456         return OC_STACK_INVALID_PARAM;
457     }
458     int id2 = 0;
459     if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
460     {
461         OIC_LOG(ERROR, TAG, "Requested value not found");
462         return OC_STACK_INVALID_PARAM;
463     }
464
465     ASCENDING_ORDER(id1, id2);
466     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
467     return addlink(id1, id2);
468 }
469
470 /**
471  * Function to remove created link
472  */
473 static OCStackResult removeLink(int id1, int id2)
474 {
475     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
476
477     int res = 0;
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);
481
482     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
483     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
484
485     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
486     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
487
488     if (SQLITE_DONE != sqlite3_step(stmt))
489     {
490         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
491         sqlite3_finalize(stmt);
492         return OC_STACK_ERROR;
493     }
494     sqlite3_finalize(stmt);
495     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
496     return OC_STACK_OK;
497 }
498
499 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
500 {
501     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
502
503     CHECK_PDM_INIT(TAG);
504     if (NULL == UUID1 || NULL == UUID2)
505     {
506         OIC_LOG(ERROR, TAG, "Invalid PARAM");
507         return  OC_STACK_INVALID_PARAM;
508     }
509
510     int id1 = 0;
511     if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
512     {
513         OIC_LOG(ERROR, TAG, "Requested value not found");
514         return OC_STACK_INVALID_PARAM;
515     }
516
517     int id2 = 0;
518     if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
519     {
520         OIC_LOG(ERROR, TAG, "Requested value not found");
521         return OC_STACK_INVALID_PARAM;
522     }
523     ASCENDING_ORDER(id1, id2);
524     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
525     return removeLink(id1, id2);
526 }
527
528 static OCStackResult removeFromDeviceList(int id)
529 {
530     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
531
532     sqlite3_stmt *stmt = 0;
533     int res = 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);
537
538     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
539     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
540
541     if (sqlite3_step(stmt) != SQLITE_DONE)
542     {
543         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
544         sqlite3_finalize(stmt);
545         return OC_STACK_ERROR;
546     }
547     sqlite3_finalize(stmt);
548     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
549     return OC_STACK_OK;
550 }
551
552 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
553 {
554     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
555
556     CHECK_PDM_INIT(TAG);
557     if (NULL == UUID)
558     {
559         return OC_STACK_INVALID_PARAM;
560     }
561     int id = 0;
562     if (OC_STACK_OK != getIdForUUID(UUID, &id))
563     {
564         OIC_LOG(ERROR, TAG, "Requested value not found");
565         return OC_STACK_INVALID_PARAM;
566     }
567     begin();
568     if(OC_STACK_OK != removeFromDeviceList(id))
569     {
570         rollback();
571         OIC_LOG(ERROR, TAG, "Requested value not found");
572         return OC_STACK_ERROR;
573     }
574     commit();
575     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
576     return OC_STACK_OK;
577 }
578
579
580 static OCStackResult updateLinkState(int id1, int id2, int state)
581 {
582     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
583
584     sqlite3_stmt *stmt = 0;
585     int res = 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);
589
590     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
591     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
592
593     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
594     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
595
596     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
597     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
598
599     if (SQLITE_DONE != sqlite3_step(stmt))
600     {
601         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
602         sqlite3_finalize(stmt);
603         return OC_STACK_ERROR;
604     }
605     sqlite3_finalize(stmt);
606     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
607     return OC_STACK_OK;
608 }
609
610 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
611 {
612     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
613
614     CHECK_PDM_INIT(TAG);
615     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
616     {
617         OIC_LOG(ERROR, TAG, "Invalid PARAM");
618         return  OC_STACK_INVALID_PARAM;
619     }
620
621     int id1 = 0;
622     if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
623     {
624         OIC_LOG(ERROR, TAG, "Requested value not found");
625         return OC_STACK_INVALID_PARAM;
626     }
627
628     int id2 = 0;
629     if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
630     {
631         OIC_LOG(ERROR, TAG, "Requested value not found");
632         return OC_STACK_INVALID_PARAM;
633     }
634     ASCENDING_ORDER(id1, id2);
635     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
636     return updateLinkState(id1, id2, PDM_DEVICE_STALE);
637 }
638
639 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
640 {
641     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
642
643     CHECK_PDM_INIT(TAG);
644     if (NULL != *uuidList)
645     {
646         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
647         return OC_STACK_INVALID_PARAM;
648     }
649     sqlite3_stmt *stmt = 0;
650     int res = 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);
654
655     size_t counter  = 0;
656     while (SQLITE_ROW == sqlite3_step(stmt))
657     {
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));
661         if (NULL == temp)
662         {
663             OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
664             sqlite3_finalize(stmt);
665             return OC_STACK_NO_MEMORY;
666         }
667         memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
668         LL_PREPEND(*uuidList,temp);
669         ++counter;
670     }
671     *numOfDevices = counter;
672     sqlite3_finalize(stmt);
673     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
674     return OC_STACK_OK;
675 }
676
677 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
678 {
679     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
680
681     sqlite3_stmt *stmt = 0;
682     int res = 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);
686
687     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
688     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
689
690     while (SQLITE_ROW == sqlite3_step(stmt))
691     {
692         const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
693         memcpy(uid, ptr, sizeof(OicUuid_t));
694
695         int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
696         if(PDM_DEVICE_STALE == temp)
697         {
698             if(result)
699             {
700                 *result = true;
701             }
702         }
703         else
704         {
705             if(result)
706             {
707                 *result = false;
708             }
709         }
710         sqlite3_finalize(stmt);
711         return OC_STACK_OK;
712     }
713     sqlite3_finalize(stmt);
714     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
715     return OC_STACK_INVALID_PARAM;
716 }
717
718 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
719 {
720     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
721
722     CHECK_PDM_INIT(TAG);
723     if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
724     {
725         return OC_STACK_INVALID_PARAM;
726     }
727     if (NULL != *UUIDLIST )
728     {
729         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
730         return OC_STACK_INVALID_PARAM;
731     }
732     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
733     OCStackResult ret = PDMGetDeviceState(UUID, &state);
734     if (OC_STACK_OK != ret)
735     {
736         OIC_LOG(ERROR, TAG, "Internal error occured");
737         return OC_STACK_ERROR;
738     }
739     if (PDM_DEVICE_ACTIVE != state)
740     {
741         OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
742         return OC_STACK_INVALID_PARAM;
743     }
744     int id = 0;
745     if (OC_STACK_OK != getIdForUUID(UUID, &id))
746     {
747         OIC_LOG(ERROR, TAG, "Requested value not found");
748         return OC_STACK_INVALID_PARAM;
749     }
750
751
752     sqlite3_stmt *stmt = 0;
753     int res = 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);
757
758     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
759     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
760
761     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
762     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
763
764     size_t counter  = 0;
765     while (SQLITE_ROW == sqlite3_step(stmt))
766     {
767         int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
768         int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
769
770         OicUuid_t temp = {{0,}};
771         if (i1 != id)
772         {
773             getUUIDforId(i1, &temp, NULL);
774         }
775         if (i2 != id)
776         {
777             getUUIDforId(i2, &temp, NULL);
778         }
779
780         OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
781         if (NULL == tempNode)
782         {
783             OIC_LOG(ERROR, TAG, "No Memory");
784             sqlite3_finalize(stmt);
785             return OC_STACK_NO_MEMORY;
786         }
787         memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
788         LL_PREPEND(*UUIDLIST,tempNode);
789         ++counter;
790     }
791     *numOfDevices = counter;
792      sqlite3_finalize(stmt);
793      OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
794      return OC_STACK_OK;
795 }
796
797 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
798 {
799     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
800
801     CHECK_PDM_INIT(TAG);
802     if (NULL != *staleDevList)
803     {
804         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
805         return OC_STACK_INVALID_PARAM;
806     }
807
808     sqlite3_stmt *stmt = 0;
809     int res = 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);
813
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);
816
817     size_t counter  = 0;
818     while (SQLITE_ROW == sqlite3_step(stmt))
819     {
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);
826
827         OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
828         if (NULL == tempNode)
829         {
830             OIC_LOG(ERROR, TAG, "No Memory");
831             sqlite3_finalize(stmt);
832             return OC_STACK_NO_MEMORY;
833         }
834         memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
835         memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
836         LL_PREPEND(*staleDevList, tempNode);
837         ++counter;
838     }
839     *numOfDevices = counter;
840     sqlite3_finalize(stmt);
841     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
842     return OC_STACK_OK;
843 }
844
845 OCStackResult PDMClose()
846 {
847     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
848
849     CHECK_PDM_INIT(TAG);
850     int res = 0;
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__);
854     return OC_STACK_OK;
855 }
856
857 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
858 {
859     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
860
861     if(ptr)
862     {
863         OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
864         LL_FOREACH_SAFE(ptr, tmp1, tmp2)
865         {
866             LL_DELETE(ptr, tmp1);
867             OICFree(tmp1);
868         }
869     }
870
871     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
872 }
873
874 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
875 {
876     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
877
878     if(ptr)
879     {
880         OCPairList_t *tmp1 = NULL,*tmp2=NULL;
881         LL_FOREACH_SAFE(ptr, tmp1, tmp2)
882         {
883             LL_DELETE(ptr, tmp1);
884             OICFree(tmp1);
885         }
886     }
887
888     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
889 }
890
891 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
892                                bool* result)
893 {
894     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
895
896     CHECK_PDM_INIT(TAG);
897     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
898     {
899         return OC_STACK_INVALID_PARAM;
900     }
901     int id1 = 0;
902     int id2 = 0;
903     if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
904     {
905         OIC_LOG(ERROR, TAG, "Requested value not found");
906         return OC_STACK_INVALID_PARAM;
907     }
908
909     if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
910     {
911         OIC_LOG(ERROR, TAG, "Requested value not found");
912         return OC_STACK_INVALID_PARAM;
913     }
914
915     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
916     if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
917     {
918         OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
919         return OC_STACK_ERROR;
920     }
921     if (PDM_DEVICE_ACTIVE != state)
922     {
923         OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
924         return OC_STACK_INVALID_PARAM;
925     }
926
927     state = PDM_DEVICE_UNKNOWN;
928     if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
929     {
930         OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
931         return OC_STACK_ERROR;
932     }
933     if (PDM_DEVICE_ACTIVE != state)
934     {
935         OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
936         return OC_STACK_INVALID_PARAM;
937     }
938
939     ASCENDING_ORDER(id1, id2);
940
941     sqlite3_stmt *stmt = 0;
942     int res = 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);
946
947     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
948     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
949
950     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
951     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
952
953     bool ret = false;
954     while(SQLITE_ROW == sqlite3_step(stmt))
955     {
956         OIC_LOG(INFO, TAG, "Link already exists between devices");
957         ret = true;
958     }
959     sqlite3_finalize(stmt);
960     *result = ret;
961     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
962     return OC_STACK_OK;
963 }
964
965 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
966 {
967     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
968     OIC_LOG_V(WARNING, TAG, "UUID is: %s", (char*) uuid);
969
970     sqlite3_stmt *stmt = 0;
971     int res = 0 ;
972     char sqlStat[PDM_SQLITE_UPDATE_DEVICE_SIZE - 1 + HEX_UUID_STR_LENGTH];
973     char hexUUID[HEX_UUID_STR_LENGTH];
974
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));
978
979     if (!convertUuidToHexString(uuid, hexUUID))
980     {
981         return OC_STACK_ERROR;
982     }
983
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);
987
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);
991
992     if (SQLITE_DONE != sqlite3_step(stmt))
993     {
994         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
995         sqlite3_finalize(stmt);
996         return OC_STACK_ERROR;
997     }
998     sqlite3_finalize(stmt);
999     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1000     return OC_STACK_OK;
1001 }
1002
1003 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
1004 {
1005     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1006
1007     sqlite3_stmt *stmt = 0;
1008     int res = 0 ;
1009
1010     int id = 0;
1011     if (OC_STACK_OK != getIdForUUID(devUuid, &id))
1012     {
1013         OIC_LOG(ERROR, TAG, "Requested value not found");
1014         return OC_STACK_INVALID_PARAM;
1015     }
1016
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,
1019                                &stmt, NULL);
1020     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1021
1022     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
1023     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1024
1025     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
1026     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1027
1028     if (SQLITE_DONE != sqlite3_step(stmt))
1029     {
1030         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1031         sqlite3_finalize(stmt);
1032         return OC_STACK_ERROR;
1033     }
1034     sqlite3_finalize(stmt);
1035     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1036     return OC_STACK_OK;
1037 }
1038
1039 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
1040 {
1041     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1042
1043     OCStackResult res = OC_STACK_ERROR;
1044
1045     CHECK_PDM_INIT(TAG);
1046     if (NULL == uuid)
1047     {
1048         OIC_LOG(ERROR, TAG, "Invalid PARAM");
1049         return  OC_STACK_INVALID_PARAM;
1050     }
1051     begin();
1052
1053     if(PDM_DEVICE_STALE == state)
1054     {
1055         res = updateLinkForStaleDevice(uuid);
1056         if (OC_STACK_OK != res)
1057         {
1058             rollback();
1059             OIC_LOG(ERROR, TAG, "unable to update links");
1060             return res;
1061         }
1062     }
1063
1064     res = updateDeviceState(uuid, state);
1065     if (OC_STACK_OK != res)
1066     {
1067         rollback();
1068         OIC_LOG(ERROR, TAG, "unable to update device state");
1069         return res;
1070     }
1071     commit();
1072     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1073     return OC_STACK_OK;
1074 }
1075
1076 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
1077 {
1078     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1079
1080     if (NULL == uuid || NULL == result)
1081     {
1082         OIC_LOG(ERROR, TAG, "UUID or result is NULL");
1083         return OC_STACK_INVALID_PARAM;
1084     }
1085
1086     sqlite3_stmt *stmt = 0;
1087     int res = 0;
1088     char sqlStat[PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1 + HEX_UUID_STR_LENGTH];
1089     char hexUUID[HEX_UUID_STR_LENGTH];
1090
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));
1094
1095     if (!convertUuidToHexString(uuid, hexUUID))
1096     {
1097         return OC_STACK_ERROR;
1098     }
1099
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);
1103
1104     *result = PDM_DEVICE_UNKNOWN;
1105     while(SQLITE_ROW == sqlite3_step(stmt))
1106     {
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;
1110     }
1111
1112     sqlite3_finalize(stmt);
1113     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1114
1115     return OC_STACK_OK;
1116 }
1117
1118 OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state)
1119 {
1120     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1121
1122     CHECK_PDM_INIT(TAG);
1123     if (PDM_DEVICE_ACTIVE != state && PDM_DEVICE_STALE != state &&
1124         PDM_DEVICE_INIT != state && PDM_DEVICE_UNKNOWN != state)
1125     {
1126         return OC_STACK_INVALID_PARAM;
1127     }
1128
1129     sqlite3_stmt *stmt = 0;
1130     int res =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);
1134
1135     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
1136     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1137
1138     if (SQLITE_DONE != sqlite3_step(stmt))
1139     {
1140         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1141         sqlite3_finalize(stmt);
1142         return OC_STACK_ERROR;
1143     }
1144     sqlite3_finalize(stmt);
1145     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1146     return OC_STACK_OK;
1147 }