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