Merge branch 'master' into extended-easysetup
[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 HAVE_STRINGS_H
43 #include <strings.h>
44 #endif
45
46 #define TAG  "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_NON_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 = encoder.ptr - 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 += encoder.ptr - 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_NON_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_NON_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                     cborFindResult = cbor_value_get_int(&prm, (int *)&pconf->prm[i++]);
509                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
510                     cborFindResult = cbor_value_advance(&prm);
511                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
512                 }
513             }
514             //PIN -- Mandatory
515             if (0 == strcmp(OIC_JSON_PIN_NAME, name) && cbor_value_is_byte_string(&pconfMap))
516             {
517                 uint8_t *pin = NULL;
518                 cborFindResult = cbor_value_dup_byte_string(&pconfMap, &pin, &len, NULL);
519                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
520                 memcpy(pconf->pin.val, pin, len);
521                 OICFree(pin);
522             }
523
524             //PDACL -- Mandatory
525             if (0 == strcmp(OIC_JSON_PDACL_NAME, name))
526             {
527                 CborValue pdAclArray = { .parser = NULL};
528                 OicSecPdAcl_t *headPdacl = NULL;
529
530                 cborFindResult = cbor_value_enter_container(&pconfMap, &pdAclArray);
531                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
532
533                 while (cbor_value_is_valid(&pdAclArray))
534                 {
535                     CborValue pdAclMap = { .parser = NULL};
536                     OicSecPdAcl_t *pdacl = (OicSecPdAcl_t *) OICCalloc(1, sizeof(OicSecPdAcl_t));
537                     VERIFY_NON_NULL(TAG, pdacl, ERROR);
538
539                     cborFindResult = cbor_value_enter_container(&pdAclArray, &pdAclMap);
540                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
541
542                     while (cbor_value_is_valid(&pdAclMap))
543                     {
544                         char* name = NULL;
545                         size_t len = 0;
546                         CborType type = cbor_value_get_type(&pdAclMap);
547                         if (type == CborTextStringType && cbor_value_is_text_string(&pdAclMap))
548                         {
549                             cborFindResult = cbor_value_dup_text_string(&pdAclMap, &name,
550                                     &len, NULL);
551                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
552                             cborFindResult = cbor_value_advance(&pdAclMap);
553                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
554                         }
555                         if (name)
556                         {
557                             // Resources -- Mandatory
558                             if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0 && cbor_value_is_array(&pdAclMap))
559                             {
560                                 int i = 0;
561                                 CborValue resources = { .parser = NULL };
562                                 cborFindResult = cbor_value_get_array_length(&pdAclMap,
563                                         &pdacl->resourcesLen);
564                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
565                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &resources);
566                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
567                                 pdacl->resources = (char **) OICCalloc(pdacl->resourcesLen,
568                                         sizeof(char*));
569                                 VERIFY_NON_NULL(TAG, pdacl->resources, ERROR);
570
571                                 while (cbor_value_is_valid(&resources))
572                                 {
573                                     CborValue rMap = { .parser = NULL  };
574                                     cborFindResult = cbor_value_enter_container(&resources, &rMap);
575                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
576
577                                     while(cbor_value_is_valid(&rMap) && cbor_value_is_text_string(&rMap))
578                                     {
579                                         char *rMapName = NULL;
580                                         size_t rMapNameLen = 0;
581                                         cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
582                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
583                                         cborFindResult = cbor_value_advance(&rMap);
584                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
585
586                                         // "href"
587                                         if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
588                                         {
589                                             // TODO : Need to check data structure of OicSecPdAcl_t based on RAML spec.
590                                             cborFindResult = cbor_value_dup_text_string(&rMap, &pdacl->resources[i++], &len, NULL);
591                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
592                                         }
593
594                                         // "rel"
595                                         if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
596                                         {
597                                             // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
598                                             char *relData = NULL;
599                                             cborFindResult = cbor_value_dup_text_string(&rMap, &relData, &len, NULL);
600                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
601                                             OICFree(relData);
602                                         }
603
604                                         // "rt"
605                                         if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
606                                         {
607                                             // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
608                                             char *rtData = NULL;
609                                             cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
610                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
611                                             OICFree(rtData);
612                                         }
613
614                                         // "if"
615                                         if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
616                                         {
617                                             // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
618                                             char *ifData = NULL;
619                                             cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
620                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
621                                             OICFree(ifData);
622                                         }
623
624                                         if (cbor_value_is_valid(&rMap))
625                                         {
626                                             cborFindResult = cbor_value_advance(&rMap);
627                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
628                                         }
629                                         OICFree(rMapName);
630                                     }
631
632                                     if (cbor_value_is_valid(&resources))
633                                     {
634                                         cborFindResult = cbor_value_advance(&resources);
635                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
636                                     }
637                                 }
638                             }
639
640                             // Permissions -- Mandatory
641                             if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0 && cbor_value_is_unsigned_integer(&pdAclMap))
642                             {
643                                 uint64_t permission = 0;
644                                 cborFindResult = cbor_value_get_uint64(&pdAclMap, &permission);
645                                 pdacl->permission = (uint16_t)permission;
646                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
647                             }
648
649                             // Period -- Not mandatory
650                             if (strcmp(name, OIC_JSON_PERIODS_NAME) == 0 && cbor_value_is_array(&pdAclMap))
651                             {
652                                 int i = 0;
653                                 CborValue period = { .parser = NULL };
654                                 cborFindResult = cbor_value_get_array_length(&pdAclMap,
655                                         &pdacl->prdRecrLen);
656                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
657                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &period);
658                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
659                                 pdacl->periods = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
660                                 VERIFY_NON_NULL(TAG, pdacl->periods, ERROR);
661
662                                 while (cbor_value_is_text_string(&period) && cbor_value_is_text_string(&period))
663                                 {
664                                     cborFindResult = cbor_value_dup_text_string(&period,
665                                             &pdacl->periods[i++], &len, NULL);
666                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
667                                     cborFindResult = cbor_value_advance(&period);
668                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
669                                     pdacl->prdRecrLen++;
670                                 }
671                             }
672
673                             // Recurrence -- Not mandatory
674                             if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0 && cbor_value_is_array(&pdAclMap))
675                             {
676                                 int i = 0;
677                                 CborValue recurrences = { .parser = NULL };
678                                 cborFindResult = cbor_value_get_array_length(&pdAclMap, &pdacl->prdRecrLen);
679                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
680                                 cborFindResult = cbor_value_enter_container(&pdAclMap, &recurrences);
681                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
682                                 pdacl->recurrences = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
683                                 VERIFY_NON_NULL(TAG, pdacl->recurrences, ERROR);
684
685                                 while (cbor_value_is_text_string(&recurrences) && cbor_value_is_text_string(&recurrences))
686                                 {
687                                     cborFindResult = cbor_value_dup_text_string(&recurrences,
688                                             &pdacl->recurrences[i++], &len, NULL);
689                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
690                                     cborFindResult = cbor_value_advance(&recurrences);
691                                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
692                                 }
693                             }
694                             if (type != CborMapType && cbor_value_is_valid(&pdAclMap))
695                             {
696                                 cborFindResult = cbor_value_advance(&pdAclMap);
697                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
698                             }
699                         }
700                         if (cbor_value_is_valid(&pdAclArray))
701                         {
702                             cborFindResult = cbor_value_advance(&pdAclArray);
703                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
704                         }
705                         OICFree(name);
706                         name = NULL;
707                     }
708                     pdacl->next = NULL;
709                     if (headPdacl == NULL)
710                     {
711                         headPdacl = pdacl;
712                     }
713                     else
714                     {
715                         OicSecPdAcl_t *temp = headPdacl;
716                         while (temp->next)
717                         {
718                             temp = temp->next;
719                         }
720                         temp->next = pdacl;
721                     }
722                 }
723                 pconf->pdacls = headPdacl;
724             }
725
726             //PDDev -- Mandatory
727             if (strcmp(name, OIC_JSON_PDDEV_LIST_NAME) == 0 && cbor_value_is_array(&pconfMap))
728             {
729                 int i = 0;
730                 CborValue pddevs = { .parser = NULL };
731                 cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->pddevLen);
732                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
733                 cborFindResult = cbor_value_enter_container(&pconfMap, &pddevs);
734                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
735
736                 pconf->pddevs = (OicUuid_t *)OICMalloc(pconf->pddevLen * sizeof(OicUuid_t));
737                 VERIFY_NON_NULL(TAG, pconf->pddevs, ERROR);
738                 while (cbor_value_is_valid(&pddevs) && cbor_value_is_text_string(&pddevs))
739                 {
740                     char *pddev = NULL;
741                     cborFindResult = cbor_value_dup_text_string(&pddevs, &pddev, &len, NULL);
742                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
743                     cborFindResult = cbor_value_advance(&pddevs);
744                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
745                     ret = ConvertStrToUuid(pddev, &pconf->pddevs[i++]);
746                     VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
747                     OICFree(pddev);
748                 }
749             }
750
751             //Mandatory - Device Id
752             if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name) && cbor_value_is_text_string(&pconfMap))
753             {
754                 char *deviceId = NULL;
755                 cborFindResult = cbor_value_dup_text_string(&pconfMap, &deviceId, &len, NULL);
756                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get deviceID");
757                 ret = ConvertStrToUuid(deviceId, &pconf->deviceID);
758                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
759                 OICFree(deviceId);
760             }
761
762             // ROwner -- Mandatory
763             if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name) && cbor_value_is_text_string(&pconfMap))
764             {
765                 char *rowner = NULL;
766                 cborFindResult = cbor_value_dup_text_string(&pconfMap, &rowner, &len, NULL);
767                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get rowner");
768                 ret = ConvertStrToUuid(rowner, &pconf->rownerID);
769                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
770                 OICFree(rowner);
771             }
772         }
773         if (CborMapType != type && cbor_value_is_valid(&pconfMap))
774         {
775             cborFindResult = cbor_value_advance(&pconfMap);
776             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
777         }
778         OICFree(name);
779         name = NULL;
780     }
781     *secPconf=pconf;
782     ret = OC_STACK_OK;
783 exit:
784     if (CborNoError != cborFindResult)
785     {
786         OIC_LOG (ERROR, TAG, "CBORPayloadToPconf failed");
787         DeletePconfBinData(pconf);
788         pconf = NULL;
789         *secPconf = NULL;
790         ret = OC_STACK_ERROR;
791     }
792     return ret;
793 }
794
795 static bool UpdatePersistentStorage(const OicSecPconf_t * pconf)
796 {
797     bool ret = false;
798
799     // Convert PCONF data into Cborpayload for update to persistent storage
800     uint8_t *payload = NULL;
801     size_t size = 0;
802     if (OC_STACK_OK == PconfToCBORPayload(pconf, &payload, &size) && NULL !=payload)
803     {
804         if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, payload, size))
805         {
806             ret = true;
807         }
808         OICFree(payload);
809     }
810     return ret;
811 }
812
813 static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest * ehRequest)
814 {
815     uint8_t* payload = NULL;
816     size_t size = 0;
817     OCEntityHandlerResult ehRet = OC_EH_OK;
818
819     OicSecPconf_t pconf;
820     memset(&pconf, 0, sizeof(OicSecPconf_t));
821
822     OIC_LOG (DEBUG, TAG, "Pconf EntityHandle processing GET request");
823
824     if (true == GetDoxmResourceData()->dpc)
825     {
826         //Making response elements for Get request
827         if( (true == gPconf->edp) &&
828             (gPconf->prm && 0 < gPconf->prmLen) &&
829             (0 < strlen((const char*)gPconf->deviceID.id)) &&
830             (0 < strlen((const char*)gPconf->rownerID.id)))
831         {
832             pconf.edp = true;
833             pconf.prm = gPconf->prm;
834             pconf.prmLen = gPconf->prmLen;
835             memcpy(&pconf.deviceID, &gPconf->deviceID, sizeof(OicUuid_t));
836             memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
837             OIC_LOG (DEBUG, TAG, "PCONF - direct pairing enabled");
838         }
839         else if (false == gPconf->edp)
840         {
841             pconf.edp = false;
842             memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
843             OIC_LOG (DEBUG, TAG, "PCONF - direct pairing disable");
844         }
845         else
846         {
847             ehRet= OC_EH_ERROR;
848             OIC_LOG (DEBUG, TAG, "PCONF - error");
849         }
850     }
851     else
852     {
853         OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
854     }
855
856
857     if (OC_STACK_OK != PconfToCBORPayload(gPconf, &payload, &size))
858     {
859         ehRet = OC_EH_ERROR;
860     }
861
862     if(OC_EH_OK == ehRet)
863     {
864         ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
865     }
866     else
867     {
868         OICFree(payload);
869         payload = NULL;
870         size = 0;
871     }
872
873     // Send response payload to request originator
874     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
875     {
876         ehRet = OC_EH_ERROR;
877         OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfGetRequest");
878     }
879     OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
880
881     OICFree(payload);
882     return ehRet;
883 }
884
885 static OCEntityHandlerResult HandlePconfPostRequest (const OCEntityHandlerRequest * ehRequest)
886 {
887     OCEntityHandlerResult ehRet = OC_EH_OK;
888     OCStackResult res=OC_STACK_OK;
889     OicSecPconf_t* newPconf = NULL;
890
891     if (true == GetDoxmResourceData()->dpc)
892     {
893         // Convert CBOR PCONF data into binary. This will also validate the PCONF data received.
894         uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
895         size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
896
897         if(payload){
898             res = CBORPayloadToPconf(payload, size, &newPconf);
899         }
900     }
901     else
902     {
903         OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
904         ehRet = OC_EH_ERROR;
905     }
906
907     if (newPconf && res == OC_STACK_OK)
908     {
909         // Check if valid Post request
910         if ((true == newPconf->edp) && (0 < newPconf->prmLen) &&
911                 DP_PIN_LENGTH == sizeof(newPconf->pin.val))
912         {
913             OicSecPrm_t *oldPrm = gPconf->prm;
914             OicSecPdAcl_t *oldPdacl = gPconf->pdacls;
915
916             // Update local PCONF with new PCONF
917             gPconf->edp = true;
918             memcpy(&gPconf->pin, &newPconf->pin, sizeof(OicDpPin_t));
919             gPconf->prm = newPconf->prm;
920             gPconf->prmLen = newPconf->prmLen;
921             gPconf->pdacls = newPconf->pdacls;
922             memcpy(&gPconf->rownerID, &newPconf->rownerID, sizeof(OicUuid_t));
923
924             // to delete old value(prm, pdacl)
925             newPconf->prm = oldPrm;
926             newPconf->pdacls = oldPdacl;
927         }
928         else if (false == newPconf->edp)
929         {
930             gPconf->edp = false;
931         }
932         else
933         {
934             ehRet = OC_EH_ERROR;
935         }
936
937         // Update storage
938         if(OC_EH_ERROR != ehRet && true == UpdatePersistentStorage(gPconf))
939         {
940             ehRet = OC_EH_RESOURCE_CREATED;
941         }
942
943         DeletePconfBinData(newPconf);
944     }
945     else
946     {
947         ehRet = OC_EH_ERROR;
948     }
949
950     // Send payload to request originator
951     if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
952     {
953         ehRet = OC_EH_ERROR;
954         OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfPostRequest");
955     }
956
957     OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
958     return ehRet;
959 }
960
961 /*
962  * This internal method is the entity handler for PCONF resources and
963  * will handle REST request (POST) for them.
964  */
965 OCEntityHandlerResult PconfEntityHandler (OCEntityHandlerFlag flag,
966                                         OCEntityHandlerRequest * ehRequest,
967                                         void* callbackParameter)
968 {
969     OIC_LOG(DEBUG, TAG, "Received request PconfEntityHandler");
970     (void)callbackParameter;
971     OCEntityHandlerResult ehRet = OC_EH_ERROR;
972
973     if (!ehRequest)
974     {
975         return ehRet;
976     }
977
978     if (flag & OC_REQUEST_FLAG)
979     {
980         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
981         switch (ehRequest->method)
982         {
983             case OC_REST_GET:
984                 ehRet = HandlePconfGetRequest(ehRequest);
985                 break;
986
987             case OC_REST_POST:
988                 ehRet = HandlePconfPostRequest(ehRequest);
989                 break;
990
991             case OC_REST_DELETE:
992                 break;
993
994             default:
995                 ehRet = OC_EH_ERROR;
996                 SendSRMResponse(ehRequest, ehRet, NULL, 0);
997         }
998     }
999
1000     return ehRet;
1001 }
1002
1003 /*
1004  * This internal method is used to create '/oic/sec/pconf' resource.
1005  */
1006 OCStackResult CreatePconfResource()
1007 {
1008     OCStackResult ret;
1009
1010     ret = OCCreateResource(&gPconfHandle,
1011                            OIC_RSRC_TYPE_SEC_PCONF,
1012                            OC_RSRVD_INTERFACE_DEFAULT,
1013                            OIC_RSRC_PCONF_URI,
1014                            PconfEntityHandler,
1015                            NULL,
1016                            OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
1017
1018     if (OC_STACK_OK != ret)
1019     {
1020         OIC_LOG (ERROR, TAG, "Unable to instantiate PCONF resource");
1021         DeInitPconfResource();
1022     }
1023     return ret;
1024 }
1025
1026 /**
1027  * Get the default value.
1028  * @retval  the gDefaultPconf pointer;
1029  */
1030 static OicSecPconf_t* GetPconfDefault()
1031 {
1032     OIC_LOG (DEBUG, TAG, "GetPconfDefault");
1033
1034     return &gDefaultPconf;
1035 }
1036
1037 /**
1038  * This method is used by SRM to retrieve PCONF resource data..
1039  *
1040  * @retval  reference to @ref OicSecPconf_t, binary format of Pconf resource data
1041  */
1042 const OicSecPconf_t* GetPconfResourceData()
1043 {
1044     return gPconf;
1045 }
1046
1047 /**
1048  * Initialize PCONF resource by loading data from persistent storage.
1049  *
1050  * @retval  OC_STACK_OK for Success, otherwise some error value
1051  */
1052 OCStackResult InitPconfResource()
1053 {
1054     OCStackResult ret = OC_STACK_ERROR;
1055
1056     uint8_t *data = NULL;
1057     size_t size = 0;
1058
1059     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PCONF_NAME, &data, &size);
1060     // If database read failed
1061     if (ret != OC_STACK_OK)
1062     {
1063         OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
1064     }
1065     if (data)
1066     {
1067         CBORPayloadToPconf(data, size, &gPconf);
1068     }
1069
1070     if (!data || !gPconf)
1071     {
1072         gPconf = GetPconfDefault();
1073
1074         // device id from doxm
1075         OicUuid_t deviceId = {.id = {0}};
1076         OCStackResult ret = GetDoxmDeviceID( &deviceId);
1077         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1078         memcpy(&gPconf->deviceID, &deviceId, sizeof(OicUuid_t));
1079     }
1080     VERIFY_NON_NULL(TAG, gPconf, ERROR);
1081
1082     // Instantiate 'oic.sec.pconf'
1083     ret = CreatePconfResource();
1084
1085 exit:
1086     if (OC_STACK_OK != ret)
1087     {
1088         DeInitPconfResource();
1089     }
1090     OICFree(data);
1091     return ret;
1092 }
1093
1094 /**
1095  * Perform cleanup for PCONF resources.
1096  *
1097  * @return
1098  * OC_STACK_OK    - no error
1099  * OC_STACK_ERROR - stack process error
1100  *
1101  */
1102 OCStackResult DeInitPconfResource()
1103 {
1104     OCStackResult ret = OCDeleteResource(gPconfHandle);
1105     if(gPconf!= &gDefaultPconf)
1106     {
1107         DeletePconfBinData(gPconf);
1108     }
1109     gPconf = NULL;
1110
1111     if(OC_STACK_OK == ret)
1112     {
1113         return OC_STACK_OK;
1114     }
1115     else
1116     {
1117         return OC_STACK_ERROR;
1118     }
1119 }
1120
1121 /**
1122  * This method might be used to add a paired device id after direct-pairing process complete.
1123  *
1124  * @param pdeviceId ID of the paired device.
1125  *
1126  * @retval  OC_STACK_OK for Success, otherwise some error value
1127  */
1128 OCStackResult AddPairedDevice(OicUuid_t *pdeviceId)
1129 {
1130     if (!gPconf || !pdeviceId)
1131     {
1132         return OC_STACK_INVALID_PARAM;
1133     }
1134
1135
1136     OicUuid_t *prevList = gPconf->pddevs;
1137     gPconf->pddevs = (OicUuid_t *)OICCalloc(gPconf->pddevLen+1, sizeof(OicUuid_t));
1138     if(!gPconf->pddevs)
1139     {
1140         return OC_STACK_NO_MEMORY;
1141     }
1142     for (size_t i=0; i<gPconf->pddevLen; i++)
1143     {
1144         memcpy(&gPconf->pddevs[i], &prevList[i], sizeof(OicUuid_t));
1145     }
1146
1147     // add new paired device id
1148     memcpy(&gPconf->pddevs[gPconf->pddevLen], pdeviceId, sizeof(OicUuid_t));
1149     gPconf->pddevLen++;
1150
1151     // Update storage
1152     if(true != UpdatePersistentStorage(gPconf))
1153     {
1154         OIC_LOG (ERROR, TAG, "Fail to update pconf resource");
1155         return OC_STACK_ERROR;
1156     }
1157
1158     OIC_LOG (ERROR, TAG, "Add paired device success");
1159     return OC_STACK_OK;
1160 }
1161
1162 /**
1163  * This method might be used by PolicyEngine to retrieve PDACL for a Subject.
1164  *
1165  * @param subjectId ID of the subject for which PDACL is required.
1166  * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
1167  *                successive calls for same subjectId.
1168  *
1169  * @retval  reference to @ref OicSecPdAcl_t if PDACL is found, else NULL
1170  */
1171 const OicSecPdAcl_t* GetPdAclData(const OicUuid_t* subjectId, OicSecPdAcl_t **savePtr)
1172 {
1173     OicSecPdAcl_t *pdacl = NULL;
1174
1175     if ( NULL == subjectId)
1176     {
1177         return NULL;
1178     }
1179
1180     /*
1181      * savePtr MUST point to NULL if this is the 'first' call to retrieve PDACL for
1182      * subjectID.
1183      */
1184     if (NULL == *savePtr)
1185     {
1186         pdacl = gPconf->pdacls;
1187
1188         // Find if 'subjectID' is in paired device list.
1189         for(size_t i=0; i<gPconf->pddevLen; i++)
1190         {
1191             if (memcmp(&(gPconf->pddevs[i]), subjectId, sizeof(OicUuid_t)) == 0)
1192             {
1193                 *savePtr = pdacl;
1194                 return pdacl;
1195             }
1196         }
1197     }
1198     else
1199     {
1200         OicSecPdAcl_t *temp = NULL;
1201
1202         /*
1203          * If this is a 'successive' call, search for location pointed by
1204          * savePtr and assign 'begin' to the next PDACL after it in the linked
1205          * list and start searching from there.
1206          */
1207         LL_FOREACH(gPconf->pdacls, temp)
1208         {
1209             if (temp == *savePtr)
1210             {
1211                 pdacl = temp->next;
1212                 *savePtr = pdacl;
1213                 return pdacl;
1214             }
1215         }
1216     }
1217
1218     // Cleanup in case no PDACL is found
1219     *savePtr = NULL;
1220     return NULL;
1221 }
1222
1223 /**
1224  * This method return whether device is paired or not.
1225  *
1226  * @param pdeviceId Target device ID to find in paired list.
1227  * @retval  ture if device is already paired, else false
1228  */
1229 bool IsPairedDevice(const OicUuid_t* pdeviceId)
1230 {
1231     // Find if 'pdeviceId' is in paired device list.
1232     for(size_t i=0; i<gPconf->pddevLen; i++)
1233     {
1234         if (memcmp(&(gPconf->pddevs[i]), pdeviceId, sizeof(OicUuid_t)) == 0)
1235         {
1236             return true;
1237         }
1238     }
1239     return false;
1240 }
1241
1242 OCStackResult SetPconfRownerId(const OicUuid_t* newROwner)
1243 {
1244     OCStackResult ret = OC_STACK_ERROR;
1245     uint8_t *cborPayload = NULL;
1246     size_t size = 0;
1247     OicUuid_t prevId = {.id={0}};
1248
1249     if(NULL == newROwner)
1250     {
1251         ret = OC_STACK_INVALID_PARAM;
1252     }
1253     if(NULL == gPconf)
1254     {
1255         ret = OC_STACK_NO_RESOURCE;
1256     }
1257
1258     if(newROwner && gPconf)
1259     {
1260         memcpy(prevId.id, gPconf->rownerID.id, sizeof(prevId.id));
1261         memcpy(gPconf->rownerID.id, newROwner->id, sizeof(newROwner->id));
1262
1263         ret = PconfToCBORPayload(gPconf, &cborPayload, &size);
1264         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1265
1266         ret = UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, cborPayload, size);
1267         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1268
1269         OICFree(cborPayload);
1270     }
1271
1272     return ret;
1273
1274 exit:
1275     OICFree(cborPayload);
1276     memcpy(gPconf->rownerID.id, prevId.id, sizeof(prevId.id));
1277     return ret;
1278 }
1279
1280 OCStackResult GetPconfRownerId(OicUuid_t *rowneruuid)
1281 {
1282     OCStackResult retVal = OC_STACK_ERROR;
1283     if (gPconf)
1284     {
1285         *rowneruuid = gPconf->rownerID;
1286         retVal = OC_STACK_OK;
1287     }
1288     return retVal;
1289 }