c774b766cae0aad57b732b2aedcc859362c5c13d
[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 OC_STACK_OK;
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     while (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         break;
402     }
403
404     OICFree(uuidStr);
405     sqlite3_finalize(stmt);
406     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
407     return ret;
408 }
409
410 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
411 {
412     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
413
414     CHECK_PDM_INIT(TAG);
415     if (NULL == UUID)
416     {
417         return OC_STACK_INVALID_PARAM;
418     }
419
420     sqlite3_stmt *stmt = 0;
421     int res =0;
422     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_T_DEVICE_LIST,
423                               strlen(PDM_SQLITE_INSERT_T_DEVICE_LIST) + 1, &stmt, NULL);
424     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
425
426     res = sqlite3_bind_blob(stmt, PDM_BIND_INDEX_SECOND, UUID, UUID_LENGTH, SQLITE_STATIC);
427     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
428
429     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_INIT);
430     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
431
432     res = sqlite3_step(stmt);
433     if (SQLITE_DONE != res)
434     {
435         if (SQLITE_CONSTRAINT == res)
436         {
437             //new OCStack result code
438             OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
439             sqlite3_finalize(stmt);
440             return OC_STACK_DUPLICATE_UUID;
441         }
442         OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
443         sqlite3_finalize(stmt);
444         return OC_STACK_ERROR;
445     }
446     sqlite3_finalize(stmt);
447
448     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
449     return OC_STACK_OK;
450 }
451
452 /**
453  *function to get Id for given UUID
454  */
455 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
456 {
457     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
458
459     sqlite3_stmt *stmt = 0;
460     int res = 0;
461     char sqlStat[PDM_SQLITE_GET_ID_SIZE - 1 + HEX_UUID_STR_LENGTH];
462     char hexUUID[HEX_UUID_STR_LENGTH];
463
464     memset(sqlStat, 0, sizeof(sqlStat));
465     strncpy(sqlStat, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE - 1);
466     memset(hexUUID, 0, sizeof(hexUUID));
467
468     if (!convertUuidToHexString(UUID, hexUUID))
469     {
470         return OC_STACK_ERROR;
471     }
472
473     strncpy(sqlStat + PDM_SQLITE_GET_ID_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
474     res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
475     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
476
477     while (SQLITE_ROW == sqlite3_step(stmt))
478     {
479         int tempId = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
480         OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
481         *id = tempId;
482         sqlite3_finalize(stmt);
483         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
484         return OC_STACK_OK;
485     }
486
487     sqlite3_finalize(stmt);
488     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
489
490     return OC_STACK_INVALID_PARAM;
491 }
492
493 /**
494  * Function to check duplication of device's Device ID.
495  */
496 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
497 {
498     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
499
500     CHECK_PDM_INIT(TAG);
501     if (NULL == UUID || NULL == result)
502     {
503         OIC_LOG(ERROR, TAG, "UUID or result is NULL");
504         return OC_STACK_INVALID_PARAM;
505     }
506     sqlite3_stmt *stmt = 0;
507     int res = 0;
508     char sqlStat[PDM_SQLITE_GET_ID_SIZE - 1 + HEX_UUID_STR_LENGTH];
509     char hexUUID[HEX_UUID_STR_LENGTH];
510
511     memset(sqlStat, 0, sizeof(sqlStat));
512     strncpy(sqlStat, PDM_SQLITE_GET_ID, PDM_SQLITE_GET_ID_SIZE - 1);
513     memset(hexUUID, 0, sizeof(hexUUID));
514
515     if (!convertUuidToHexString(UUID, hexUUID))
516     {
517         return OC_STACK_ERROR;
518     }
519
520     strncpy(sqlStat + PDM_SQLITE_GET_ID_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
521     res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
522     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
523
524     bool retValue = false;
525     while(SQLITE_ROW == sqlite3_step(stmt))
526     {
527         OIC_LOG(INFO, TAG, "Duplicated UUID");
528         retValue = true;
529     }
530
531     sqlite3_finalize(stmt);
532     *result = retValue;
533
534     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
535     return OC_STACK_OK;
536 }
537
538 /**
539  * Function to add link in sqlite
540  */
541 static OCStackResult addlink(int id1, int id2)
542 {
543     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
544
545     sqlite3_stmt *stmt = 0;
546     int res = 0;
547     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
548                               strlen(PDM_SQLITE_INSERT_LINK_DATA) + 1, &stmt, NULL);
549     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
550
551     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
552     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
553
554     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
555     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
556
557     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, PDM_DEVICE_ACTIVE);
558     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
559
560     if (sqlite3_step(stmt) != SQLITE_DONE)
561     {
562         OIC_LOG_V(ERROR, TAG, "Error Occured: %s",sqlite3_errmsg(g_db));
563         sqlite3_finalize(stmt);
564         return OC_STACK_ERROR;
565     }
566     sqlite3_finalize(stmt);
567     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
568     return OC_STACK_OK;
569 }
570
571 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
572 {
573     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
574
575     CHECK_PDM_INIT(TAG);
576     if (NULL == UUID1 || NULL == UUID2)
577     {
578         OIC_LOG(ERROR, TAG, "Invalid PARAM");
579         return  OC_STACK_INVALID_PARAM;
580     }
581
582     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
583     if (OC_STACK_OK != PDMGetDeviceState(UUID1, &state))
584     {
585         OIC_LOG(ERROR, TAG, "Internal error occured");
586         return OC_STACK_ERROR;
587     }
588     if (PDM_DEVICE_ACTIVE != state)
589     {
590         OIC_LOG_V(ERROR, TAG, "UUID1: Device state is not active : %d", state);
591         return OC_STACK_INVALID_PARAM;
592     }
593
594     state = PDM_DEVICE_UNKNOWN;
595     if (OC_STACK_OK != PDMGetDeviceState(UUID2, &state))
596     {
597         OIC_LOG(ERROR, TAG, "Internal error occured");
598         return OC_STACK_ERROR;
599     }
600     if (PDM_DEVICE_ACTIVE != state)
601     {
602         OIC_LOG_V(ERROR, TAG, "UUID2: Device state is not active : %d", state);
603         return OC_STACK_INVALID_PARAM;
604     }
605
606     int id1 = 0;
607     if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
608     {
609         OIC_LOG(ERROR, TAG, "Requested value not found");
610         return OC_STACK_INVALID_PARAM;
611     }
612     int id2 = 0;
613     if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
614     {
615         OIC_LOG(ERROR, TAG, "Requested value not found");
616         return OC_STACK_INVALID_PARAM;
617     }
618
619     ASCENDING_ORDER(id1, id2);
620     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
621     return addlink(id1, id2);
622 }
623
624 /**
625  * Function to remove created link
626  */
627 static OCStackResult removeLink(int id1, int id2)
628 {
629     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
630
631     int res = 0;
632     sqlite3_stmt *stmt = 0;
633     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK, strlen(PDM_SQLITE_DELETE_LINK) + 1, &stmt, NULL);
634     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
635
636     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
637     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
638
639     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
640     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
641
642     if (SQLITE_DONE != sqlite3_step(stmt))
643     {
644         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
645         sqlite3_finalize(stmt);
646         return OC_STACK_ERROR;
647     }
648     sqlite3_finalize(stmt);
649     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
650     return OC_STACK_OK;
651 }
652
653 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
654 {
655     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
656
657     CHECK_PDM_INIT(TAG);
658     if (NULL == UUID1 || NULL == UUID2)
659     {
660         OIC_LOG(ERROR, TAG, "Invalid PARAM");
661         return  OC_STACK_INVALID_PARAM;
662     }
663
664     int id1 = 0;
665     if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
666     {
667         OIC_LOG(ERROR, TAG, "Requested value not found");
668         return OC_STACK_INVALID_PARAM;
669     }
670
671     int id2 = 0;
672     if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
673     {
674         OIC_LOG(ERROR, TAG, "Requested value not found");
675         return OC_STACK_INVALID_PARAM;
676     }
677     ASCENDING_ORDER(id1, id2);
678     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
679     return removeLink(id1, id2);
680 }
681
682 static OCStackResult removeFromDeviceList(int id)
683 {
684     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
685
686     sqlite3_stmt *stmt = 0;
687     int res = 0;
688     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
689                               strlen(PDM_SQLITE_DELETE_DEVICE) + 1, &stmt, NULL);
690     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
691
692     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
693     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
694
695     if (sqlite3_step(stmt) != SQLITE_DONE)
696     {
697         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
698         sqlite3_finalize(stmt);
699         return OC_STACK_ERROR;
700     }
701     sqlite3_finalize(stmt);
702     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
703     return OC_STACK_OK;
704 }
705
706 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
707 {
708     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
709
710     CHECK_PDM_INIT(TAG);
711     if (NULL == UUID)
712     {
713         return OC_STACK_INVALID_PARAM;
714     }
715     int id = 0;
716     if (OC_STACK_OK != getIdForUUID(UUID, &id))
717     {
718         OIC_LOG(ERROR, TAG, "Requested value not found");
719         return OC_STACK_INVALID_PARAM;
720     }
721     begin();
722     if(OC_STACK_OK != removeFromDeviceList(id))
723     {
724         rollback();
725         OIC_LOG(ERROR, TAG, "Requested value not found");
726         return OC_STACK_ERROR;
727     }
728     commit();
729     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
730     return OC_STACK_OK;
731 }
732
733
734 static OCStackResult updateLinkState(int id1, int id2, int state)
735 {
736     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
737
738     sqlite3_stmt *stmt = 0;
739     int res = 0 ;
740     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
741                               strlen(PDM_SQLITE_UPDATE_LINK) + 1, &stmt, NULL);
742     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
743
744     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
745     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
746
747     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id1);
748     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
749
750     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_THIRD, id2);
751     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
752
753     if (SQLITE_DONE != sqlite3_step(stmt))
754     {
755         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
756         sqlite3_finalize(stmt);
757         return OC_STACK_ERROR;
758     }
759     sqlite3_finalize(stmt);
760     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
761     return OC_STACK_OK;
762 }
763
764 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
765 {
766     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
767
768     CHECK_PDM_INIT(TAG);
769     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
770     {
771         OIC_LOG(ERROR, TAG, "Invalid PARAM");
772         return  OC_STACK_INVALID_PARAM;
773     }
774
775     int id1 = 0;
776     if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
777     {
778         OIC_LOG(ERROR, TAG, "Requested value not found");
779         return OC_STACK_INVALID_PARAM;
780     }
781
782     int id2 = 0;
783     if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
784     {
785         OIC_LOG(ERROR, TAG, "Requested value not found");
786         return OC_STACK_INVALID_PARAM;
787     }
788     ASCENDING_ORDER(id1, id2);
789     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
790     return updateLinkState(id1, id2, PDM_DEVICE_STALE);
791 }
792
793 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
794 {
795     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
796
797     CHECK_PDM_INIT(TAG);
798     if (NULL != *uuidList)
799     {
800         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
801         return OC_STACK_INVALID_PARAM;
802     }
803     sqlite3_stmt *stmt = 0;
804     int res = 0;
805     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_LIST_ALL_UUID,
806                               strlen(PDM_SQLITE_LIST_ALL_UUID) + 1, &stmt, NULL);
807     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
808
809     size_t counter  = 0;
810     while (SQLITE_ROW == sqlite3_step(stmt))
811     {
812         const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
813         OicUuid_t *uid = (OicUuid_t *)ptr;
814         OCUuidList_t *temp = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
815         if (NULL == temp)
816         {
817             OIC_LOG_V(ERROR, TAG, "Memory allocation problem");
818             sqlite3_finalize(stmt);
819             return OC_STACK_NO_MEMORY;
820         }
821         memcpy(&temp->dev.id, uid->id, UUID_LENGTH);
822         LL_PREPEND(*uuidList,temp);
823         ++counter;
824     }
825     *numOfDevices = counter;
826     sqlite3_finalize(stmt);
827     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
828     return OC_STACK_OK;
829 }
830
831 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
832 {
833     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
834
835     sqlite3_stmt *stmt = 0;
836     int res = 0;
837     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
838                               strlen(PDM_SQLITE_GET_UUID) + 1, &stmt, NULL);
839     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
840
841     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
842     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
843
844     while (SQLITE_ROW == sqlite3_step(stmt))
845     {
846         const void *ptr = sqlite3_column_blob(stmt, PDM_FIRST_INDEX);
847         memcpy(uid, ptr, sizeof(OicUuid_t));
848
849         int temp = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
850         if(PDM_DEVICE_STALE == temp)
851         {
852             if(result)
853             {
854                 *result = true;
855             }
856         }
857         else
858         {
859             if(result)
860             {
861                 *result = false;
862             }
863         }
864         sqlite3_finalize(stmt);
865         return OC_STACK_OK;
866     }
867     sqlite3_finalize(stmt);
868     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
869     return OC_STACK_INVALID_PARAM;
870 }
871
872 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
873 {
874     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
875
876     CHECK_PDM_INIT(TAG);
877     if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
878     {
879         return OC_STACK_INVALID_PARAM;
880     }
881     if (NULL != *UUIDLIST )
882     {
883         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
884         return OC_STACK_INVALID_PARAM;
885     }
886     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
887     OCStackResult ret = PDMGetDeviceState(UUID, &state);
888     if (OC_STACK_OK != ret)
889     {
890         OIC_LOG(ERROR, TAG, "Internal error occured");
891         return OC_STACK_ERROR;
892     }
893     if (PDM_DEVICE_ACTIVE != state)
894     {
895         OIC_LOG_V(ERROR, TAG, "Device state is not active : %d", state);
896         return OC_STACK_INVALID_PARAM;
897     }
898     int id = 0;
899     if (OC_STACK_OK != getIdForUUID(UUID, &id))
900     {
901         OIC_LOG(ERROR, TAG, "Requested value not found");
902         return OC_STACK_INVALID_PARAM;
903     }
904
905
906     sqlite3_stmt *stmt = 0;
907     int res = 0;
908     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_LINKED_DEVICES,
909                               strlen(PDM_SQLITE_GET_LINKED_DEVICES) + 1, &stmt, NULL);
910     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
911
912     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
913     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
914
915     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
916     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
917
918     size_t counter  = 0;
919     while (SQLITE_ROW == sqlite3_step(stmt))
920     {
921         int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
922         int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
923
924         OicUuid_t temp = {{0,}};
925         if (i1 != id)
926         {
927             getUUIDforId(i1, &temp, NULL);
928         }
929         if (i2 != id)
930         {
931             getUUIDforId(i2, &temp, NULL);
932         }
933
934         OCUuidList_t *tempNode = (OCUuidList_t *) OICCalloc(1,sizeof(OCUuidList_t));
935         if (NULL == tempNode)
936         {
937             OIC_LOG(ERROR, TAG, "No Memory");
938             sqlite3_finalize(stmt);
939             return OC_STACK_NO_MEMORY;
940         }
941         memcpy(&tempNode->dev.id, &temp.id, UUID_LENGTH);
942         LL_PREPEND(*UUIDLIST,tempNode);
943         ++counter;
944     }
945     *numOfDevices = counter;
946      sqlite3_finalize(stmt);
947      OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
948      return OC_STACK_OK;
949 }
950
951 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
952 {
953     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
954
955     CHECK_PDM_INIT(TAG);
956     if (NULL != *staleDevList)
957     {
958         OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
959         return OC_STACK_INVALID_PARAM;
960     }
961
962     sqlite3_stmt *stmt = 0;
963     int res = 0;
964     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_STALE_INFO,
965                               strlen(PDM_SQLITE_GET_STALE_INFO) + 1, &stmt, NULL);
966     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
967
968     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, PDM_DEVICE_STALE);
969     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
970
971     size_t counter  = 0;
972     while (SQLITE_ROW == sqlite3_step(stmt))
973     {
974         int i1 = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
975         int i2 = sqlite3_column_int(stmt, PDM_SECOND_INDEX);
976         OicUuid_t temp1 = {{0,}};
977         OicUuid_t temp2 = {{0,}};;
978         getUUIDforId(i1, &temp1, NULL);
979         getUUIDforId(i2, &temp2, NULL);
980
981         OCPairList_t *tempNode = (OCPairList_t *) OICCalloc(1, sizeof(OCPairList_t));
982         if (NULL == tempNode)
983         {
984             OIC_LOG(ERROR, TAG, "No Memory");
985             sqlite3_finalize(stmt);
986             return OC_STACK_NO_MEMORY;
987         }
988         memcpy(&tempNode->dev.id, &temp1.id, UUID_LENGTH);
989         memcpy(&tempNode->dev2.id, &temp2.id, UUID_LENGTH);
990         LL_PREPEND(*staleDevList, tempNode);
991         ++counter;
992     }
993     *numOfDevices = counter;
994     sqlite3_finalize(stmt);
995     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
996     return OC_STACK_OK;
997 }
998
999 OCStackResult PDMClose()
1000 {
1001     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1002
1003     CHECK_PDM_INIT(TAG);
1004     int res = 0;
1005     res = sqlite3_close(g_db);
1006     PDM_VERIFY_SQLITE_OK(TAG, res, NULL, ERROR, OC_STACK_ERROR);
1007     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1008     return OC_STACK_OK;
1009 }
1010
1011 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
1012 {
1013     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1014
1015     if(ptr)
1016     {
1017         OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
1018         LL_FOREACH_SAFE(ptr, tmp1, tmp2)
1019         {
1020             LL_DELETE(ptr, tmp1);
1021             OICFree(tmp1);
1022         }
1023     }
1024
1025     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1026 }
1027
1028 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
1029 {
1030     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1031
1032     if(ptr)
1033     {
1034         OCPairList_t *tmp1 = NULL,*tmp2=NULL;
1035         LL_FOREACH_SAFE(ptr, tmp1, tmp2)
1036         {
1037             LL_DELETE(ptr, tmp1);
1038             OICFree(tmp1);
1039         }
1040     }
1041
1042     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1043 }
1044
1045 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
1046                                bool* result)
1047 {
1048     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1049
1050     CHECK_PDM_INIT(TAG);
1051     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
1052     {
1053         return OC_STACK_INVALID_PARAM;
1054     }
1055     int id1 = 0;
1056     int id2 = 0;
1057     if (OC_STACK_OK != getIdForUUID(uuidOfDevice1, &id1))
1058     {
1059         OIC_LOG(ERROR, TAG, "Requested value not found");
1060         return OC_STACK_INVALID_PARAM;
1061     }
1062
1063     if (OC_STACK_OK != getIdForUUID(uuidOfDevice2, &id2))
1064     {
1065         OIC_LOG(ERROR, TAG, "Requested value not found");
1066         return OC_STACK_INVALID_PARAM;
1067     }
1068
1069     PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
1070     if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice1, &state))
1071     {
1072         OIC_LOG(ERROR, TAG, "uuidOfDevice1:Internal error occured");
1073         return OC_STACK_ERROR;
1074     }
1075     if (PDM_DEVICE_ACTIVE != state)
1076     {
1077         OIC_LOG_V(ERROR, TAG, "uuidOfDevice1:Device state is not active : %d", state);
1078         return OC_STACK_INVALID_PARAM;
1079     }
1080
1081     state = PDM_DEVICE_UNKNOWN;
1082     if (OC_STACK_OK != PDMGetDeviceState(uuidOfDevice2, &state))
1083     {
1084         OIC_LOG(ERROR, TAG, "uuidOfDevice2:Internal error occured");
1085         return OC_STACK_ERROR;
1086     }
1087     if (PDM_DEVICE_ACTIVE != state)
1088     {
1089         OIC_LOG_V(ERROR, TAG, "uuidOfDevice2:Device state is not active : %d", state);
1090         return OC_STACK_INVALID_PARAM;
1091     }
1092
1093     ASCENDING_ORDER(id1, id2);
1094
1095     sqlite3_stmt *stmt = 0;
1096     int res = 0;
1097     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_DEVICE_LINKS,
1098                               strlen(PDM_SQLITE_GET_DEVICE_LINKS) + 1, &stmt, NULL);
1099     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1100
1101     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id1);
1102     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1103
1104     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id2);
1105     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1106
1107     bool ret = false;
1108     while(SQLITE_ROW == sqlite3_step(stmt))
1109     {
1110         OIC_LOG(INFO, TAG, "Link already exists between devices");
1111         ret = true;
1112     }
1113     sqlite3_finalize(stmt);
1114     *result = ret;
1115     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1116     return OC_STACK_OK;
1117 }
1118
1119 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
1120 {
1121     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1122     OIC_LOG_V(WARNING, TAG, "UUID is: %s", (char*) uuid);
1123
1124     sqlite3_stmt *stmt = 0;
1125     int res = 0 ;
1126     char sqlStat[PDM_SQLITE_UPDATE_DEVICE_SIZE - 1 + HEX_UUID_STR_LENGTH];
1127     char hexUUID[HEX_UUID_STR_LENGTH];
1128
1129     memset(sqlStat, 0, sizeof(sqlStat));
1130     strncpy(sqlStat, PDM_SQLITE_UPDATE_DEVICE, PDM_SQLITE_UPDATE_DEVICE_SIZE - 1);
1131     memset(hexUUID, 0, sizeof(hexUUID));
1132
1133     if (!convertUuidToHexString(uuid, hexUUID))
1134     {
1135         return OC_STACK_ERROR;
1136     }
1137
1138     strncpy(sqlStat + PDM_SQLITE_UPDATE_DEVICE_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
1139     res = sqlite3_prepare_v2(g_db, sqlStat,
1140                                   (int)sizeof(sqlStat), &stmt, NULL);
1141
1142     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1143     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
1144     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1145
1146     if (SQLITE_DONE != sqlite3_step(stmt))
1147     {
1148         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1149         sqlite3_finalize(stmt);
1150         return OC_STACK_ERROR;
1151     }
1152     sqlite3_finalize(stmt);
1153     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1154     return OC_STACK_OK;
1155 }
1156
1157 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
1158 {
1159     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1160
1161     sqlite3_stmt *stmt = 0;
1162     int res = 0 ;
1163
1164     int id = 0;
1165     if (OC_STACK_OK != getIdForUUID(devUuid, &id))
1166     {
1167         OIC_LOG(ERROR, TAG, "Requested value not found");
1168         return OC_STACK_INVALID_PARAM;
1169     }
1170
1171     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE,
1172                               strlen(PDM_SQLITE_UPDATE_LINK_STALE_FOR_STALE_DEVICE) + 1,
1173                                &stmt, NULL);
1174     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1175
1176     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, id);
1177     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1178
1179     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_SECOND, id);
1180     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1181
1182     if (SQLITE_DONE != sqlite3_step(stmt))
1183     {
1184         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1185         sqlite3_finalize(stmt);
1186         return OC_STACK_ERROR;
1187     }
1188     sqlite3_finalize(stmt);
1189     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1190     return OC_STACK_OK;
1191 }
1192
1193 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
1194 {
1195     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1196
1197     OCStackResult res = OC_STACK_ERROR;
1198
1199     CHECK_PDM_INIT(TAG);
1200     if (NULL == uuid)
1201     {
1202         OIC_LOG(ERROR, TAG, "Invalid PARAM");
1203         return  OC_STACK_INVALID_PARAM;
1204     }
1205     begin();
1206
1207     if(PDM_DEVICE_STALE == state)
1208     {
1209         res = updateLinkForStaleDevice(uuid);
1210         if (OC_STACK_OK != res)
1211         {
1212             rollback();
1213             OIC_LOG(ERROR, TAG, "unable to update links");
1214             return res;
1215         }
1216     }
1217
1218     res = updateDeviceState(uuid, state);
1219     if (OC_STACK_OK != res)
1220     {
1221         rollback();
1222         OIC_LOG(ERROR, TAG, "unable to update device state");
1223         return res;
1224     }
1225     commit();
1226     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1227     return OC_STACK_OK;
1228 }
1229
1230 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
1231 {
1232     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1233
1234     if (NULL == uuid || NULL == result)
1235     {
1236         OIC_LOG(ERROR, TAG, "UUID or result is NULL");
1237         return OC_STACK_INVALID_PARAM;
1238     }
1239
1240     sqlite3_stmt *stmt = 0;
1241     int res = 0;
1242     char sqlStat[PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1 + HEX_UUID_STR_LENGTH];
1243     char hexUUID[HEX_UUID_STR_LENGTH];
1244
1245     memset(sqlStat, 0, sizeof(sqlStat));
1246     strncpy(sqlStat, PDM_SQLITE_GET_DEVICE_STATUS, PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1);
1247     memset(hexUUID, 0, sizeof(hexUUID));
1248
1249     if (!convertUuidToHexString(uuid, hexUUID))
1250     {
1251         return OC_STACK_ERROR;
1252     }
1253
1254     strncpy(sqlStat + PDM_SQLITE_GET_DEVICE_STATUS_SIZE - 1, hexUUID, HEX_UUID_STR_LENGTH);
1255     res = sqlite3_prepare_v2(g_db, sqlStat, (int)sizeof(sqlStat), &stmt, 0);
1256     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1257
1258     *result = PDM_DEVICE_UNKNOWN;
1259     while(SQLITE_ROW == sqlite3_step(stmt))
1260     {
1261         int tempStaleStateFromDb = sqlite3_column_int(stmt, PDM_FIRST_INDEX);
1262         OIC_LOG_V(DEBUG, TAG, "Device state is %d", tempStaleStateFromDb);
1263         *result = (PdmDeviceState_t)tempStaleStateFromDb;
1264     }
1265
1266     sqlite3_finalize(stmt);
1267     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1268
1269     return OC_STACK_OK;
1270 }
1271
1272 OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state)
1273 {
1274     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1275
1276     CHECK_PDM_INIT(TAG);
1277     if (PDM_DEVICE_ACTIVE != state && PDM_DEVICE_STALE != state &&
1278         PDM_DEVICE_INIT != state && PDM_DEVICE_UNKNOWN != state)
1279     {
1280         return OC_STACK_INVALID_PARAM;
1281     }
1282
1283     sqlite3_stmt *stmt = 0;
1284     int res =0;
1285     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE_WITH_STATE,
1286                               strlen(PDM_SQLITE_DELETE_DEVICE_WITH_STATE) + 1, &stmt, NULL);
1287     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1288
1289     res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
1290     PDM_VERIFY_SQLITE_OK(TAG, res, stmt, ERROR, OC_STACK_ERROR);
1291
1292     if (SQLITE_DONE != sqlite3_step(stmt))
1293     {
1294         OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
1295         sqlite3_finalize(stmt);
1296         return OC_STACK_ERROR;
1297     }
1298     sqlite3_finalize(stmt);
1299     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1300     return OC_STACK_OK;
1301 }