Imported Upstream version 1.1.1
[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 = 4;
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;
172     CborEncoder pconfMap;
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;
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;
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;
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;
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;
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_REL_NAME,
285                         strlen(OIC_JSON_REL_NAME));
286                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
287
288                 // TODO : Need to assign real value of REL
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 REL Value.");
292
293                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
294                         strlen(OIC_JSON_RT_NAME));
295                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
296
297                 // TODO : Need to assign real value of RT
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 RT Value.");
301
302                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
303                         strlen(OIC_JSON_IF_NAME));
304                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
305
306                 // TODO : Need to assign real value of IF
307                 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
308                         strlen(OIC_JSON_EMPTY_STRING));
309                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
310
311                 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
312                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
313             }
314
315             cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &resources);
316             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,  "Failed to close resource array");
317
318             // Permissions -- Mandatory
319             cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERMISSION_NAME,
320                     strlen(OIC_JSON_PERMISSION_NAME));
321             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,  "Failed to create permition string");
322             cborEncoderResult = cbor_encode_int(&pdAclMap, pdacl->permission);
323             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode permition calue");
324
325             // Period -- Not Mandatory
326             if (pdacl->periods)
327             {
328                 CborEncoder period;
329                 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERIODS_NAME,
330                         strlen(OIC_JSON_PERIODS_NAME));
331                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period value");
332                 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &period,
333                         pdacl->prdRecrLen);
334                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
335
336                 for (size_t i = 0; i < pdacl->prdRecrLen; i++)
337                 {
338                     cborEncoderResult = cbor_encode_text_string(&period, pdacl->periods[i],
339                             strlen(pdacl->periods[i]));
340                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period");
341                 }
342                 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &period);
343                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to close period array");
344             }
345
346             // Period -- Not Mandatory
347             if(0 != pdacl->prdRecrLen && pdacl->recurrences)
348             {
349                 CborEncoder recurrences;
350                 cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RECURRENCES_NAME,
351                         strlen(OIC_JSON_RECURRENCES_NAME));
352                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to encode recurrences");
353                 cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &recurrences,
354                         pdacl->prdRecrLen);
355                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create rec array");
356
357                 for (size_t i = 0; i < pdacl->prdRecrLen; i++)
358                 {
359                     cborEncoderResult = cbor_encode_text_string(&recurrences,
360                             pdacl->recurrences[i], strlen(pdacl->recurrences[i]));
361                     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode recurrences");
362                 }
363                 cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &recurrences);
364                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close rec array");
365             }
366             cborEncoderResult = cbor_encoder_close_container(&pdAclArray, &pdAclMap);
367             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl map");
368
369             pdacl = pdacl->next;
370         }
371         //clsoe the array
372         cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pdAclArray);
373         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl array");
374     }
375
376     //PDDev -- Mandatory
377     //There may not be paired devices if it did not pairing before
378     if (pconf->pddevs && 0 < pconf->pddevLen)
379     {
380         CborEncoder pddev;
381         cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDDEV_LIST_NAME,
382                 strlen(OIC_JSON_PDDEV_LIST_NAME));
383         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode pddev");
384         cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pddev,  pconf->pddevLen);
385         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
386
387         for (size_t i = 0; i < pconf->pddevLen; i++)
388         {
389             char *pddevId = NULL;
390             ret = ConvertUuidToStr(&pconf->pddevs[i], &pddevId);
391             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
392             cborEncoderResult = cbor_encode_text_string(&pddev, pddevId, strlen(pddevId));
393             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding pddev Id Value.");
394             OICFree(pddevId);
395         }
396         cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pddev);
397         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pddev array");
398     }
399
400     //DeviceId -- Mandatory
401     //There may not be devicd id if caller is provisoning tool
402     cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_DEVICE_ID_NAME,
403             strlen(OIC_JSON_DEVICE_ID_NAME));
404     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode device id");
405     {
406         char *deviceId = NULL;
407         ret = ConvertUuidToStr(&pconf->deviceID, &deviceId);
408         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
409         cborEncoderResult = cbor_encode_text_string(&pconfMap, deviceId, strlen(deviceId));
410         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode deviceID value");
411         OICFree(deviceId);
412     }
413
414     //ROwner -- Mandatory
415     {
416         char *rowner = NULL;
417         cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_ROWNERID_NAME,
418                 strlen(OIC_JSON_ROWNERID_NAME));
419         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rowner string");
420         ret = ConvertUuidToStr(&pconf->rownerID, &rowner);
421         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
422         cborEncoderResult = cbor_encode_text_string(&pconfMap, rowner, strlen(rowner));
423         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rwoner value");
424         OICFree(rowner);
425     }
426
427     cborEncoderResult = cbor_encoder_close_container(&encoder, &pconfMap);
428     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pconfMap");
429
430     *size = encoder.ptr - outPayload;
431     *payload = outPayload;
432     ret = OC_STACK_OK;
433 exit:
434     if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
435     {
436         // reallocate and try again!
437         OICFree(outPayload);
438         // Since the allocated initial memory failed, double the memory.
439         cborLen += encoder.ptr - encoder.end;
440         cborEncoderResult = CborNoError;
441         ret = PconfToCBORPayload(pconf, payload, &cborLen);
442         *size = cborLen;
443     }
444     if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
445     {
446         OICFree(outPayload);
447         outPayload = NULL;
448         *payload = NULL;
449         *size = 0;
450         ret = OC_STACK_ERROR;
451     }
452     return ret;
453 }
454
455 OCStackResult CBORPayloadToPconf(const uint8_t *cborPayload, size_t size, OicSecPconf_t **secPconf)
456 {
457     if (NULL == cborPayload || NULL == secPconf || NULL != *secPconf || 0 == size)
458     {
459         return OC_STACK_INVALID_PARAM;
460     }
461     OCStackResult ret = OC_STACK_ERROR;
462     *secPconf = NULL;
463     CborValue pconfCbor = { .parser = NULL };
464     CborParser parser = { .end = NULL };
465     CborError cborFindResult = CborNoError;
466
467     cbor_parser_init(cborPayload, size, 0, &parser, &pconfCbor);
468     CborValue pconfMap = { .parser = NULL } ;
469     OicSecPconf_t *pconf = NULL;
470     cborFindResult = cbor_value_enter_container(&pconfCbor, &pconfMap);
471     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter map");
472     pconf = (OicSecPconf_t *)OICCalloc(1, sizeof(*pconf));
473     VERIFY_NON_NULL(TAG, pconf, ERROR);
474     while (cbor_value_is_valid(&pconfMap))
475     {
476         char *name = NULL;
477         size_t len = 0;
478         CborType type = cbor_value_get_type(&pconfMap);
479         if (type == CborTextStringType && cbor_value_is_text_string(&pconfMap))
480         {
481             cborFindResult = cbor_value_dup_text_string(&pconfMap, &name, &len, NULL);
482             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
483             cborFindResult = cbor_value_advance(&pconfMap);
484             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
485         }
486
487         if (name)
488         {
489             //EDP -- Mandatory
490             if(0 == strcmp(OIC_JSON_EDP_NAME, name) && cbor_value_is_boolean(&pconfMap))
491             {
492                 cborFindResult = cbor_value_get_boolean(&pconfMap, &pconf->edp);
493                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
494             }
495             if (0 == strcmp(OIC_JSON_PRM_NAME, name))
496             {
497                 int i = 0;
498                 CborValue prm = { .parser = NULL };
499                 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->prmLen);
500                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
501                 VERIFY_SUCCESS(TAG, pconf->prmLen != 0, ERROR);
502
503                 pconf->prm = (OicSecPrm_t *)OICCalloc(pconf->prmLen, sizeof(OicSecPrm_t));
504                 VERIFY_NON_NULL(TAG, pconf->prm, ERROR);
505                 cborFindResult = cbor_value_enter_container(&pconfMap, &prm);
506                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to eneter array");
507
508                 while (cbor_value_is_valid(&prm) && cbor_value_is_integer(&prm))
509                 {
510                     cborFindResult = cbor_value_get_int(&prm, (int *)&pconf->prm[i++]);
511                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
512                     cborFindResult = cbor_value_advance(&prm);
513                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
514                 }
515             }
516             //PIN -- Mandatory
517             if (0 == strcmp(OIC_JSON_PIN_NAME, name) && cbor_value_is_byte_string(&pconfMap))
518             {
519                 uint8_t *pin = NULL;
520                 cborFindResult = cbor_value_dup_byte_string(&pconfMap, &pin, &len, NULL);
521                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
522                 memcpy(pconf->pin.val, pin, len);
523                 OICFree(pin);
524             }
525
526             //PDACL -- Mandatory
527             if (0 == strcmp(OIC_JSON_PDACL_NAME, name))
528             {
529                 CborValue pdAclArray = { .parser = NULL};
530                 OicSecPdAcl_t *headPdacl = NULL;
531
532                 cborFindResult = cbor_value_enter_container(&pconfMap, &pdAclArray);
533                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
534
535                 while (cbor_value_is_valid(&pdAclArray))
536                 {
537                     CborValue pdAclMap = { .parser = NULL};
538                     OicSecPdAcl_t *pdacl = (OicSecPdAcl_t *) OICCalloc(1, sizeof(OicSecPdAcl_t));
539                     VERIFY_NON_NULL(TAG, pdacl, ERROR);
540
541                     cborFindResult = cbor_value_enter_container(&pdAclArray, &pdAclMap);
542                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
543
544                     while (cbor_value_is_valid(&pdAclMap))
545                     {
546                         char* name = NULL;
547                         size_t len = 0;
548                         CborType type = cbor_value_get_type(&pdAclMap);
549                         if (type == CborTextStringType && cbor_value_is_text_string(&pdAclMap))
550                         {
551                             cborFindResult = cbor_value_dup_text_string(&pdAclMap, &name,
552                                     &len, NULL);
553                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
554                             cborFindResult = cbor_value_advance(&pdAclMap);
555                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
556                         }
557                         if (name)
558                         {
559                             // Resources -- Mandatory
560                             if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0 && cbor_value_is_array(&pdAclMap))
561                             {
562                                 int i = 0;
563                                 CborValue resources = { .parser = NULL };
564                                 cborFindResult = cbor_value_get_array_length(&pdAclMap,
565                                         &pdacl->resourcesLen);
566                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
567                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &resources);
568                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
569                                 pdacl->resources = (char **) OICCalloc(pdacl->resourcesLen,
570                                         sizeof(char*));
571                                 VERIFY_NON_NULL(TAG, pdacl->resources, ERROR);
572
573                                 while (cbor_value_is_valid(&resources))
574                                 {
575                                     CborValue rMap = { .parser = NULL  };
576                                     cborFindResult = cbor_value_enter_container(&resources, &rMap);
577                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
578
579                                     while(cbor_value_is_valid(&rMap) && cbor_value_is_text_string(&rMap))
580                                     {
581                                         char *rMapName = NULL;
582                                         size_t rMapNameLen = 0;
583                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
584                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
585                                         cborFindResult = cbor_value_advance(&rMap);
586                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
587
588                                         // "href"
589                                         if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
590                                         {
591                                             // TODO : Need to check data structure of OicSecPdAcl_t based on RAML spec.
592                                             cborFindResult = cbor_value_dup_text_string(&rMap, &pdacl->resources[i++], &len, NULL);
593                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
594                                         }
595
596                                         // "rel"
597                                         if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
598                                         {
599                                             // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
600                                             char *relData = NULL;
601                                             cborFindResult = cbor_value_dup_text_string(&rMap, &relData, &len, NULL);
602                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
603                                             OICFree(relData);
604                                         }
605
606                                         // "rt"
607                                         if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
608                                         {
609                                             // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
610                                             char *rtData = NULL;
611                                             cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
612                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
613                                             OICFree(rtData);
614                                         }
615
616                                         // "if"
617                                         if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
618                                         {
619                                             // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
620                                             char *ifData = NULL;
621                                             cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
622                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
623                                             OICFree(ifData);
624                                         }
625
626                                         if (cbor_value_is_valid(&rMap))
627                                         {
628                                             cborFindResult = cbor_value_advance(&rMap);
629                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
630                                         }
631                                         OICFree(rMapName);
632                                     }
633
634                                     if (cbor_value_is_valid(&resources))
635                                     {
636                                         cborFindResult = cbor_value_advance(&resources);
637                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
638                                     }
639                                 }
640                             }
641
642                             // Permissions -- Mandatory
643                             if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0 && cbor_value_is_unsigned_integer(&pdAclMap))
644                             {
645                                 uint64_t permission = 0;
646                                 cborFindResult = cbor_value_get_uint64(&pdAclMap, &permission);
647                                 pdacl->permission = (uint16_t)permission;
648                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
649                             }
650
651                             // Period -- Not mandatory
652                             if (strcmp(name, OIC_JSON_PERIODS_NAME) == 0 && cbor_value_is_array(&pdAclMap))
653                             {
654                                 int i = 0;
655                                 CborValue period = { .parser = NULL };
656                                 cborFindResult = cbor_value_get_array_length(&pdAclMap,
657                                         &pdacl->prdRecrLen);
658                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
659                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &period);
660                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
661                                 pdacl->periods = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
662                                 VERIFY_NON_NULL(TAG, pdacl->periods, ERROR);
663
664                                 while (cbor_value_is_text_string(&period) && cbor_value_is_text_string(&period))
665                                 {
666                                     cborFindResult = cbor_value_dup_text_string(&period,
667                                             &pdacl->periods[i++], &len, NULL);
668                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
669                                     cborFindResult = cbor_value_advance(&period);
670                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
671                                     pdacl->prdRecrLen++;
672                                 }
673                             }
674
675                             // Recurrence -- Not mandatory
676                             if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0 && cbor_value_is_array(&pdAclMap))
677                             {
678                                 int i = 0;
679                                 CborValue recurrences = { .parser = NULL };
680                                 cborFindResult = cbor_value_get_array_length(&pdAclMap, &pdacl->prdRecrLen);
681                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
682                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &recurrences);
683                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
684                                 pdacl->recurrences = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
685                                 VERIFY_NON_NULL(TAG, pdacl->recurrences, ERROR);
686
687                                 while (cbor_value_is_text_string(&recurrences) && cbor_value_is_text_string(&recurrences))
688                                 {
689                                     cborFindResult = cbor_value_dup_text_string(&recurrences,
690                                             &pdacl->recurrences[i++], &len, NULL);
691                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
692                                     cborFindResult = cbor_value_advance(&recurrences);
693                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
694                                 }
695                             }
696                             if (type != CborMapType && cbor_value_is_valid(&pdAclMap))
697                             {
698                                 cborFindResult = cbor_value_advance(&pdAclMap);
699                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
700                             }
701                         }
702                         if (cbor_value_is_valid(&pdAclArray))
703                         {
704                             cborFindResult = cbor_value_advance(&pdAclArray);
705                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
706                         }
707                         OICFree(name);
708                         name = NULL;
709                     }
710                     pdacl->next = NULL;
711                     if (headPdacl == NULL)
712                     {
713                         headPdacl = pdacl;
714                     }
715                     else
716                     {
717                         OicSecPdAcl_t *temp = headPdacl;
718                         while (temp->next)
719                         {
720                             temp = temp->next;
721                         }
722                         temp->next = pdacl;
723                     }
724                 }
725                 pconf->pdacls = headPdacl;
726             }
727
728             //PDDev -- Mandatory
729             if (strcmp(name, OIC_JSON_PDDEV_LIST_NAME) == 0 && cbor_value_is_array(&pconfMap))
730             {
731                 int i = 0;
732                 CborValue pddevs = { .parser = NULL };
733                 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->pddevLen);
734                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
735                 cborFindResult = cbor_value_enter_container(&pconfMap, &pddevs);
736                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
737
738                 pconf->pddevs = (OicUuid_t *)OICMalloc(pconf->pddevLen * sizeof(OicUuid_t));
739                 VERIFY_NON_NULL(TAG, pconf->pddevs, ERROR);
740                 while (cbor_value_is_valid(&pddevs) && cbor_value_is_text_string(&pddevs))
741                 {
742                     char *pddev = NULL;
743                     cborFindResult = cbor_value_dup_text_string(&pddevs, &pddev, &len, NULL);
744                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
745                     cborFindResult = cbor_value_advance(&pddevs);
746                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
747                     ret = ConvertStrToUuid(pddev, &pconf->pddevs[i++]);
748                     VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
749                     OICFree(pddev);
750                 }
751             }
752
753             //Mandatory - Device Id
754             if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name) && cbor_value_is_text_string(&pconfMap))
755             {
756                 char *deviceId = NULL;
757                 cborFindResult = cbor_value_dup_text_string(&pconfMap, &deviceId, &len, NULL);
758                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get deviceID");
759                 ret = ConvertStrToUuid(deviceId, &pconf->deviceID);
760                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
761                 OICFree(deviceId);
762             }
763
764             // ROwner -- Mandatory
765             if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name) && cbor_value_is_text_string(&pconfMap))
766             {
767                 char *rowner = NULL;
768                 cborFindResult = cbor_value_dup_text_string(&pconfMap, &rowner, &len, NULL);
769                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get rowner");
770                 ret = ConvertStrToUuid(rowner, &pconf->rownerID);
771                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
772                 OICFree(rowner);
773             }
774         }
775         if (CborMapType != type && cbor_value_is_valid(&pconfMap))
776         {
777             cborFindResult = cbor_value_advance(&pconfMap);
778             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
779         }
780         OICFree(name);
781         name = NULL;
782     }
783     *secPconf=pconf;
784     ret = OC_STACK_OK;
785 exit:
786     if (CborNoError != cborFindResult)
787     {
788         OIC_LOG (ERROR, TAG, "CBORPayloadToPconf failed");
789         DeletePconfBinData(pconf);
790         pconf = NULL;
791         *secPconf = NULL;
792         ret = OC_STACK_ERROR;
793     }
794     return ret;
795 }
796
797 static bool UpdatePersistentStorage(const OicSecPconf_t * pconf)
798 {
799     bool ret = false;
800
801     // Convert PCONF data into Cborpayload for update to persistent storage
802     uint8_t *payload = NULL;
803     size_t size = 0;
804     if (OC_STACK_OK == PconfToCBORPayload(pconf, &payload, &size) && NULL !=payload)
805     {
806         if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, payload, size))
807         {
808             ret = true;
809         }
810         OICFree(payload);
811     }
812     return ret;
813 }
814
815 static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest * ehRequest)
816 {
817     uint8_t* payload = NULL;
818     size_t size = 0;
819     OCEntityHandlerResult ehRet = OC_EH_OK;
820
821     OicSecPconf_t pconf;
822     memset(&pconf, 0, sizeof(OicSecPconf_t));
823
824     OIC_LOG (DEBUG, TAG, "Pconf EntityHandle processing GET request");
825
826     if (true == GetDoxmResourceData()->dpc)
827     {
828         //Making response elements for Get request
829         if( (true == gPconf->edp) &&
830             (gPconf->prm && 0 < gPconf->prmLen) &&
831             (0 < strlen((const char*)gPconf->deviceID.id)) &&
832             (0 < strlen((const char*)gPconf->rownerID.id)))
833         {
834             pconf.edp = true;
835             pconf.prm = gPconf->prm;
836             pconf.prmLen = gPconf->prmLen;
837             memcpy(&pconf.deviceID, &gPconf->deviceID, sizeof(OicUuid_t));
838             memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
839             OIC_LOG (DEBUG, TAG, "PCONF - direct pairing enabled");
840         }
841         else if (false == gPconf->edp)
842         {
843             pconf.edp = false;
844             memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
845             OIC_LOG (DEBUG, TAG, "PCONF - direct pairing disable");
846         }
847         else
848         {
849             ehRet= OC_EH_ERROR;
850             OIC_LOG (DEBUG, TAG, "PCONF - error");
851         }
852     }
853     else
854     {
855         OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
856     }
857
858
859     if (OC_STACK_OK != PconfToCBORPayload(gPconf, &payload, &size))
860     {
861         ehRet = OC_EH_ERROR;
862     }
863
864     if(OC_EH_OK == ehRet)
865     {
866         ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
867     }
868     else
869     {
870         OICFree(payload);
871         payload = NULL;
872         size = 0;
873     }
874
875     // Send response payload to request originator
876     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
877     {
878         ehRet = OC_EH_ERROR;
879         OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfGetRequest");
880     }
881     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
882
883     OICFree(payload);
884     return ehRet;
885 }
886
887 static OCEntityHandlerResult HandlePconfPostRequest (const OCEntityHandlerRequest * ehRequest)
888 {
889     OCEntityHandlerResult ehRet = OC_EH_OK;
890     OCStackResult res=OC_STACK_OK;
891     OicSecPconf_t* newPconf = NULL;
892
893     if (true == GetDoxmResourceData()->dpc)
894     {
895         // Convert CBOR PCONF data into binary. This will also validate the PCONF data received.
896         uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
897         size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
898
899         if(payload){
900             res = CBORPayloadToPconf(payload, size, &newPconf);
901         }
902     }
903     else
904     {
905         OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
906         ehRet = OC_EH_ERROR;
907     }
908
909     if (newPconf && res == OC_STACK_OK)
910     {
911         // Check if valid Post request
912         if ((true == newPconf->edp) && (0 < newPconf->prmLen) &&
913                 DP_PIN_LENGTH == sizeof(newPconf->pin.val))
914         {
915             OicSecPrm_t *oldPrm = gPconf->prm;
916             OicSecPdAcl_t *oldPdacl = gPconf->pdacls;
917
918             // Update local PCONF with new PCONF
919             gPconf->edp = true;
920             memcpy(&gPconf->pin, &newPconf->pin, sizeof(OicDpPin_t));
921             gPconf->prm = newPconf->prm;
922             gPconf->prmLen = newPconf->prmLen;
923             gPconf->pdacls = newPconf->pdacls;
924             memcpy(&gPconf->rownerID, &newPconf->rownerID, sizeof(OicUuid_t));
925
926             // to delete old value(prm, pdacl)
927             newPconf->prm = oldPrm;
928             newPconf->pdacls = oldPdacl;
929         }
930         else if (false == newPconf->edp)
931         {
932             gPconf->edp = false;
933         }
934         else
935         {
936             ehRet = OC_EH_ERROR;
937         }
938
939         // Update storage
940         if(OC_EH_ERROR != ehRet && true == UpdatePersistentStorage(gPconf))
941         {
942             ehRet = OC_EH_CHANGED;
943         }
944
945         DeletePconfBinData(newPconf);
946     }
947     else
948     {
949         ehRet = OC_EH_ERROR;
950     }
951
952     // Send payload to request originator
953     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
954     {
955         ehRet = OC_EH_ERROR;
956         OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfPostRequest");
957     }
958
959     OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
960     return ehRet;
961 }
962
963 /*
964  * This internal method is the entity handler for PCONF resources and
965  * will handle REST request (POST) for them.
966  */
967 OCEntityHandlerResult PconfEntityHandler (OCEntityHandlerFlag flag,
968                                         OCEntityHandlerRequest * ehRequest,
969                                         void* callbackParameter)
970 {
971     OIC_LOG(DEBUG, TAG, "Received request PconfEntityHandler");
972     (void)callbackParameter;
973     OCEntityHandlerResult ehRet = OC_EH_ERROR;
974
975     if (!ehRequest)
976     {
977         return ehRet;
978     }
979
980     if (flag & OC_REQUEST_FLAG)
981     {
982         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
983         switch (ehRequest->method)
984         {
985             case OC_REST_GET:
986                 ehRet = HandlePconfGetRequest(ehRequest);
987                 break;
988
989             case OC_REST_POST:
990                 ehRet = HandlePconfPostRequest(ehRequest);
991                 break;
992
993             case OC_REST_DELETE:
994                 break;
995
996             default:
997                 ehRet = OC_EH_ERROR;
998                 SendSRMResponse(ehRequest, ehRet, NULL, 0);
999         }
1000     }
1001
1002     return ehRet;
1003 }
1004
1005 /*
1006  * This internal method is used to create '/oic/sec/pconf' resource.
1007  */
1008 OCStackResult CreatePconfResource()
1009 {
1010     OCStackResult ret;
1011
1012     ret = OCCreateResource(&gPconfHandle,
1013                            OIC_RSRC_TYPE_SEC_PCONF,
1014                            OC_RSRVD_INTERFACE_DEFAULT,
1015                            OIC_RSRC_PCONF_URI,
1016                            PconfEntityHandler,
1017                            NULL,
1018                            OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
1019
1020     if (OC_STACK_OK != ret)
1021     {
1022         OIC_LOG (ERROR, TAG, "Unable to instantiate PCONF resource");
1023         DeInitPconfResource();
1024     }
1025     return ret;
1026 }
1027
1028 /**
1029  * Get the default value.
1030  * @retval  the gDefaultPconf pointer;
1031  */
1032 static OicSecPconf_t* GetPconfDefault()
1033 {
1034     OIC_LOG (DEBUG, TAG, "GetPconfDefault");
1035
1036     return &gDefaultPconf;
1037 }
1038
1039 /**
1040  * This method is used by SRM to retrieve PCONF resource data..
1041  *
1042  * @retval  reference to @ref OicSecPconf_t, binary format of Pconf resource data
1043  */
1044 const OicSecPconf_t* GetPconfResourceData()
1045 {
1046     return gPconf;
1047 }
1048
1049 /**
1050  * Initialize PCONF resource by loading data from persistent storage.
1051  *
1052  * @retval  OC_STACK_OK for Success, otherwise some error value
1053  */
1054 OCStackResult InitPconfResource()
1055 {
1056     OCStackResult ret = OC_STACK_ERROR;
1057
1058     uint8_t *data = NULL;
1059     size_t size = 0;
1060
1061     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PCONF_NAME, &data, &size);
1062     // If database read failed
1063     if (ret != OC_STACK_OK)
1064     {
1065         OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
1066     }
1067     if (data)
1068     {
1069         CBORPayloadToPconf(data, size, &gPconf);
1070     }
1071
1072     if (!data || !gPconf)
1073     {
1074         gPconf = GetPconfDefault();
1075
1076         // device id from doxm
1077         OicUuid_t deviceId = {.id = {0}};
1078         OCStackResult ret = GetDoxmDeviceID( &deviceId);
1079         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1080         memcpy(&gPconf->deviceID, &deviceId, sizeof(OicUuid_t));
1081     }
1082     VERIFY_NON_NULL(TAG, gPconf, ERROR);
1083
1084     // Instantiate 'oic.sec.pconf'
1085     ret = CreatePconfResource();
1086
1087 exit:
1088     if (OC_STACK_OK != ret)
1089     {
1090         DeInitPconfResource();
1091     }
1092     OICFree(data);
1093     return ret;
1094 }
1095
1096 /**
1097  * Perform cleanup for PCONF resources.
1098  *
1099  * @return
1100  * OC_STACK_OK    - no error
1101  * OC_STACK_ERROR - stack process error
1102  *
1103  */
1104 OCStackResult DeInitPconfResource()
1105 {
1106     OCStackResult ret = OCDeleteResource(gPconfHandle);
1107     if(gPconf!= &gDefaultPconf)
1108     {
1109         DeletePconfBinData(gPconf);
1110     }
1111     gPconf = NULL;
1112
1113     if(OC_STACK_OK == ret)
1114     {
1115         return OC_STACK_OK;
1116     }
1117     else
1118     {
1119         return OC_STACK_ERROR;
1120     }
1121 }
1122
1123 /**
1124  * This method might be used to add a paired device id after direct-pairing process complete.
1125  *
1126  * @param pdeviceId ID of the paired device.
1127  *
1128  * @retval  OC_STACK_OK for Success, otherwise some error value
1129  */
1130 OCStackResult AddPairedDevice(OicUuid_t *pdeviceId)
1131 {
1132     if (!gPconf || !pdeviceId)
1133     {
1134         return OC_STACK_INVALID_PARAM;
1135     }
1136
1137
1138     OicUuid_t *prevList = gPconf->pddevs;
1139     gPconf->pddevs = (OicUuid_t *)OICCalloc(gPconf->pddevLen+1, sizeof(OicUuid_t));
1140     if(!gPconf->pddevs)
1141     {
1142         return OC_STACK_NO_MEMORY;
1143     }
1144     for (size_t i=0; i<gPconf->pddevLen; i++)
1145     {
1146         memcpy(&gPconf->pddevs[i], &prevList[i], sizeof(OicUuid_t));
1147     }
1148
1149     // add new paired device id
1150     memcpy(&gPconf->pddevs[gPconf->pddevLen], pdeviceId, sizeof(OicUuid_t));
1151     gPconf->pddevLen++;
1152
1153     // Update storage
1154     if(true != UpdatePersistentStorage(gPconf))
1155     {
1156         OIC_LOG (ERROR, TAG, "Fail to update pconf resource");
1157         return OC_STACK_ERROR;
1158     }
1159
1160     OIC_LOG (ERROR, TAG, "Add paired device success");
1161     return OC_STACK_OK;
1162 }
1163
1164 /**
1165  * This method might be used by PolicyEngine to retrieve PDACL for a Subject.
1166  *
1167  * @param subjectId ID of the subject for which PDACL is required.
1168  * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
1169  *                successive calls for same subjectId.
1170  *
1171  * @retval  reference to @ref OicSecPdAcl_t if PDACL is found, else NULL
1172  */
1173 const OicSecPdAcl_t* GetPdAclData(const OicUuid_t* subjectId, OicSecPdAcl_t **savePtr)
1174 {
1175     OicSecPdAcl_t *pdacl = NULL;
1176
1177     if ( NULL == subjectId)
1178     {
1179         return NULL;
1180     }
1181
1182     /*
1183      * savePtr MUST point to NULL if this is the 'first' call to retrieve PDACL for
1184      * subjectID.
1185      */
1186     if (NULL == *savePtr)
1187     {
1188         pdacl = gPconf->pdacls;
1189
1190         // Find if 'subjectID' is in paired device list.
1191         for(size_t i=0; i<gPconf->pddevLen; i++)
1192         {
1193             if (memcmp(&(gPconf->pddevs[i]), subjectId, sizeof(OicUuid_t)) == 0)
1194             {
1195                 *savePtr = pdacl;
1196                 return pdacl;
1197             }
1198         }
1199     }
1200     else
1201     {
1202         OicSecPdAcl_t *temp = NULL;
1203
1204         /*
1205          * If this is a 'successive' call, search for location pointed by
1206          * savePtr and assign 'begin' to the next PDACL after it in the linked
1207          * list and start searching from there.
1208          */
1209         LL_FOREACH(gPconf->pdacls, temp)
1210         {
1211             if (temp == *savePtr)
1212             {
1213                 pdacl = temp->next;
1214                 *savePtr = pdacl;
1215                 return pdacl;
1216             }
1217         }
1218     }
1219
1220     // Cleanup in case no PDACL is found
1221     *savePtr = NULL;
1222     return NULL;
1223 }
1224
1225 /**
1226  * This method return whether device is paired or not.
1227  *
1228  * @param pdeviceId Target device ID to find in paired list.
1229  * @retval  ture if device is already paired, else false
1230  */
1231 bool IsPairedDevice(const OicUuid_t* pdeviceId)
1232 {
1233     // Find if 'pdeviceId' is in paired device list.
1234     for(size_t i=0; i<gPconf->pddevLen; i++)
1235     {
1236         if (memcmp(&(gPconf->pddevs[i]), pdeviceId, sizeof(OicUuid_t)) == 0)
1237         {
1238             return true;
1239         }
1240     }
1241     return false;
1242 }
1243
1244 OCStackResult SetPconfRownerId(const OicUuid_t* newROwner)
1245 {
1246     OCStackResult ret = OC_STACK_ERROR;
1247     uint8_t *cborPayload = NULL;
1248     size_t size = 0;
1249     OicUuid_t prevId = {.id={0}};
1250
1251     if(NULL == newROwner)
1252     {
1253         ret = OC_STACK_INVALID_PARAM;
1254     }
1255     if(NULL == gPconf)
1256     {
1257         ret = OC_STACK_NO_RESOURCE;
1258     }
1259
1260     if(newROwner && gPconf)
1261     {
1262         memcpy(prevId.id, gPconf->rownerID.id, sizeof(prevId.id));
1263         memcpy(gPconf->rownerID.id, newROwner->id, sizeof(newROwner->id));
1264
1265         ret = PconfToCBORPayload(gPconf, &cborPayload, &size);
1266         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1267
1268         ret = UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, cborPayload, size);
1269         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1270
1271         OICFree(cborPayload);
1272     }
1273
1274     return ret;
1275
1276 exit:
1277     OICFree(cborPayload);
1278     memcpy(gPconf->rownerID.id, prevId.id, sizeof(prevId.id));
1279     return ret;
1280 }
1281
1282 OCStackResult GetPconfRownerId(OicUuid_t *rowneruuid)
1283 {
1284     OCStackResult retVal = OC_STACK_ERROR;
1285     if (gPconf)
1286     {
1287         *rowneruuid = gPconf->rownerID;
1288         retVal = OC_STACK_OK;
1289     }
1290     return retVal;
1291 }