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