RAML v1.1 sync-up in SVR DB
[platform/upstream/iotivity.git] / resource / csdk / security / src / pconfresource.c
1 /* *****************************************************************
2  *
3  * Copyright 2016 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 <stdlib.h>
22 #include <string.h>
23 #include "ocstack.h"
24 #include "logger.h"
25 #include "oic_malloc.h"
26 #include "oic_string.h"
27 #include "cJSON.h"
28 #include "base64.h"
29 #include "ocpayload.h"
30 #include "payload_logging.h"
31 #include "resourcemanager.h"
32 #include "pconfresource.h"
33 #include "psinterface.h"
34 #include "utlist.h"
35 #include "srmresourcestrings.h"
36 #include "doxmresource.h"
37 #include "srmutility.h"
38 #include "ocserverrequest.h"
39 #include <stdlib.h>
40 #include "psinterface.h"
41 #include "security_internals.h"
42 #ifdef WITH_ARDUINO
43 #include <string.h>
44 #else
45 #include <strings.h>
46 #endif
47
48 #define TAG  "SRM-PCONF"
49
50 static const uint16_t CBOR_SIZE = 1024;
51 static const uint64_t CBOR_MAX_SIZE = 4400;
52 static const uint8_t  PCONF_MAP_SIZE = 4;
53 static const uint8_t  PCONF_RESOURCE_MAP_SIZE = 3;
54
55 static OicSecPconf_t          *gPconf = NULL;
56 static OCResourceHandle   gPconfHandle = NULL;
57 static OicSecPconf_t         gDefaultPconf =
58 {
59     false,                  /* bool edp */
60     NULL,                  /* OicSecPrm *prm */
61     0,                       /* size_t prmLen */
62     {.val = {0}},       /* OicDpPin_t pin */
63     NULL,                  /* OicSecPdAcl_t *pdacls */
64     NULL,                  /* OicUuid_t *pddevs */
65     0,                       /* size_t pddevLen */
66     {.id = {0}},        /* OicUuid_t deviceID */
67     {.id = {0}},        /* OicUuid_t rowner */
68 };
69
70 /**
71  * This function frees OicSecPdAcl_t object's fields and object itself.
72  */
73 void FreePdAclList(OicSecPdAcl_t* pdacls)
74 {
75     if (pdacls)
76     {
77         size_t i = 0;
78
79         //Clean pdacl objecs
80         OicSecPdAcl_t *aclTmp1 = NULL;
81         OicSecPdAcl_t *aclTmp2 = NULL;
82         LL_FOREACH_SAFE(pdacls, aclTmp1, aclTmp2)
83         {
84             LL_DELETE(pdacls, aclTmp1);
85
86             // Clean Resources
87             for (i = 0; i < aclTmp1->resourcesLen; i++)
88             {
89                 OICFree(aclTmp1->resources[i]);
90             }
91             OICFree(aclTmp1->resources);
92
93             //Clean Period
94             if(aclTmp1->periods)
95             {
96                 for(i = 0; i < aclTmp1->prdRecrLen; i++)
97                 {
98                     OICFree(aclTmp1->periods[i]);
99                 }
100                 OICFree(aclTmp1->periods);
101             }
102
103             //Clean Recurrence
104             if(aclTmp1->recurrences)
105             {
106                 for(i = 0; i < aclTmp1->prdRecrLen; i++)
107                 {
108                     OICFree(aclTmp1->recurrences[i]);
109                 }
110                 OICFree(aclTmp1->recurrences);
111             }
112         }
113
114         //Clean pconf itself
115         OICFree(pdacls);
116     }
117 }
118
119 void DeletePconfBinData(OicSecPconf_t* pconf)
120 {
121     if (pconf)
122     {
123         //Clean prm
124         OICFree(pconf->prm);
125
126         //Clean pdacl
127         if (pconf->pdacls)
128         {
129             FreePdAclList(pconf->pdacls);
130         }
131
132         //Clean pddev
133         OICFree(pconf->pddevs);
134
135         //Clean pconf itself
136         OICFree(pconf);
137     }
138 }
139
140 static size_t OicPdAclSize(const OicSecPdAcl_t *pdAcl)
141 {
142     if (!pdAcl)
143     {
144         return 0;
145     }
146
147     OicSecPdAcl_t *tmp = (OicSecPdAcl_t *)pdAcl;
148     size_t size = 0;
149     while (tmp)
150     {
151         size++;
152         tmp = tmp->next;
153     }
154     return size;
155 }
156
157 OCStackResult PconfToCBORPayload(const OicSecPconf_t *pconf,uint8_t **payload,size_t *size)
158 {
159     if (NULL == pconf || NULL == payload || NULL != *payload || NULL == size)
160     {
161         return OC_STACK_INVALID_PARAM;
162     }
163     size_t cborLen = *size;
164     if(0 == cborLen)
165     {
166         cborLen = CBOR_SIZE;
167     }
168     *payload = NULL;
169
170     OCStackResult ret = OC_STACK_ERROR;
171     CborEncoder encoder = { {.ptr = NULL}, .end = 0};
172     CborEncoder pconfMap = { {.ptr = NULL}, .end = 0};
173
174     int64_t cborEncoderResult = CborNoError;
175     uint8_t mapSize = PCONF_MAP_SIZE;
176
177     if (pconf->prmLen > 0)
178     {
179         mapSize++;
180     }
181     if (pconf->pdacls)
182     {
183         mapSize++;
184     }
185     if (pconf->pddevs)
186     {
187         mapSize++;
188     }
189
190     uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
191     VERIFY_NON_NULL(TAG, outPayload, ERROR);
192
193     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
194     cborEncoderResult = cbor_encoder_create_map(&encoder, &pconfMap, mapSize);
195     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating Pconf Map.");
196
197     //edp  -- Mandatory
198     cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_EDP_NAME,
199             strlen(OIC_JSON_EDP_NAME));
200     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Encode EDP String.");
201     cborEncoderResult = cbor_encode_boolean(&pconfMap, pconf->edp);
202     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert PconfEDP value");
203
204     //PRM type -- Not Mandatory
205     if(pconf->prmLen > 0)
206     {
207         CborEncoder prm = { {.ptr = NULL }, .end = 0 };
208         cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PRM_NAME,
209                 strlen(OIC_JSON_PRM_NAME));
210         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM NAME");
211         cborEncoderResult = cbor_encoder_create_array(&pconfMap, &prm, pconf->prmLen);
212         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM value");
213
214         for (size_t i = 0; i < pconf->prmLen; i++)
215         {
216             cborEncoderResult = cbor_encode_int(&prm, pconf->prm[i]);
217             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM Array");
218         }
219         cborEncoderResult = cbor_encoder_close_container(&pconfMap, &prm);
220         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close encode array");
221     }
222
223     //PIN -- Mandatory
224     cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PIN_NAME,
225             strlen(OIC_JSON_PIN_NAME));
226     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create OIC_JSON_PIN_NAME");
227     cborEncoderResult = cbor_encode_byte_string(&pconfMap, pconf->pin.val, sizeof(pconf->pin.val));
228     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to convert pin value");
229
230     //PDACL -- Mandatory
231     if (pconf->pdacls)
232     {
233         OicSecPdAcl_t *pdacl = pconf->pdacls;
234         CborEncoder pdAclArray = {{.ptr = NULL }, .end = 0 };
235         cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDACL_NAME,
236                 strlen(OIC_JSON_PDACL_NAME));
237         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create OIC_JSON_PDACL_NAME");
238         cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pdAclArray,
239                 OicPdAclSize(pconf->pdacls));
240         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to creeate _pdacl array");
241
242         while(pdacl)
243         {
244             CborEncoder pdAclMap = { {.ptr = NULL }, .end = 0, .added = 0, .flags = 0 };
245             // PDACL Map size - Number of mandatory items
246             uint8_t aclMapSize = 2;
247
248             if (pdacl->prdRecrLen)
249             {
250                 ++aclMapSize;
251             }
252             if (pdacl->recurrences)
253             {
254                 ++aclMapSize;
255             }
256
257             cborEncoderResult = cbor_encoder_create_map(&pdAclArray, &pdAclMap, aclMapSize);
258             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,  "Failed to creeate _pdacl array");
259
260             // Resources -- Mandatory
261             cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RESOURCES_NAME,
262                     strlen(OIC_JSON_RESOURCES_NAME));
263             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,  "Failed to encode resource result");
264
265             CborEncoder resources = { {.ptr = NULL }, .end = 0, .added = 0, .flags = 0 };
266             cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &resources,
267                     pdacl->resourcesLen);
268             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,  "Failed to create resource array");
269
270             for (size_t i = 0; i < pdacl->resourcesLen; i++)
271             {
272                 CborEncoder rMap = { {.ptr = NULL }, .end = 0 };
273                 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap,
274                         PCONF_RESOURCE_MAP_SIZE);
275                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
276
277                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
278                         strlen(OIC_JSON_HREF_NAME));
279                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
280                 cborEncoderResult = cbor_encode_text_string(&rMap, pdacl->resources[i],
281                         strlen(pdacl->resources[i]));
282                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
283
284                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
285                         strlen(OIC_JSON_RT_NAME));
286                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
287
288                 // TODO : Need to assign real value of RT
289                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
290                         strlen(OIC_JSON_EMPTY_STRING));
291                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
292
293                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
294                         strlen(OIC_JSON_IF_NAME));
295                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
296
297                 // TODO : Need to assign real value of IF
298                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
299                         strlen(OIC_JSON_EMPTY_STRING));
300                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
301
302                 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
303                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
304             }
305
306             cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &resources);
307             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,  "Failed to close resource array");
308
309             // Permissions -- Mandatory
310             cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERMISSION_NAME,
311                     strlen(OIC_JSON_PERMISSION_NAME));
312             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,  "Failed to create permition string");
313             cborEncoderResult = cbor_encode_int(&pdAclMap, pdacl->permission);
314             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode permition calue");
315
316             // Period -- Not Mandatory
317             if (pdacl->periods)
318             {
319                 CborEncoder period = { {.ptr = NULL }, .end = 0, .added = 0, .flags = 0 };
320                 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERIODS_NAME,
321                         strlen(OIC_JSON_PERIODS_NAME));
322                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period value");
323                 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &period,
324                         pdacl->prdRecrLen);
325                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
326
327                 for (size_t i = 0; i < pdacl->prdRecrLen; i++)
328                 {
329                     cborEncoderResult = cbor_encode_text_string(&period, pdacl->periods[i],
330                             strlen(pdacl->periods[i]));
331                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period");
332                 }
333                 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &period);
334                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to close period array");
335             }
336
337             // Period -- Not Mandatory
338             if(0 != pdacl->prdRecrLen && pdacl->recurrences)
339             {
340                 CborEncoder recurrences = { {.ptr = NULL }, .end = 0, .added = 0, .flags = 0 };
341                 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RECURRENCES_NAME,
342                         strlen(OIC_JSON_RECURRENCES_NAME));
343                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to encode recurrences");
344                 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &recurrences,
345                         pdacl->prdRecrLen);
346                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create rec array");
347
348                 for (size_t i = 0; i < pdacl->prdRecrLen; i++)
349                 {
350                     cborEncoderResult = cbor_encode_text_string(&recurrences,
351                             pdacl->recurrences[i], strlen(pdacl->recurrences[i]));
352                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode recurrences");
353                 }
354                 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &recurrences);
355                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close rec array");
356             }
357             cborEncoderResult = cbor_encoder_close_container(&pdAclArray, &pdAclMap);
358             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl map");
359
360             pdacl = pdacl->next;
361         }
362         //clsoe the array
363         cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pdAclArray);
364         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl array");
365     }
366
367     //PDDev -- Mandatory
368     //There may not be paired devices if it did not pairing before
369     if (pconf->pddevs && 0 < pconf->pddevLen)
370     {
371         CborEncoder pddev = { {.ptr = NULL }, .end = 0, .added = 0, .flags = 0 };
372         cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDDEV_LIST_NAME,
373                 strlen(OIC_JSON_PDDEV_LIST_NAME));
374         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode pddev");
375         cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pddev,  pconf->pddevLen);
376         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
377
378         for (size_t i = 0; i < pconf->pddevLen; i++)
379         {
380             char *pddevId = NULL;
381             ret = ConvertUuidToStr(&pconf->pddevs[i], &pddevId);
382             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
383             cborEncoderResult = cbor_encode_text_string(&pddev, pddevId, strlen(pddevId));
384             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding pddev Id Value.");
385             OICFree(pddevId);
386         }
387         cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pddev);
388         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pddev array");
389     }
390
391     //DeviceId -- Mandatory
392     //There may not be devicd id if caller is provisoning tool
393     cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_DEVICE_ID_NAME,
394             strlen(OIC_JSON_DEVICE_ID_NAME));
395     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode device id");
396     {
397         char *deviceId = NULL;
398         ret = ConvertUuidToStr(&pconf->deviceID, &deviceId);
399         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
400         cborEncoderResult = cbor_encode_text_string(&pconfMap, deviceId, strlen(deviceId));
401         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode deviceID value");
402         OICFree(deviceId);
403     }
404
405     //ROwner -- Mandatory
406     cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_ROWNERID_NAME,
407             strlen(OIC_JSON_ROWNERID_NAME));
408     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rowner string");
409     {
410         char *rowner = NULL;
411         ret = ConvertUuidToStr(&pconf->rowner, &rowner);
412         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
413         cborEncoderResult = cbor_encode_text_string(&pconfMap, rowner, strlen(rowner));
414         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rwoner value");
415         OICFree(rowner);
416     }
417
418     cborEncoderResult = cbor_encoder_close_container(&encoder, &pconfMap);
419     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pconfMap");
420
421     *size = encoder.ptr - outPayload;
422     *payload = outPayload;
423     ret = OC_STACK_OK;
424 exit:
425     if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
426     {
427         // reallocate and try again!
428         OICFree(outPayload);
429         // Since the allocated initial memory failed, double the memory.
430         cborLen += encoder.ptr - encoder.end;
431         cborEncoderResult = CborNoError;
432         ret = PconfToCBORPayload(pconf, payload, &cborLen);
433         *size = cborLen;
434     }
435     if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
436     {
437         OICFree(outPayload);
438         outPayload = NULL;
439         *payload = NULL;
440         *size = 0;
441         ret = OC_STACK_ERROR;
442     }
443     return ret;
444 }
445
446 OCStackResult CBORPayloadToPconf(const uint8_t *cborPayload, size_t size, OicSecPconf_t **secPconf)
447 {
448     if (NULL == cborPayload || NULL == secPconf || NULL != *secPconf || 0 == size)
449     {
450         return OC_STACK_INVALID_PARAM;
451     }
452     OCStackResult ret = OC_STACK_ERROR;
453     *secPconf = NULL;
454     CborValue pconfCbor = { .parser = NULL };
455     CborParser parser = { .end = NULL };
456     CborError cborFindResult = CborNoError;
457     int cborLen = size;
458
459     cbor_parser_init(cborPayload, cborLen, 0, &parser, &pconfCbor);
460     CborValue pconfMap = { .parser = NULL } ;
461     OicSecPconf_t *pconf = NULL;
462     cborFindResult = cbor_value_enter_container(&pconfCbor, &pconfMap);
463     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter map");
464     pconf = (OicSecPconf_t *)OICCalloc(1, sizeof(*pconf));
465     VERIFY_NON_NULL(TAG, pconf, ERROR);
466     while (cbor_value_is_valid(&pconfMap))
467     {
468         char *name = NULL;
469         size_t len = 0;
470         CborType type = cbor_value_get_type(&pconfMap);
471         if (type == CborTextStringType)
472         {
473             cborFindResult = cbor_value_dup_text_string(&pconfMap, &name, &len, NULL);
474             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
475             cborFindResult = cbor_value_advance(&pconfMap);
476             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
477         }
478
479         if (name)
480         {
481             //EDP -- Mandatory
482             if(0 == strcmp(OIC_JSON_EDP_NAME, name))
483             {
484                 cborFindResult = cbor_value_get_boolean(&pconfMap, &pconf->edp);
485                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
486             }
487             if (0 == strcmp(OIC_JSON_PRM_NAME, name))
488             {
489                 int i = 0;
490                 CborValue prm = { .parser = NULL };
491                 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->prmLen);
492                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
493                 VERIFY_SUCCESS(TAG, pconf->prmLen != 0, ERROR);
494
495                 pconf->prm = (OicSecPrm_t *)OICCalloc(pconf->prmLen, sizeof(OicSecPrm_t));
496                 VERIFY_NON_NULL(TAG, pconf->prm, ERROR);
497                 cborFindResult = cbor_value_enter_container(&pconfMap, &prm);
498                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to eneter array");
499
500                 while (cbor_value_is_valid(&prm))
501                 {
502                     cborFindResult = cbor_value_get_int(&prm, (int *)&pconf->prm[i++]);
503                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
504                     cborFindResult = cbor_value_advance(&prm);
505                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
506                 }
507             }
508             //PIN -- Mandatory
509             if (0 == strcmp(OIC_JSON_PIN_NAME, name))
510             {
511                 uint8_t *pin = NULL;
512                 cborFindResult = cbor_value_dup_byte_string(&pconfMap, &pin, &len, NULL);
513                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
514                 memcpy(pconf->pin.val, pin, len);
515                 OICFree(pin);
516             }
517
518             //PDACL -- Mandatory
519             if (0 == strcmp(OIC_JSON_PDACL_NAME, name))
520             {
521                 CborValue pdAclArray = { .parser = NULL};
522                 OicSecPdAcl_t *headPdacl = NULL;
523
524                 cborFindResult = cbor_value_enter_container(&pconfMap, &pdAclArray);
525                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
526
527                 while (cbor_value_is_valid(&pdAclArray))
528                 {
529                     CborValue pdAclMap = { .parser = NULL};
530                     OicSecPdAcl_t *pdacl = (OicSecPdAcl_t *) OICCalloc(1, sizeof(OicSecPdAcl_t));
531                     VERIFY_NON_NULL(TAG, pdacl, ERROR);
532
533                     cborFindResult = cbor_value_enter_container(&pdAclArray, &pdAclMap);
534                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
535
536                     while (cbor_value_is_valid(&pdAclMap))
537                     {
538                         char* name = NULL;
539                         size_t len = 0;
540                         CborType type = cbor_value_get_type(&pdAclMap);
541                         if (type == CborTextStringType)
542                         {
543                             cborFindResult = cbor_value_dup_text_string(&pdAclMap, &name,
544                                     &len, NULL);
545                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
546                             cborFindResult = cbor_value_advance(&pdAclMap);
547                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
548                         }
549                         if (name)
550                         {
551                             // Resources -- Mandatory
552                             if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
553                             {
554                                 int i = 0;
555                                 CborValue resources = { .parser = NULL };
556                                 cborFindResult = cbor_value_get_array_length(&pdAclMap,
557                                         &pdacl->resourcesLen);
558                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
559                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &resources);
560                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
561                                 pdacl->resources = (char **) OICCalloc(pdacl->resourcesLen,
562                                         sizeof(char*));
563                                 VERIFY_NON_NULL(TAG, pdacl->resources, ERROR);
564
565                                 while (cbor_value_is_valid(&resources))
566                                 {
567                                     CborValue rMap = { .parser = NULL  };
568                                     cborFindResult = cbor_value_enter_container(&resources, &rMap);
569                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
570
571                                     while(cbor_value_is_valid(&rMap))
572                                     {
573                                         char *rMapName = NULL;
574                                         size_t rMapNameLen = 0;
575                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
576                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
577                                         cborFindResult = cbor_value_advance(&rMap);
578                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
579
580                                         // "href"
581                                         if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
582                                         {
583                                             // TODO : Need to check data structure of OicSecPdAcl_t based on RAML spec.
584                                             cborFindResult = cbor_value_dup_text_string(&rMap, &pdacl->resources[i++], &len, NULL);
585                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
586                                         }
587
588                                         // "rt"
589                                         if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
590                                         {
591                                             // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
592                                             char *rtData = NULL;
593                                             cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
594                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
595                                             OICFree(rtData);
596                                         }
597
598                                         // "if"
599                                         if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
600                                         {
601                                             // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
602                                             char *ifData = NULL;
603                                             cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
604                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
605                                             OICFree(ifData);
606                                         }
607
608                                         if (cbor_value_is_valid(&rMap))
609                                         {
610                                             cborFindResult = cbor_value_advance(&rMap);
611                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
612                                         }
613                                         OICFree(rMapName);
614                                     }
615
616                                     if (cbor_value_is_valid(&resources))
617                                     {
618                                         cborFindResult = cbor_value_advance(&resources);
619                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
620                                     }
621                                 }
622                             }
623
624                             // Permissions -- Mandatory
625                             if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
626                             {
627                                 cborFindResult = cbor_value_get_uint64(&pdAclMap,
628                                         (uint64_t *) &pdacl->permission);
629                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
630                             }
631
632                             // Period -- Not mandatory
633                             if (strcmp(name, OIC_JSON_PERIODS_NAME) == 0)
634                             {
635                                 int i = 0;
636                                 CborValue period = { .parser = NULL };
637                                 cborFindResult = cbor_value_get_array_length(&pdAclMap,
638                                         &pdacl->prdRecrLen);
639                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
640                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &period);
641                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
642                                 pdacl->periods = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
643                                 VERIFY_NON_NULL(TAG, pdacl->periods, ERROR);
644
645                                 while (cbor_value_is_text_string(&period))
646                                 {
647                                     cborFindResult = cbor_value_dup_text_string(&period,
648                                             &pdacl->periods[i++], &len, NULL);
649                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
650                                     cborFindResult = cbor_value_advance(&period);
651                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
652                                     pdacl->prdRecrLen++;
653                                 }
654                             }
655
656                             // Recurrence -- Not mandatory
657                             if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0)
658                             {
659                                 int i = 0;
660                                 CborValue recurrences = { .parser = NULL };
661                                 cborFindResult = cbor_value_get_array_length(&pdAclMap, &pdacl->prdRecrLen);
662                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
663                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &recurrences);
664                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
665                                 pdacl->recurrences = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
666                                 VERIFY_NON_NULL(TAG, pdacl->recurrences, ERROR);
667
668                                 while (cbor_value_is_text_string(&recurrences))
669                                 {
670                                     cborFindResult = cbor_value_dup_text_string(&recurrences,
671                                             &pdacl->recurrences[i++], &len, NULL);
672                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
673                                     cborFindResult = cbor_value_advance(&recurrences);
674                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
675                                 }
676                             }
677                             if (type != CborMapType && cbor_value_is_valid(&pdAclMap))
678                             {
679                                 cborFindResult = cbor_value_advance(&pdAclMap);
680                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
681                             }
682                         }
683                         if (cbor_value_is_valid(&pdAclArray))
684                         {
685                             cborFindResult = cbor_value_advance(&pdAclArray);
686                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
687                         }
688                         OICFree(name);
689                         name = NULL;
690                     }
691                     pdacl->next = NULL;
692                     if (headPdacl == NULL)
693                     {
694                         headPdacl = pdacl;
695                     }
696                     else
697                     {
698                         OicSecPdAcl_t *temp = headPdacl;
699                         while (temp->next)
700                         {
701                             temp = temp->next;
702                         }
703                         temp->next = pdacl;
704                     }
705                 }
706                 pconf->pdacls = headPdacl;
707             }
708
709             //PDDev -- Mandatory
710             if (strcmp(name, OIC_JSON_PDDEV_LIST_NAME) == 0)
711             {
712                 int i = 0;
713                 CborValue pddevs = { .parser = NULL };
714                 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->pddevLen);
715                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
716                 cborFindResult = cbor_value_enter_container(&pconfMap, &pddevs);
717                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
718
719                 pconf->pddevs = (OicUuid_t *)OICMalloc(pconf->pddevLen * sizeof(OicUuid_t));
720                 VERIFY_NON_NULL(TAG, pconf->pddevs, ERROR);
721                 while (cbor_value_is_valid(&pddevs))
722                 {
723                     char *pddev = NULL;
724                     cborFindResult = cbor_value_dup_text_string(&pddevs, &pddev, &len, NULL);
725                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
726                     cborFindResult = cbor_value_advance(&pddevs);
727                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
728                     ret = ConvertStrToUuid(pddev, &pconf->pddevs[i++]);
729                     VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
730                     OICFree(pddev);
731                 }
732             }
733
734             //Mandatory - Device Id
735             if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name))
736             {
737                 char *deviceId = NULL;
738                 cborFindResult = cbor_value_dup_text_string(&pconfMap, &deviceId, &len, NULL);
739                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get deviceID");
740                 ret = ConvertStrToUuid(deviceId, &pconf->deviceID);
741                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
742                 OICFree(deviceId);
743             }
744
745             // ROwner -- Mandatory
746             if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name))
747             {
748                 char *rowner = NULL;
749                 cborFindResult = cbor_value_dup_text_string(&pconfMap, &rowner, &len, NULL);
750                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get rowner");
751                 ret = ConvertStrToUuid(rowner, &pconf->rowner);
752                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
753                 OICFree(rowner);
754             }
755         }
756         if (CborMapType != type && cbor_value_is_valid(&pconfMap))
757         {
758             cborFindResult = cbor_value_advance(&pconfMap);
759             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
760         }
761         OICFree(name);
762         name = NULL;
763     }
764     *secPconf=pconf;
765     ret = OC_STACK_OK;
766 exit:
767     if (CborNoError != cborFindResult)
768     {
769         OIC_LOG (ERROR, TAG, "CBORPayloadToPconf failed");
770         DeletePconfBinData(pconf);
771         pconf = NULL;
772         *secPconf = NULL;
773         ret = OC_STACK_ERROR;
774     }
775     return ret;
776 }
777
778 static bool UpdatePersistentStorage(const OicSecPconf_t * pconf)
779 {
780     bool ret = false;
781
782     // Convert PCONF data into Cborpayload for update to persistent storage
783     uint8_t *payload = NULL;
784     size_t size = 0;
785     if (OC_STACK_OK == PconfToCBORPayload(pconf, &payload, &size) && NULL !=payload)
786     {
787         if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, payload, size))
788         {
789             ret = true;
790         }
791         OICFree(payload);
792     }
793     return ret;
794 }
795
796 static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest * ehRequest)
797 {
798     uint8_t* payload = NULL;
799     size_t size = 0;
800     OCEntityHandlerResult ehRet = OC_EH_OK;
801
802     OicSecPconf_t pconf;
803     memset(&pconf, 0, sizeof(OicSecPconf_t));
804
805     OIC_LOG (DEBUG, TAG, "Pconf EntityHandle processing GET request");
806
807     if (true == GetDoxmResourceData()->dpc)
808     {
809         //Making response elements for Get request
810         if( (true == gPconf->edp) && (gPconf->prm && 0 < gPconf->prmLen) &&
811                 (0 < strlen((const char*)gPconf->deviceID.id)) && (0 < strlen((const char*)gPconf->rowner.id)))
812         {
813             pconf.edp = true;
814             pconf.prm = gPconf->prm;
815             pconf.prmLen = gPconf->prmLen;
816             memcpy(&pconf.deviceID, &gPconf->deviceID, sizeof(OicUuid_t));
817             memcpy(&pconf.rowner, &gPconf->rowner, sizeof(OicUuid_t));
818             OIC_LOG (DEBUG, TAG, "PCONF - direct pairing enabled");
819         }
820         else if (false == gPconf->edp)
821         {
822             pconf.edp = false;
823             memcpy(&pconf.rowner, &gPconf->rowner, sizeof(OicUuid_t));
824             OIC_LOG (DEBUG, TAG, "PCONF - direct pairing disable");
825         }
826         else
827         {
828             ehRet= OC_EH_ERROR;
829             OIC_LOG (DEBUG, TAG, "PCONF - error");
830         }
831     }
832     else
833     {
834         OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
835     }
836
837
838     if (OC_STACK_OK != PconfToCBORPayload(gPconf, &payload, &size))
839     {
840         ehRet = OC_EH_ERROR;
841     }
842
843     if(OC_EH_OK == ehRet)
844     {
845         ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
846     }
847     else
848     {
849         OICFree(payload);
850         payload = NULL;
851         size = 0;
852     }
853
854     // Send response payload to request originator
855     SendSRMCBORResponse(ehRequest, ehRet, payload, size);
856     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
857
858     return ehRet;
859 }
860
861 static OCEntityHandlerResult HandlePconfPostRequest (const OCEntityHandlerRequest * ehRequest)
862 {
863     OCEntityHandlerResult ehRet = OC_EH_OK;
864     OCStackResult res=OC_STACK_OK;
865     OicSecPconf_t* newPconf = NULL;
866
867     if (true == GetDoxmResourceData()->dpc)
868     {
869         // Convert CBOR PCONF data into binary. This will also validate the PCONF data received.
870         uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData1;
871         size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
872
873         if(payload){
874             res = CBORPayloadToPconf(payload, size, &newPconf);
875         }
876     }
877     else
878     {
879         OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
880         ehRet = OC_EH_ERROR;
881     }
882
883     if (newPconf && res == OC_STACK_OK)
884     {
885         // Check if valid Post request
886         if ((true == newPconf->edp) && (0 < newPconf->prmLen) &&
887                 DP_PIN_LENGTH == sizeof((const char*)newPconf->pin.val))
888         {
889             OicSecPrm_t *oldPrm = gPconf->prm;
890             OicSecPdAcl_t *oldPdacl = gPconf->pdacls;
891
892             // Update local PCONF with new PCONF
893             gPconf->edp = true;
894             memcpy(&gPconf->pin, &newPconf->pin, sizeof(OicDpPin_t));
895             gPconf->prm = newPconf->prm;
896             gPconf->prmLen = newPconf->prmLen;
897             gPconf->pdacls = newPconf->pdacls;
898             memcpy(&gPconf->rowner, &newPconf->rowner, sizeof(OicUuid_t));
899
900             // to delete old value(prm, pdacl)
901             newPconf->prm = oldPrm;
902             newPconf->pdacls = oldPdacl;
903         }
904         else if (false == newPconf->edp)
905         {
906             gPconf->edp = false;
907         }
908         else
909         {
910             ehRet = OC_EH_ERROR;
911         }
912
913         // Update storage
914         if(OC_EH_ERROR != ehRet && true == UpdatePersistentStorage(gPconf))
915         {
916             ehRet = OC_EH_RESOURCE_CREATED;
917         }
918
919         DeletePconfBinData(newPconf);
920     }
921     else
922     {
923         ehRet = OC_EH_ERROR;
924     }
925
926     // Send payload to request originator
927     SendSRMCBORResponse(ehRequest, ehRet, NULL, 0);
928
929     OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
930     return ehRet;
931 }
932
933 /*
934  * This internal method is the entity handler for PCONF resources and
935  * will handle REST request (POST) for them.
936  */
937 OCEntityHandlerResult PconfEntityHandler (OCEntityHandlerFlag flag,
938                                         OCEntityHandlerRequest * ehRequest,
939                                         void* callbackParameter)
940 {
941     OIC_LOG(DEBUG, TAG, "Received request PconfEntityHandler");
942     (void)callbackParameter;
943     OCEntityHandlerResult ehRet = OC_EH_ERROR;
944
945     if (!ehRequest)
946     {
947         return ehRet;
948     }
949
950     if (flag & OC_REQUEST_FLAG)
951     {
952         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
953         switch (ehRequest->method)
954         {
955             case OC_REST_GET:
956                 ehRet = HandlePconfGetRequest(ehRequest);
957                 break;
958
959             case OC_REST_POST:
960                 ehRet = HandlePconfPostRequest(ehRequest);
961                 break;
962
963             case OC_REST_DELETE:
964                 break;
965
966             default:
967                 ehRet = OC_EH_ERROR;
968                 SendSRMCBORResponse(ehRequest, ehRet, NULL, 0);
969         }
970     }
971
972     return ehRet;
973 }
974
975 /*
976  * This internal method is used to create '/oic/sec/pconf' resource.
977  */
978 OCStackResult CreatePconfResource()
979 {
980     OCStackResult ret;
981
982     ret = OCCreateResource(&gPconfHandle,
983                            OIC_RSRC_TYPE_SEC_PCONF,
984                            OIC_MI_DEF,
985                            OIC_RSRC_PCONF_URI,
986                            PconfEntityHandler,
987                            NULL,
988                            OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
989
990     if (OC_STACK_OK != ret)
991     {
992         OIC_LOG (ERROR, TAG, "Unable to instantiate PCONF resource");
993         DeInitPconfResource();
994     }
995     return ret;
996 }
997
998 /**
999  * Get the default value.
1000  * @retval  the gDefaultPconf pointer;
1001  */
1002 static OicSecPconf_t* GetPconfDefault()
1003 {
1004     OIC_LOG (DEBUG, TAG, "GetPconfDefault");
1005
1006     return &gDefaultPconf;
1007 }
1008
1009 /**
1010  * This method is used by SRM to retrieve PCONF resource data..
1011  *
1012  * @retval  reference to @ref OicSecPconf_t, binary format of Pconf resource data
1013  */
1014 const OicSecPconf_t* GetPconfResourceData()
1015 {
1016     return gPconf;
1017 }
1018
1019 /**
1020  * Initialize PCONF resource by loading data from persistent storage.
1021  *
1022  * @retval  OC_STACK_OK for Success, otherwise some error value
1023  */
1024 OCStackResult InitPconfResource()
1025 {
1026     OCStackResult ret = OC_STACK_ERROR;
1027
1028     uint8_t *data = NULL;
1029     size_t size = 0;
1030
1031     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PCONF_NAME, &data, &size);
1032     // If database read failed
1033     if (ret != OC_STACK_OK)
1034     {
1035         OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
1036     }
1037     if (data)
1038     {
1039         CBORPayloadToPconf(data, size, &gPconf);
1040     }
1041
1042     if (!data || !gPconf)
1043     {
1044         gPconf = GetPconfDefault();
1045
1046         // device id from doxm
1047         OicUuid_t deviceId = {.id = {0}};
1048         OCStackResult ret = GetDoxmDeviceID( &deviceId);
1049         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1050         memcpy(&gPconf->deviceID, &deviceId, sizeof(OicUuid_t));
1051     }
1052     VERIFY_NON_NULL(TAG, gPconf, ERROR);
1053
1054     // Instantiate 'oic.sec.pconf'
1055     ret = CreatePconfResource();
1056
1057 exit:
1058     if (OC_STACK_OK != ret)
1059     {
1060         DeInitPconfResource();
1061     }
1062     OICFree(data);
1063     return ret;
1064 }
1065
1066 /**
1067  * Perform cleanup for PCONF resources.
1068  *
1069  * @return
1070  * OC_STACK_OK    - no error
1071  * OC_STACK_ERROR - stack process error
1072  *
1073  */
1074 OCStackResult DeInitPconfResource()
1075 {
1076     OCStackResult ret = OCDeleteResource(gPconfHandle);
1077     if(gPconf!= &gDefaultPconf)
1078     {
1079         DeletePconfBinData(gPconf);
1080     }
1081     gPconf = NULL;
1082
1083     if(OC_STACK_OK == ret)
1084     {
1085         return OC_STACK_OK;
1086     }
1087     else
1088     {
1089         return OC_STACK_ERROR;
1090     }
1091 }
1092
1093 /**
1094  * This method might be used to add a paired device id after direct-pairing process complete.
1095  *
1096  * @param pdeviceId ID of the paired device.
1097  *
1098  * @retval  OC_STACK_OK for Success, otherwise some error value
1099  */
1100 OCStackResult AddPairedDevice(OicUuid_t *pdeviceId)
1101 {
1102     if (!gPconf || !pdeviceId)
1103     {
1104         return OC_STACK_INVALID_PARAM;
1105     }
1106
1107
1108     OicUuid_t *prevList = gPconf->pddevs;
1109     gPconf->pddevs = (OicUuid_t *)OICCalloc(gPconf->pddevLen+1, sizeof(OicUuid_t));
1110     if(!gPconf->pddevs)
1111     {
1112         return OC_STACK_NO_MEMORY;
1113     }
1114     for (size_t i=0; i<gPconf->pddevLen; i++)
1115     {
1116         memcpy(&gPconf->pddevs[i], &prevList[i], sizeof(OicUuid_t));
1117     }
1118
1119     // add new paired device id
1120     memcpy(&gPconf->pddevs[gPconf->pddevLen], pdeviceId, sizeof(OicUuid_t));
1121     gPconf->pddevLen++;
1122
1123     // Update storage
1124     if(true != UpdatePersistentStorage(gPconf))
1125     {
1126         OIC_LOG (ERROR, TAG, "Fail to update pconf resource");
1127         return OC_STACK_ERROR;
1128     }
1129
1130     OIC_LOG (ERROR, TAG, "Add paired device success");
1131     return OC_STACK_OK;
1132 }
1133
1134 /**
1135  * This method might be used by PolicyEngine to retrieve PDACL for a Subject.
1136  *
1137  * @param subjectId ID of the subject for which PDACL is required.
1138  * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
1139  *                successive calls for same subjectId.
1140  *
1141  * @retval  reference to @ref OicSecPdAcl_t if PDACL is found, else NULL
1142  */
1143 const OicSecPdAcl_t* GetPdAclData(const OicUuid_t* subjectId, OicSecPdAcl_t **savePtr)
1144 {
1145     OicSecPdAcl_t *pdacl = NULL;
1146
1147     if ( NULL == subjectId)
1148     {
1149         return NULL;
1150     }
1151
1152     /*
1153      * savePtr MUST point to NULL if this is the 'first' call to retrieve PDACL for
1154      * subjectID.
1155      */
1156     if (NULL == *savePtr)
1157     {
1158         pdacl = gPconf->pdacls;
1159
1160         // Find if 'subjectID' is in paired device list.
1161         for(size_t i=0; i<gPconf->pddevLen; i++)
1162         {
1163             if (memcmp(&(gPconf->pddevs[i]), subjectId, sizeof(OicUuid_t)) == 0)
1164             {
1165                 *savePtr = pdacl;
1166                 return pdacl;
1167             }
1168         }
1169     }
1170     else
1171     {
1172         OicSecPdAcl_t *temp = NULL;
1173
1174         /*
1175          * If this is a 'successive' call, search for location pointed by
1176          * savePtr and assign 'begin' to the next PDACL after it in the linked
1177          * list and start searching from there.
1178          */
1179         LL_FOREACH(gPconf->pdacls, temp)
1180         {
1181             if (temp == *savePtr)
1182             {
1183                 pdacl = temp->next;
1184                 *savePtr = pdacl;
1185                 return pdacl;
1186             }
1187         }
1188     }
1189
1190     // Cleanup in case no PDACL is found
1191     *savePtr = NULL;
1192     return NULL;
1193 }
1194
1195 /**
1196  * This method return whether device is paired or not.
1197  *
1198  * @param pdeviceId Target device ID to find in paired list.
1199  * @retval  ture if device is already paired, else false
1200  */
1201 bool IsPairedDevice(const OicUuid_t* pdeviceId)
1202 {
1203     // Find if 'pdeviceId' is in paired device list.
1204     for(size_t i=0; i<gPconf->pddevLen; i++)
1205     {
1206         if (memcmp(&(gPconf->pddevs[i]), pdeviceId, sizeof(OicUuid_t)) == 0)
1207         {
1208             return true;
1209         }
1210     }
1211     return false;
1212 }