1 /* *****************************************************************
3 * Copyright 2016 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * *****************************************************************/
25 #include "oic_malloc.h"
26 #include "oic_string.h"
29 #include "resourcemanager.h"
30 #include "dpairingresource.h"
31 #include "psinterface.h"
33 #include "srmresourcestrings.h"
34 #include "cainterface.h"
35 #include "doxmresource.h"
36 #include "pconfresource.h"
37 #include "credresource.h"
38 #include "aclresource.h"
39 #include "srmutility.h"
40 #include "ocserverrequest.h"
41 #include "ocpayloadcbor.h"
42 #include "ocpayload.h"
43 #include "payload_logging.h"
53 #define TAG "SRM-DPAIRING"
55 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
56 * The value of payload size is increased until reaching belox max cbor size. */
57 static const uint16_t CBOR_SIZE = 1024;
59 /** Max cbor size payload. */
60 static const uint16_t CBOR_MAX_SIZE = 4400;
62 /** DOXM Map size - Number of mandatory items. */
63 static const uint8_t DPAIR_MAP_SIZE = 3;
65 static OicSecDpairing_t *gDpair = NULL;
66 static OCResourceHandle gDpairHandle = NULL;
67 static OicSecDpairing_t gDefaultDpair =
69 PRM_NOT_ALLOWED, /* OicSecPrm_t spm */
70 {.id = {0}}, /* OicUuid_t pdeviceID */
71 {.id = {0}}, /* OicUuid_t rowner */
74 void DeleteDpairingBinData(OicSecDpairing_t* dpair)
78 //Clean dpairing itself
84 * Get the default value.
85 * @retval the gDefaultDpair pointer;
87 static OicSecDpairing_t* GetDpairingDefault()
89 OIC_LOG (DEBUG, TAG, "GetDpairingDefault");
91 return &gDefaultDpair;
95 * This method is used by SRM to retrieve Dpairing resource data..
97 void SetDpairingResourceOwner(OicUuid_t *rowner)
99 OIC_LOG (DEBUG, TAG, "SetDpairingResourceOwner");
102 memcpy(&gDpair->rownerID, rowner, sizeof(OicUuid_t));
108 * Function to save PairingPSK.
110 * @param[in] endpoint current endpoint.
111 * @param[in] peerDevID peer device indentitiy.
112 * @param[in] isPairingServer indicate if it generates PairingPSK for server or client.
114 * @return OC_STACK_OK on success
116 OCStackResult SavePairingPSK(OCDevAddr *endpoint,
117 OicUuid_t *peerDevID, OicUuid_t *owner, bool isPairingServer)
119 OIC_LOG(DEBUG, TAG, "IN SavePairingPSK");
121 if(NULL == endpoint || NULL == peerDevID || NULL == owner)
123 OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);
124 return OC_STACK_INVALID_PARAM;
127 OCStackResult res = OC_STACK_ERROR;
129 OicUuid_t ptDeviceID = {.id={0}};
130 if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
132 OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
136 uint8_t pairingPSK[OWNER_PSK_LENGTH_128] = {0};
137 OicSecKey_t pairingKey = {pairingPSK, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
139 //Generating PairingPSK using OwnerPSK scheme
140 CAResult_t pskRet = CAGenerateOwnerPSK((const CAEndpoint_t *)endpoint,
141 (uint8_t *)OIC_RSRC_TYPE_SEC_DPAIRING,
142 strlen(OIC_RSRC_TYPE_SEC_DPAIRING),
143 (isPairingServer ? ptDeviceID.id : peerDevID->id), sizeof(OicUuid_t), // server
144 (isPairingServer ? peerDevID->id : ptDeviceID.id), sizeof(OicUuid_t), // client
145 pairingPSK, OWNER_PSK_LENGTH_128);
147 if (CA_STATUS_OK == pskRet)
149 OIC_LOG(INFO, TAG, "pairingPSK dump:\n");
150 OIC_LOG_BUFFER(INFO, TAG, pairingPSK, OWNER_PSK_LENGTH_128);
151 //Generating new credential for direct-pairing client
153 OicSecCred_t *cred = GenerateCredential(peerDevID,
154 SYMMETRIC_PAIR_WISE_KEY, NULL,
156 VERIFY_NON_NULL(TAG, cred, ERROR);
158 res = AddCredential(cred);
159 if(res != OC_STACK_OK)
161 DeleteCredList(cred);
167 OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
170 OIC_LOG(DEBUG, TAG, "OUT SavePairingPSK");
174 #endif // __WITH_DTLS__
176 OCStackResult DpairingToCBORPayload(const OicSecDpairing_t *dpair, uint8_t **payload, size_t *size)
178 if (NULL == dpair || NULL == payload || NULL != *payload || NULL == size)
180 return OC_STACK_INVALID_PARAM;
183 size_t cborLen = *size;
192 OCStackResult ret = OC_STACK_ERROR;
195 CborEncoder dpairMap;
197 int64_t cborEncoderResult = CborNoError;
198 uint8_t mapSize = DPAIR_MAP_SIZE;
200 uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
201 VERIFY_NON_NULL(TAG, outPayload, ERROR);
202 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
204 cborEncoderResult = cbor_encoder_create_map(&encoder, &dpairMap, mapSize);
205 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating DPAIRING Map");
208 cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_SPM_NAME,
209 strlen(OIC_JSON_SPM_NAME));
210 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SPM name tag");
211 cborEncoderResult = cbor_encode_int(&dpairMap, dpair->spm);
212 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SPM value");
214 //PDEVICEID -- Mandatory
215 cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_PDEVICE_ID_NAME,
216 strlen(OIC_JSON_PDEVICE_ID_NAME));
217 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PDeviceID tag");
219 char *deviceId = NULL;
220 ret = ConvertUuidToStr(&dpair->pdeviceID, &deviceId);
221 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
222 cborEncoderResult = cbor_encode_text_string(&dpairMap, deviceId, strlen(deviceId));
223 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode PDeviceID value");
227 //ROWNER -- Mandatory
230 cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_ROWNERID_NAME,
231 strlen(OIC_JSON_ROWNERID_NAME));
232 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROWNER tag");
233 ret = ConvertUuidToStr(&dpair->rownerID, &rowner);
234 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
235 cborEncoderResult = cbor_encode_text_string(&dpairMap, rowner, strlen(rowner));
236 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Rowner ID value");
240 cborEncoderResult = cbor_encoder_close_container(&encoder, &dpairMap);
241 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close dpairMap");
243 if (CborNoError == cborEncoderResult)
245 *size = encoder.ptr - outPayload;
246 *payload = outPayload;
251 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
253 // reallocate and try again!
255 // Since the allocated initial memory failed, double the memory.
256 cborLen += encoder.ptr - encoder.end;
257 cborEncoderResult = CborNoError;
258 ret = DpairingToCBORPayload(dpair, payload, &cborLen);
262 if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
268 ret = OC_STACK_ERROR;
274 OCStackResult CBORPayloadToDpair(const uint8_t *cborPayload, size_t size,
275 OicSecDpairing_t **secDpair)
277 if (NULL == cborPayload || NULL == secDpair || NULL != *secDpair || 0 == size)
279 return OC_STACK_INVALID_PARAM;
282 OCStackResult ret = OC_STACK_ERROR;
285 CborValue dpairCbor = { .parser = NULL };
286 CborParser parser = { .end = NULL };
287 CborError cborFindResult = CborNoError;
289 cbor_parser_init(cborPayload, size, 0, &parser, &dpairCbor);
290 CborValue dpairMap = { .parser = NULL };
291 OicSecDpairing_t *dpair = NULL;
292 cborFindResult = cbor_value_enter_container(&dpairCbor, &dpairMap);
293 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering DPairing Map");
295 dpair = (OicSecDpairing_t *)OICCalloc(1, sizeof(*dpair));
296 VERIFY_NON_NULL(TAG, dpair, ERROR);
298 while (cbor_value_is_valid(&dpairMap) && cbor_value_is_text_string(&dpairMap))
302 CborType type = CborInvalidType;
303 cborFindResult = cbor_value_dup_text_string(&dpairMap, &name, &len, NULL);
304 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding tag name");
305 cborFindResult = cbor_value_advance(&dpairMap);
306 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a value in DPair map");
308 type = cbor_value_get_type(&dpairMap);
309 if (0 == strcmp(OIC_JSON_SPM_NAME, name) && cbor_value_is_integer(&dpairMap))
313 cborFindResult = cbor_value_get_int(&dpairMap, &spm);
314 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SPM Value");
315 dpair->spm = (OicSecPrm_t)spm;
318 if (0 == strcmp(OIC_JSON_PDEVICE_ID_NAME, name))
321 cborFindResult = cbor_value_dup_text_string(&dpairMap, &id, &len, NULL);
322 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PDeviceID value");
323 ret = ConvertStrToUuid(id, &dpair->pdeviceID);
324 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
328 if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name))
331 cborFindResult = cbor_value_dup_text_string(&dpairMap, &id, &len, NULL);
332 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RownerID value");
333 ret = ConvertStrToUuid(id, &dpair->rownerID);
334 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
338 if (CborMapType != type && cbor_value_is_valid(&dpairMap))
340 cborFindResult = cbor_value_advance(&dpairMap);
341 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Dpair Map");
350 if (CborNoError != cborFindResult)
352 OIC_LOG (ERROR, TAG, "CBORPayloadToDoxm failed");
353 DeleteDpairingBinData(dpair);
356 ret = OC_STACK_ERROR;
361 * Function to handle the handshake result in Direct-Pairing.
362 * This function will be invoked after DTLS handshake
363 * @param endPoint [IN] The remote endpoint.
364 * @param errorInfo [IN] Error information from the endpoint.
367 void DPairingDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
369 OIC_LOG_V(INFO, TAG, "IN DPairingDTLSHandshakeCB");
371 if(gDpair && endpoint && info)
373 OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
374 endpoint->addr, endpoint->port, info->result);
376 if(CA_STATUS_OK == info->result)
378 OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Connection success.");
380 else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
382 OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Authentication failed");
387 CARegisterDTLSHandshakeCallback(NULL);
388 #endif // __WITH_DTLS__
390 // delete temporary key
391 RemoveCredential(&gDpair->pdeviceID);
394 OIC_LOG_V(INFO, TAG, "OUT DPairingDTLSHandshakeCB");
397 static OCEntityHandlerResult HandleDpairingPostRequest (const OCEntityHandlerRequest * ehRequest)
399 OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing POST request");
400 OCEntityHandlerResult ehRet = OC_EH_ERROR;
401 OicSecDpairing_t* newDpair = NULL;
402 OCStackResult res = OC_STACK_OK;
404 const OicSecPconf_t *pconf = GetPconfResourceData();
405 if (true == pconf->edp)
407 uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData;
408 size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
411 res = CBORPayloadToDpair(payload, size, &newDpair);
416 OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled");
420 if (OC_STACK_OK == res && newDpair && false == IsPairedDevice(&newDpair->pdeviceID))
422 // Check if valid Post request
423 bool prmMached = false;
424 for (size_t i=0; i<pconf->prmLen; i++)
426 if (newDpair->spm == pconf->prm[i])
432 OIC_LOG_V(DEBUG, TAG, "Parsed spm is %s", prmMached ? "valid" :
433 "invalid, send error response");
435 // Update local Dpairing with new Dpairing & prepare dtls session
436 if (prmMached && '\0' != (char)newDpair->pdeviceID.id[0])
440 gDpair = GetDpairingDefault();
442 gDpair->spm = newDpair->spm;
443 memcpy(&gDpair->pdeviceID, &newDpair->pdeviceID, sizeof(OicUuid_t));
444 memcpy(&gDpair->rownerID, &pconf->rownerID, sizeof(OicUuid_t));
449 OicUuid_t subjectId = {.id={0}};
450 res = AddTmpPskWithPIN(&gDpair->pdeviceID,
451 SYMMETRIC_PAIR_WISE_KEY,
452 (char*)pconf->pin.val, DP_PIN_LENGTH,
453 &gDpair->rownerID, &subjectId);
454 if(res != OC_STACK_OK ||
455 memcmp(&gDpair->pdeviceID, &subjectId, sizeof(OicUuid_t)))
457 OIC_LOG_V(ERROR, TAG, "Failed to save the temporal PSK : %d", res);
461 // Prepare to establish a secure channel with Pin-based PSK cipher suite
462 if (CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false) ||
463 CA_STATUS_OK != CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))
465 OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
469 if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DPairingDTLSHandshakeCB))
471 OIC_LOG(WARNING, TAG, "DirectPairingHandler : Failed to register"
472 " DTLS handshake callback.");
475 #endif // __WITH_DTLS__
477 // should be lock /oic/sec/dpairing resource if Direct-Pairing starts normally ?
478 OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource created");
480 ehRet = OC_EH_RESOURCE_CREATED;
484 OIC_LOG(ERROR, TAG, "Error in request check");
491 #endif // __WITH_DTLS__
493 // Send payload to request originator
494 if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
497 OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPostRequest");
500 if (OC_EH_ERROR == ehRet && gDpair)
502 RemoveCredential(&gDpair->pdeviceID);
506 DeleteDpairingBinData(newDpair);
507 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
511 static OCEntityHandlerResult HandleDpairingPutRequest (const OCEntityHandlerRequest * ehRequest)
513 OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing PUT request (Comfirmation)");
515 OCEntityHandlerResult ehRet = OC_EH_ERROR;
516 OicSecDpairing_t* newDpair = NULL;
517 OCStackResult res = OC_STACK_OK;
519 const OicSecPconf_t *pconf = GetPconfResourceData();
520 if (true == pconf->edp)
522 uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData;
523 size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
526 res = CBORPayloadToDpair(payload, size, &newDpair);
532 OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled");
537 if ((OC_STACK_OK == res) && gDpair && newDpair)
539 OIC_LOG(DEBUG, TAG, "Received direct-pairing finalization request");
541 // Check if valid Put request
542 VERIFY_SUCCESS(TAG, PRM_NOT_ALLOWED == newDpair->spm, ERROR);
544 const OicSecPconf_t *pconf = GetPconfResourceData();
545 VERIFY_NON_NULL(TAG, pconf, ERROR);
548 OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;
549 VERIFY_SUCCESS(TAG, (request->devAddr.flags | OC_FLAG_SECURE), ERROR);
551 //Generate new credential
552 OIC_LOG_V(INFO, TAG, "SavePairingPSK for %s(%d)", request->devAddr.addr,
553 request->devAddr.port);
554 OCStackResult res = SavePairingPSK(&request->devAddr, &newDpair->pdeviceID,
555 (OicUuid_t *)&pconf->rownerID, true);
556 VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
557 #endif //__WITH_DTLS__
560 OicSecPdAcl_t *pdAcl;
561 LL_FOREACH(pconf->pdacls, pdAcl)
563 OicSecAcl_t* acl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
564 VERIFY_NON_NULL(TAG, acl, ERROR);
566 OicSecAce_t* ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
567 VERIFY_NON_NULL(TAG, ace, ERROR);
569 LL_APPEND(acl->aces, ace);
571 memcpy(&ace->subjectuuid, &gDpair->pdeviceID, sizeof(OicUuid_t));
573 for(size_t i = 0; i < pdAcl->resourcesLen; i++)
575 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
576 VERIFY_NON_NULL(TAG, rsrc, ERROR);
577 LL_APPEND(ace->resources, rsrc);
580 rsrc->href = OICStrdup(pdAcl->resources[i]);
582 // TODO: Append 'if' and 'rt' as workaround
584 rsrc->interfaceLen = 1;
585 rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char));
586 VERIFY_NON_NULL(TAG, (rsrc->interfaces), ERROR);
587 rsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
588 VERIFY_NON_NULL(TAG, (rsrc->interfaces[0]), ERROR);
592 rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char));
593 VERIFY_NON_NULL(TAG, (rsrc->types), ERROR);
594 rsrc->types[0] = OICStrdup("oic.core");
595 VERIFY_NON_NULL(TAG, (rsrc->types[0]), ERROR);
598 ace->permission = pdAcl->permission;
601 if(pdAcl->periods || pdAcl->recurrences)
603 OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
604 VERIFY_NON_NULL(TAG, validity, ERROR);
606 if(pdAcl->periods && pdAcl->periods[0])
608 size_t periodLen = strlen(pdAcl->periods[0]) + 1;
609 validity->period = (char*)OICMalloc(periodLen * sizeof(char));
610 VERIFY_NON_NULL(TAG, (validity->period), ERROR);
611 OICStrcpy(validity->period, periodLen, pdAcl->periods[0]);
614 if(pdAcl->recurrences && 0 < pdAcl->prdRecrLen)
616 validity->recurrenceLen = pdAcl->prdRecrLen;
617 validity->recurrences = (char**)OICMalloc(sizeof(char*) * pdAcl->prdRecrLen);
618 VERIFY_NON_NULL(TAG, (validity->recurrences), ERROR);
620 for(size_t i = 0; i < pdAcl->prdRecrLen; i++)
622 size_t recurrenceLen = strlen(pdAcl->recurrences[i]) + 1;
623 validity->recurrences[i] = (char*)OICMalloc(recurrenceLen * sizeof(char));
624 VERIFY_NON_NULL(TAG, (validity->recurrences[i]), ERROR);
626 OICStrcpy(validity->recurrences[i], recurrenceLen, pdAcl->recurrences[i]);
630 LL_APPEND(ace->validities, validity);
634 uint8_t *payload = NULL;
635 if (OC_STACK_OK == AclToCBORPayload(acl, &payload, &size))
637 InstallNewACL(payload, size);
643 //update pconf device list
644 AddPairedDevice(&newDpair->pdeviceID);
646 //Initialize dpairing resource
649 OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource updated,"
650 "direct-pairing finalization success");
656 //Send payload to request originator
657 if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
660 OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPutRequest");
663 DeleteDpairingBinData(newDpair);
664 OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
668 * This internal method is the entity handler for Dpairing resources and
669 * will handle REST request (GET/POST) for them.
671 OCEntityHandlerResult DpairingEntityHandler (OCEntityHandlerFlag flag,
672 OCEntityHandlerRequest * ehRequest,
673 void* callbackParameter)
675 OIC_LOG(DEBUG, TAG, "Received request DpairingEntityHandler");
676 (void)callbackParameter;
677 OCEntityHandlerResult ehRet = OC_EH_ERROR;
684 if (flag & OC_REQUEST_FLAG)
686 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
687 switch (ehRequest->method)
693 ehRet = HandleDpairingPostRequest(ehRequest);
697 ehRet = HandleDpairingPutRequest(ehRequest);
705 SendSRMResponse(ehRequest, ehRet, NULL, 0);
713 * This internal method is used to create '/oic/sec/dpairing' resource.
715 OCStackResult CreateDpairingResource()
719 ret = OCCreateResource(&gDpairHandle,
720 OIC_RSRC_TYPE_SEC_DPAIRING,
721 OC_RSRVD_INTERFACE_DEFAULT,
722 OIC_RSRC_DPAIRING_URI,
723 DpairingEntityHandler,
725 OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
727 if (OC_STACK_OK != ret)
729 OIC_LOG (ERROR, TAG, "Unable to instantiate Dpairing resource");
730 DeInitDpairingResource();
736 * Initialize Dpairing resource by loading data from persistent storage.
738 * @retval OC_STACK_OK for Success, otherwise some error value
740 OCStackResult InitDpairingResource()
742 OCStackResult ret = OC_STACK_ERROR;
744 // Instantiate 'oic.sec.dpairing'
745 ret = CreateDpairingResource();
746 if (OC_STACK_OK != ret)
748 DeInitDpairingResource();
754 * Perform cleanup for Dpairing resources.
757 * OC_STACK_OK - no error
758 * OC_STACK_ERROR - stack process error
761 OCStackResult DeInitDpairingResource()
763 OCStackResult ret = OCDeleteResource(gDpairHandle);
766 if(OC_STACK_OK == ret)
772 return OC_STACK_ERROR;
776 OCStackResult SetDpairingRownerId(const OicUuid_t* newROwner)
778 OCStackResult ret = OC_STACK_ERROR;
779 uint8_t *cborPayload = NULL;
781 OicUuid_t prevId = {.id={0}};
783 if(NULL == newROwner)
785 ret = OC_STACK_INVALID_PARAM;
789 ret = OC_STACK_NO_RESOURCE;
792 if(newROwner && gDpair)
794 memcpy(prevId.id, gDpair->rownerID.id, sizeof(prevId.id));
795 memcpy(gDpair->rownerID.id, newROwner->id, sizeof(newROwner->id));
797 ret = DpairingToCBORPayload(gDpair, &cborPayload, &size);
798 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
800 ret = UpdateSecureResourceInPS(OIC_JSON_DPAIRING_NAME, cborPayload, size);
801 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
803 OICFree(cborPayload);
809 OICFree(cborPayload);
810 memcpy(gDpair->rownerID.id, prevId.id, sizeof(prevId.id));
814 OCStackResult GetDpairingRownerId(OicUuid_t *rowneruuid)
816 OCStackResult retVal = OC_STACK_ERROR;
819 *rowneruuid = gDpair->rownerID;
820 retVal = OC_STACK_OK;