1 /* *****************************************************************
3 * Copyright 2015 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 * *****************************************************************/
21 // Defining _POSIX_C_SOURCE macro with 199309L (or greater) as value
22 // causes header files to expose definitions
23 // corresponding to the POSIX.1b, Real-time extensions
24 // (IEEE Std 1003.1b-1993) specification
26 // For this specific file, see use of clock_gettime,
27 // Refer to http://pubs.opengroup.org/stage7tc1/functions/clock_gettime.html
28 // and to http://man7.org/linux/man-pages/man2/clock_gettime.2.html
29 #ifndef _POSIX_C_SOURCE
30 #define _POSIX_C_SOURCE 200809L
33 #include "iotivity_config.h"
40 #ifdef HAVE_SYS_TIME_H
49 #include "oic_malloc.h"
50 #include "oic_string.h"
52 #include "cainterface.h"
54 #if defined (__TIZENRT__)
55 #include <apps/netutils/cJSON.h>
60 #include "srmresourcestrings.h"
61 #include "doxmresource.h"
62 #include "pstatresource.h"
63 #include "credresource.h"
64 #include "aclresource.h"
65 #include "ownershiptransfermanager.h"
66 #include "securevirtualresourcetypes.h"
67 #include "oxmjustworks.h"
68 #include "oxmrandompin.h"
69 #include "oxmrawpublickey.h"
70 #include "oxmmanufacturercert.h"
71 #include "secureresourceprovider.h"
74 #include "oxmpreconfpin.h"
75 #endif //MULTIPLE_OWNER
76 #include "otmcontextlist.h"
78 #include "pmutility.h"
79 #include "srmutility.h"
80 #include "provisioningdatabasemanager.h"
81 #include "ocpayload.h"
82 #include "payload_logging.h"
83 #include "pkix_interface.h"
84 #include "oxmverifycommon.h"
85 #include "psinterface.h"
91 #define NOT_ALLOWED_OXM 0
94 * List of allowed oxm list.
95 * All oxm methods are allowed as default.
98 static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
99 ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
100 ALLOWED_OXM, NOT_ALLOWED_OXM};
102 static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
103 ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
107 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
109 OCStackResult res = OC_STACK_INVALID_PARAM;
111 OIC_LOG(INFO, TAG, "IN OTMSetOTCallback");
113 VERIFY_NON_NULL(TAG, callbacks, ERROR);
115 #ifdef MULTIPLE_OWNER
116 VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm
117 || OIC_CON_MFG_CERT == oxm || OIC_RAW_PUB_KEY == oxm), ERROR);
119 VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm || OIC_RAW_PUB_KEY == oxm), ERROR);
120 #endif // MULTIPLE_OWNER
125 callbacks->loadSecretCB = LoadSecretJustWorksCallback;
126 callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
127 callbacks->createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
128 callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
130 case OIC_RANDOM_DEVICE_PIN:
131 callbacks->loadSecretCB = InputPinCodeCallback;
132 callbacks->createSecureSessionCB = CreateSecureSessionRandomPinCallback;
133 callbacks->createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
134 callbacks->createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
136 case OIC_MANUFACTURER_CERTIFICATE:
137 callbacks->loadSecretCB = PrepareMCertificateCallback;
138 callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
139 callbacks->createSelectOxmPayloadCB = CreateMCertificateBasedSelectOxmPayload;
140 callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
142 case OIC_DECENTRALIZED_PUBLIC_KEY:
143 OIC_LOG(ERROR, TAG, "OIC_DECENTRALIZED_PUBLIC_KEY not supported yet.");
144 return OC_STACK_INVALID_METHOD;
145 #ifdef MULTIPLE_OWNER
146 case OIC_PRECONFIG_PIN:
147 callbacks->loadSecretCB = LoadPreconfigPinCodeCallback;
148 callbacks->createSecureSessionCB = CreateSecureSessionPreconfigPinCallback;
149 callbacks->createSelectOxmPayloadCB = CreatePreconfigPinBasedSelectOxmPayload;
150 callbacks->createOwnerTransferPayloadCB = CreatePreconfigPinBasedOwnerTransferPayload;
152 #endif //MULTIPLE_OWNER
153 case OIC_MV_JUST_WORKS:
154 callbacks->loadSecretCB = LoadSecretJustWorksCallback;
155 callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
156 callbacks->createSelectOxmPayloadCB = CreateMVJustWorksSelectOxmPayload;
157 callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
159 case OIC_CON_MFG_CERT:
160 callbacks->loadSecretCB = PrepareMCertificateCallback;
161 callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
162 callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload;
163 callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
165 case OIC_RAW_PUB_KEY:
166 callbacks->loadSecretCB = GetMasterRPKCallback;
167 callbacks->createSecureSessionCB = CreateSecureSessionRPKCallback;
168 callbacks->createSelectOxmPayloadCB = CreateRPKBasedSelectOxmPayload;
169 callbacks->createOwnerTransferPayloadCB = CreateRPKBasedOwnerTransferPayload;
172 OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
173 return OC_STACK_INVALID_PARAM;
179 OIC_LOG(INFO, TAG, "OUT OTMSetOTCallback");
184 * Internal API to convert OxM value to index of oxm allow table.
186 static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm)
191 return OXM_IDX_JUST_WORKS;
192 case OIC_RANDOM_DEVICE_PIN:
193 return OXM_IDX_RANDOM_DEVICE_PIN;
194 case OIC_MANUFACTURER_CERTIFICATE:
195 return OXM_IDX_MANUFACTURER_CERTIFICATE;
196 case OIC_DECENTRALIZED_PUBLIC_KEY:
197 return OXM_IDX_DECENTRALIZED_PUBLIC_KEY;
198 case OIC_MV_JUST_WORKS:
199 return OXM_IDX_MV_JUST_WORKS;
200 case OIC_RAW_PUB_KEY:
201 return OXM_IDX_RAW_PUBLIC_KEY;
202 case OIC_CON_MFG_CERT:
203 return OXM_IDX_CON_MFG_CERT;
204 #ifdef MULTIPLE_OWNER
205 case OIC_PRECONFIG_PIN:
206 return OXM_IDX_PRECONFIG_PIN;
209 return OXM_IDX_UNKNOWN;
214 * Function to select appropriate provisioning method.
216 * @param[in] supportedMethods Array of supported methods
217 * @param[in] numberOfMethods number of supported methods
218 * @param[out] selectedMethod Selected methods
219 * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)
220 * @return OC_STACK_OK on success
222 OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
223 size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType)
225 bool isOxmSelected = false;
226 OxmAllowTableIdx_t selectedOxmIdx = OXM_IDX_UNKNOWN;
228 OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
230 if (numberOfMethods == 0 || !supportedMethods)
232 OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
233 return OC_STACK_ERROR;
240 for (size_t i = 0; i < numberOfMethods; i++)
242 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
243 if (OXM_IDX_COUNT <= selectedOxmIdx)
245 OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
248 #ifdef MULTIPLE_OWNER
249 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
250 OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
253 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
254 #endif //MULTIPLE_OWNER
256 *selectedMethod = supportedMethods[i];
257 isOxmSelected = true;
262 #ifdef MULTIPLE_OWNER
265 for (size_t i = 0; i < numberOfMethods; i++)
267 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
268 if (OXM_IDX_COUNT <= selectedOxmIdx)
270 OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
274 //in case of MOT, only Random PIN & Preconfigured PIN based OxM is allowed
275 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
276 (OXM_IDX_RANDOM_DEVICE_PIN == selectedOxmIdx ||
277 OXM_IDX_PRECONFIG_PIN == selectedOxmIdx))
279 *selectedMethod = supportedMethods[i];
280 isOxmSelected = true;
288 OIC_LOG_V(ERROR, TAG, "Unknown owner type or Not supported owner type : %d", ownerType);
289 return OC_STACK_INVALID_PARAM;
295 OIC_LOG(ERROR, TAG, "Can not find the allowed OxM.");
296 return OC_STACK_NOT_ALLOWED_OXM;
299 OIC_LOG(DEBUG, TAG, "OUT SelectProvisioningMethod");
305 * Function to select operation mode.This function will return most secure common operation mode.
307 * @param[in] selectedDeviceInfo selected device information to performing provisioning.
308 * @param[out] selectedMode selected operation mode
309 * @return OC_STACK_OK on success
311 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
312 OicSecDpom_t *selectedMode)
314 OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
315 *selectedMode = selectedDeviceInfo->pstat->sm[0];
316 OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
320 * Function to start ownership transfer.
321 * This function will send the first request for provisioning,
322 * The next request message is sent from the response handler for this request.
324 * @param[in] ctx context value passed to callback from calling function.
325 * @param[in] selectedDevice selected device information to performing provisioning.
326 * @return OC_STACK_OK on success
328 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
331 * Internal function to setup & cleanup PDM to performing provisioning.
333 * @param[in] selectedDevice selected device information to performing provisioning.
334 * @return OC_STACK_OK on success
336 static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice);
339 * Function to update owner transfer mode
341 * @param[in] otmCtx Context value of ownership transfer.
342 * @return OC_STACK_OK on success
344 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx);
347 * Function to send request to resource to get its pstat resource information.
349 * @param[in] otmCtx Context value of ownership transfer.
350 * @return OC_STACK_OK on success
352 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
356 * Function to send uuid of owner device to new device.
357 * This function would update 'owner of doxm' as UUID for provisioning tool.
359 * @param[in] otmCtx Context value of ownership transfer.
360 * @return OC_STACK_OK on success
362 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx);
365 * Function to update the operation mode. As per the spec. Operation mode in client driven
366 * single service provisioning it will be updated to 0x3
368 * @param[in] otmCtx Context value of ownership transfer.
369 * @return OC_STACK_OK on success
371 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx);
374 * Function to update the owner credential to new device
376 * @param[in] otmCtx Context value of ownership transfer.
377 * @param[in] selectedOperationMode selected operation mode
378 * @return OC_STACK_OK on success
380 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx);
383 * Function to update the owner ACL to new device.
385 * @param[in] otmCtx Context value of ownership transfer.
386 * @return OC_STACK_OK on success
388 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx);
391 * Function to send ownerShip info.
392 * This function would update 'owned of doxm' as true.
394 * @param[in] otmCtx Context value of ownership transfer.
395 * @return OC_STACK_OK on success
397 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx);
400 * Function to update pstat as Ready for provisioning.
401 * This function would update 'cm' from bx0000,0010 to bx0000,0000.
403 * @param[in] ctx context value passed to callback from calling function.
404 * @param[in] selectedDevice selected device information to performing provisioning.
405 * @return OC_STACK_OK on success
407 static OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx);
410 * Function to update pstat as Ready for Normal Operation.
411 * This function would update 'isop' from false to true.
413 * @param[in] ctx context value passed to callback from calling function.
414 * @param[in] selectedDevice selected device information to performing provisioning.
415 * @return OC_STACK_OK on success
417 static OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx);
419 static bool IsComplete(OTMContext_t* otmCtx)
421 for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
423 if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
433 * Function to save the result of provisioning.
435 * @param[in,out] otmCtx Context value of ownership transfer.
436 * @param[in] res result of provisioning
438 void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
440 OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
442 if(NULL == otmCtx || NULL == otmCtx->selectedDeviceInfo
443 || NULL == otmCtx->selectedDeviceInfo->doxm)
445 OIC_LOG(WARNING, TAG, "OTMContext is NULL");
449 //If OTM Context was removed from previous response handler, just exit the current OTM process.
450 if(NULL == GetOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
451 otmCtx->selectedDeviceInfo->securePort))
453 OIC_LOG(WARNING, TAG, "Current OTM Process has already ended.");
456 //Revert psk_info callback and new deivce uuid in case of random PIN OxM
457 if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
459 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
461 OIC_LOG(WARNING, TAG, "Failed to revert is DTLS credential handler.");
463 OicUuid_t emptyUuid = { .id={0}};
464 SetUuidForPinBasedOxm(&emptyUuid);
466 else if(OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel ||
467 OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)
469 //Revert back certificate related callbacks.
470 if(CA_STATUS_OK != CAregisterPkixInfoHandler(GetPkixInfo))
472 OIC_LOG(WARNING, TAG, "Failed to revert PkixInfoHandler.");
474 if(CA_STATUS_OK != CAregisterGetCredentialTypesHandler(InitCipherSuiteList))
476 OIC_LOG(WARNING, TAG, "Failed to revert CredentialTypesHandler.");
480 for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
482 if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
483 otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
485 otmCtx->ctxResultArray[i].res = res;
486 if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res)
488 otmCtx->ctxHasError = true;
489 if (OC_STACK_OK != PDMDeleteDevice(&otmCtx->ctxResultArray[i].deviceId))
491 OIC_LOG(WARNING, TAG, "Internal error in PDMDeleteDevice");
493 CAEndpoint_t endpoint;
494 memcpy(&endpoint, &(otmCtx->selectedDeviceInfo->endpoint), sizeof(CAEndpoint_t));
495 endpoint.port = otmCtx->selectedDeviceInfo->securePort;
496 if (CA_STATUS_OK != CAcloseSslConnection(&endpoint))
498 OIC_LOG(WARNING, TAG, "Failed to close Secure session");
504 //In case of duplicated OTM process, OTMContext and OCDoHandle should not be removed.
505 if(OC_STACK_DUPLICATE_REQUEST != res)
507 //Remove the current OTM Context from OTM queue
508 RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
509 otmCtx->selectedDeviceInfo->securePort);
511 //If there is a request being performed, cancel it to prevent retransmission.
512 if(otmCtx->ocDoHandle)
514 OIC_LOG_V(DEBUG, TAG, "OCCancel - %s : %d",
515 otmCtx->selectedDeviceInfo->endpoint.addr,
516 otmCtx->selectedDeviceInfo->securePort);
517 if(OC_STACK_OK != OCCancel(otmCtx->ocDoHandle, OC_HIGH_QOS, NULL, 0))
519 OIC_LOG(WARNING, TAG, "Failed to remove registered callback");
523 otmCtx->ocDoHandle = NULL;
528 //If all OTM process is complete, invoke the user callback.
529 if(IsComplete(otmCtx))
531 if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res)
533 // Reset doxm and pstat properties to pre-Ownership Transfer state
534 OIC_LOG(DEBUG, TAG, "Resetting doxm and pstat properties");
535 if(otmCtx->selectedDeviceInfo->doxm)
537 OicUuid_t emptyUuid = {.id = {0}};
538 memcpy(&(otmCtx->selectedDeviceInfo->doxm->owner), &emptyUuid, sizeof(OicUuid_t));
539 otmCtx->selectedDeviceInfo->doxm->owned = false;
541 if(otmCtx->selectedDeviceInfo->pstat)
543 otmCtx->selectedDeviceInfo->pstat->isOp = false;
544 otmCtx->selectedDeviceInfo->pstat->cm |= TAKE_OWNER;
548 otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
549 otmCtx->ctxResultArray, otmCtx->ctxHasError);
550 OICFree(otmCtx->ctxResultArray);
555 if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
556 otmCtx->selectedDeviceInfo->next))
558 OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
562 OIC_LOG(DEBUG, TAG, "OUT SetResult");
566 * Function to handle the handshake result in OTM.
567 * This function will be invoked after DTLS handshake
568 * @param endPoint [IN] The remote endpoint.
569 * @param errorInfo [IN] Error information from the endpoint.
572 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
574 OIC_LOG(DEBUG, TAG, "IN DTLSHandshakeCB");
575 if(NULL != endpoint && NULL != info)
577 OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
578 endpoint->addr, endpoint->port, info->result);
580 OTMContext_t* otmCtx = GetOTMContext(endpoint->addr, endpoint->port);
583 OicSecDoxm_t* newDevDoxm = otmCtx->selectedDeviceInfo->doxm;
584 if(NULL != newDevDoxm)
586 OicUuid_t emptyUuid = {.id={0}};
588 //Make sure the address matches.
589 if(strncmp(otmCtx->selectedDeviceInfo->endpoint.addr,
591 sizeof(endpoint->addr)) == 0 &&
592 otmCtx->selectedDeviceInfo->securePort == endpoint->port)
594 OCStackResult res = OC_STACK_ERROR;
596 //If temporal secure sesstion established successfully
597 if(CA_STATUS_OK == info->result &&
598 false == newDevDoxm->owned &&
599 memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0)
601 //In case of Mutual Verified Just-Works, display mutualVerifNum
602 if (OIC_MV_JUST_WORKS == newDevDoxm->oxmSel)
604 uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
605 uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
606 OicUuid_t deviceID = {.id = {0}};
608 //Generate mutualVerifNum
609 char label[LABEL_LEN] = {0};
610 snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS);
611 res = GetDoxmDeviceID(&deviceID);
612 if (OC_STACK_OK != res)
614 OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
615 SetResult(otmCtx, res);
619 CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
622 deviceID.id, sizeof(deviceID.id),
623 newDevDoxm->deviceID.id, sizeof(newDevDoxm->deviceID.id),
624 preMutualVerifNum, OWNER_PSK_LENGTH_128);
625 if (CA_STATUS_OK != pskRet)
627 OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
628 SetResult(otmCtx, OC_STACK_ERROR);
632 memcpy(mutualVerifNum, preMutualVerifNum + OWNER_PSK_LENGTH_128 - sizeof(mutualVerifNum),
633 sizeof(mutualVerifNum));
634 res = VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM);
635 if (OC_STACK_OK != res)
637 OIC_LOG(ERROR, TAG, "Error while displaying mutualVerifNum");
638 SetResult(otmCtx, res);
642 //In case of confirmed manufacturer cert, display message
643 else if (OIC_MANUFACTURER_CERTIFICATE == newDevDoxm->oxmSel || OIC_CON_MFG_CERT == newDevDoxm->oxmSel)
645 res = VerifyOwnershipTransfer(NULL, DISPLAY_NUM);
646 if (OC_STACK_OK != res)
648 OIC_LOG(ERROR, TAG, "Error while displaying message");
649 SetResult(otmCtx, res);
654 //Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
655 res = PostOwnerUuid(otmCtx);
656 if(OC_STACK_OK != res)
658 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
659 SetResult(otmCtx, res);
662 //In case of authentication failure
663 else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
665 //in case of error from owner credential
666 if(memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0 &&
667 true == newDevDoxm->owned)
669 OIC_LOG(ERROR, TAG, "The owner credential may incorrect.");
671 if(OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID)))
673 OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
675 SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
677 //in case of error from wrong PIN, re-start the ownership transfer
678 else if(OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel)
680 OIC_LOG(ERROR, TAG, "The PIN number may incorrect.");
682 memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
683 newDevDoxm->owned = false;
684 otmCtx->attemptCnt++;
686 RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
687 otmCtx->selectedDeviceInfo->securePort);
689 // In order to re-start ownership transfer, device information should be deleted from PDM.
690 res = PDMDeleteDevice(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
691 if (OC_STACK_OK != res)
693 SetResult(otmCtx, res);
694 OIC_LOG(ERROR, TAG, "Failed to PDMDeleteDevice");
698 if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
700 res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
701 if(OC_STACK_OK != res)
703 SetResult(otmCtx, res);
704 OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
709 OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
710 SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
716 OIC_LOG(ERROR, TAG, "Failed to establish secure session.");
717 SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
725 OIC_LOG(ERROR, TAG, "Can not find the OTM Context.");
728 OIC_LOG(DEBUG, TAG, "OUT DTLSHandshakeCB");
732 * Function to save the Owner/SubOwner PSK.
734 * @param[in] selectedDeviceInfo selected device information to performing provisioning.
735 * @return OC_STACK_OK on success
737 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
739 OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
741 OCStackResult res = OC_STACK_ERROR;
743 CAEndpoint_t endpoint;
744 memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
745 OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
746 endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
747 endpoint.port = selectedDeviceInfo->securePort;
748 endpoint.adapter = selectedDeviceInfo->endpoint.adapter;
750 OicUuid_t ownerDeviceID = {.id={0}};
751 if (OC_STACK_OK != GetDoxmDeviceID(&ownerDeviceID))
753 OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
757 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
758 OicSecKey_t ownerKey = {.data=ownerPSK, .len=OWNER_PSK_LENGTH_128, .encoding=OIC_ENCODING_RAW};
760 //Generating OwnerPSK
761 CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
762 (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
763 strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
764 ownerDeviceID.id, sizeof(ownerDeviceID.id),
765 selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
766 ownerPSK, OWNER_PSK_LENGTH_128);
768 if (CA_STATUS_OK == pskRet)
770 OIC_LOG(DEBUG, TAG,"Owner PSK dump:\n");
771 OIC_LOG_BUFFER(DEBUG, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
772 //Generating new credential for provisioning tool
773 OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
774 SYMMETRIC_PAIR_WISE_KEY, NULL,
775 &ownerKey, &ownerDeviceID, NULL);
776 OICClearMemory(ownerPSK, sizeof(ownerPSK));
777 VERIFY_NON_NULL(TAG, cred, ERROR);
779 uint32_t outSize = 0;
780 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
781 char* b64Buf = (char *)OICCalloc(1, b64BufSize);
782 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
783 b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize);
785 OICFree( cred->privateData.data );
786 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
787 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
789 strncpy((char*)(cred->privateData.data), b64Buf, outSize);
790 cred->privateData.data[outSize] = '\0';
791 cred->privateData.encoding = OIC_ENCODING_BASE64;
792 cred->privateData.len = outSize;
795 //Finding previous ownerPSK.
796 const OicSecCred_t* credList = GetCredList();
797 const OicSecCred_t* prevCred = NULL;
799 LL_FOREACH(credList, prevCred)
801 //OwnerPSK's type is SYMMETRIC_PAIR_WISE_KEY
802 if (SYMMETRIC_PAIR_WISE_KEY == prevCred->credType &&
803 0 == memcmp(prevCred->subject.id, cred->subject.id, sizeof(cred->subject.id)))
805 credId = prevCred->credId;
810 //If duplicate owner PSK is exists, remove it.
813 OIC_LOG(WARNING, TAG, "Duplicate OwnerPSK was detected.");
814 OIC_LOG(WARNING, TAG, "[Subject] : ");
815 OIC_LOG_BUFFER(WARNING, TAG, prevCred->subject.id, sizeof(prevCred->subject.id));
816 OIC_LOG_V(WARNING, TAG, "[Encoding Type] : %d", prevCred->privateData.encoding);
817 OIC_LOG(DEBUG, TAG, "[Private Data] : ");
818 OIC_LOG_BUFFER(DEBUG, TAG, prevCred->privateData.data, prevCred->privateData.len);
819 OIC_LOG(WARNING, TAG, "Previous OwnerPSK will be removed.");
821 res = RemoveCredentialByCredId(credId);
822 if(OC_STACK_RESOURCE_DELETED != res)
824 OIC_LOG(ERROR, TAG, "Failed to remove the previous OwnerPSK");
825 DeleteCredList(cred);
830 res = AddCredential(cred);
831 if(res != OC_STACK_OK)
833 DeleteCredList(cred);
839 OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
842 OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
848 * Callback handler for OwnerShipTransferModeHandler API.
850 * @param[in] ctx ctx value passed to callback from calling function.
851 * @param[in] UNUSED handle to an invocation
852 * @param[in] clientResponse Response from queries to remote servers.
853 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
854 * and OC_STACK_KEEP_TRANSACTION to keep it.
856 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
857 OCClientResponse *clientResponse)
859 OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
861 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
862 VERIFY_NON_NULL(TAG, ctx, WARNING);
864 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
865 otmCtx->ocDoHandle = NULL;
867 if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
869 OIC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
870 //Send request : GET /oic/sec/pstat
871 OCStackResult res = GetProvisioningStatusResource(otmCtx);
872 if(OC_STACK_OK != res)
874 OIC_LOG(WARNING, TAG, "Failed to get pstat information");
875 SetResult(otmCtx, res);
880 OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
881 clientResponse->result);
882 SetResult(otmCtx, clientResponse->result);
885 OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
888 return OC_STACK_DELETE_TRANSACTION;
892 * Callback handler for ProvisioningStatusResouceHandler API.
894 * @param[in] ctx ctx value passed to callback from calling function.
895 * @param[in] UNUSED handle to an invocation
896 * @param[in] clientResponse Response from queries to remote servers.
897 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
898 * and OC_STACK_KEEP_TRANSACTION to keep it.
900 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
901 OCClientResponse *clientResponse)
903 OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
905 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
906 VERIFY_NON_NULL(TAG, ctx, WARNING);
908 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
909 otmCtx->ocDoHandle = NULL;
911 if (OC_STACK_OK == clientResponse->result)
913 if (NULL == clientResponse->payload)
915 OIC_LOG(INFO, TAG, "Skiping Null payload");
916 SetResult(otmCtx, OC_STACK_ERROR);
917 return OC_STACK_DELETE_TRANSACTION;
920 if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
922 OIC_LOG(INFO, TAG, "Unknown payload type");
923 SetResult(otmCtx, OC_STACK_ERROR);
924 return OC_STACK_DELETE_TRANSACTION;
926 OicSecPstat_t* pstat = NULL;
927 OCStackResult result = CBORPayloadToPstat(
928 ((OCSecurityPayload*)clientResponse->payload)->securityData,
929 ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
931 if(NULL == pstat || result != OC_STACK_OK)
933 OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
934 SetResult(otmCtx, OC_STACK_ERROR);
935 return OC_STACK_DELETE_TRANSACTION;
937 if(false == (TAKE_OWNER & pstat->cm))
939 OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
940 SetResult(otmCtx, OC_STACK_ERROR);
941 return OC_STACK_DELETE_TRANSACTION;
943 otmCtx->selectedDeviceInfo->pstat = pstat;
945 //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
946 SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
948 //Send request : POST /oic/sec/pstat [{"om":"bx11", .. }]
949 OCStackResult res = PostUpdateOperationMode(otmCtx);
950 if (OC_STACK_OK != res)
952 OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
953 SetResult(otmCtx, res);
958 OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
959 clientResponse->result);
960 SetResult(otmCtx, clientResponse->result);
963 OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
965 return OC_STACK_DELETE_TRANSACTION;
968 static void deleteCallback(void *ctx)
971 OIC_LOG_V(DEBUG, TAG, "%s: otm context deleted", __func__);
976 * Response handler for update owner uuid request.
978 * @param[in] ctx ctx value passed to callback from calling function.
979 * @param[in] UNUSED handle to an invocation
980 * @param[in] clientResponse Response from queries to remote servers.
981 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
982 * and OC_STACK_KEEP_TRANSACTION to keep it.
984 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
985 OCClientResponse *clientResponse)
987 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
988 VERIFY_NON_NULL(TAG, ctx, WARNING);
990 OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
992 OCStackResult res = OC_STACK_OK;
993 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
994 otmCtx->ocDoHandle = NULL;
996 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
998 if(otmCtx && otmCtx->selectedDeviceInfo)
1000 //In case of Mutual Verified Just-Works, wait for user confirmation
1001 if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1003 res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
1004 if (OC_STACK_OK != res)
1006 if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, deleteCallback))
1008 OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error");
1010 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to verify user confirm");
1011 SetResult(otmCtx, res);
1012 return OC_STACK_DELETE_TRANSACTION;
1016 res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
1017 if(OC_STACK_OK != res)
1019 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
1020 SetResult(otmCtx, res);
1021 return OC_STACK_DELETE_TRANSACTION;
1024 //POST owner credential to new device according to security spec B.
1025 res = PostOwnerCredential(otmCtx);
1026 if(OC_STACK_OK != res)
1029 "OwnerUuidUpdateHandler:Failed to send PosT request for onwer credential");
1030 SetResult(otmCtx, res);
1031 return OC_STACK_DELETE_TRANSACTION;
1037 if (((OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel) ||
1038 (OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)) &&
1039 OC_STACK_NOT_ACCEPTABLE == clientResponse->result)
1041 res = OC_STACK_USER_DENIED_REQ;
1042 OIC_LOG_V(ERROR, TAG,
1043 "OwnerUuidUpdateHandler : Denied Request(%d)", res);
1045 else if (OC_STACK_GATEWAY_TIMEOUT == clientResponse->result)
1047 res = clientResponse->result;
1048 OIC_LOG_V(ERROR, TAG,
1049 "OwnerUuidUpdateHandler : Timeout:No Response Received(%d)", res);
1053 res = clientResponse->result;
1054 OIC_LOG_V(ERROR, TAG, "OwnerUuidUpdateHandler : Unexpected result(%d)", res);
1056 SetResult(otmCtx, res);
1059 OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
1062 return OC_STACK_DELETE_TRANSACTION;
1066 * Invokes Callback to load Random PIN
1068 void *LoadRandomPin(void *ctx)
1070 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1071 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1072 OCStackResult res = OC_STACK_ERROR;
1073 res = otmCtx->otmCallback.loadSecretCB(otmCtx);
1075 if(OC_STACK_OK != res)
1077 OIC_LOG_V(ERROR, TAG, "%s : Failed to load secret", __func__);
1078 SetResult(otmCtx, res);
1079 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1083 //Save the current context instance to use on the dtls handshake callback
1084 if(OC_STACK_OK != AddOTMContext(otmCtx,
1085 otmCtx->selectedDeviceInfo->endpoint.addr,
1086 otmCtx->selectedDeviceInfo->securePort))
1088 OIC_LOG_V(ERROR, TAG, "%s : Failed to add OTM Context into OTM List.", __func__);
1089 SetResult(otmCtx, res);
1090 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1094 //Try DTLS handshake to generate secure session
1095 if(otmCtx->otmCallback.createSecureSessionCB)
1097 res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
1098 if(OC_STACK_OK != res)
1100 OIC_LOG_V(ERROR, TAG, "%s : Failed to create DTLS session", __func__);
1101 SetResult(otmCtx, res);
1104 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1109 * Response handler for update operation mode.
1111 * @param[in] ctx ctx value passed to callback from calling function.
1112 * @param[in] UNUSED handle to an invocation
1113 * @param[in] clientResponse Response from queries to remote servers.
1114 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1115 * and OC_STACK_KEEP_TRANSACTION to keep it.
1117 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
1118 OCClientResponse *clientResponse)
1120 OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
1122 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1123 VERIFY_NON_NULL(TAG, ctx, WARNING);
1125 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1126 otmCtx->ocDoHandle = NULL;
1128 if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1130 OCStackResult res = OC_STACK_ERROR;
1133 //Load secret for temporal secure session.
1134 if(otmCtx->otmCallback.loadSecretCB)
1136 if (OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1140 thr_result = pthread_create(&p_thread, NULL, LoadRandomPin, (void *) otmCtx);
1141 if (0 != thr_result)
1143 OIC_LOG_V(ERROR, TAG, "pthread_create Error with code %d", thr_result);
1144 SetResult(otmCtx, res);
1145 return OC_STACK_DELETE_TRANSACTION;
1147 OIC_LOG(INFO, TAG, "Random Pin loadSecretCB Thread Created");
1151 res = otmCtx->otmCallback.loadSecretCB(otmCtx);
1152 if(OC_STACK_OK != res)
1154 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
1155 SetResult(otmCtx, res);
1156 return OC_STACK_DELETE_TRANSACTION;
1159 //Save the current context instance to use on the dtls handshake callback
1160 if(OC_STACK_OK != AddOTMContext(otmCtx,
1161 otmCtx->selectedDeviceInfo->endpoint.addr,
1162 otmCtx->selectedDeviceInfo->securePort))
1164 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List.");
1165 SetResult(otmCtx, res);
1166 return OC_STACK_DELETE_TRANSACTION;
1169 //Try DTLS handshake to generate secure session
1170 if(otmCtx->otmCallback.createSecureSessionCB)
1172 res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
1173 if(OC_STACK_OK != res)
1175 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
1176 SetResult(otmCtx, res);
1177 return OC_STACK_DELETE_TRANSACTION;
1185 OIC_LOG(ERROR, TAG, "Error while update operation mode");
1186 SetResult(otmCtx, clientResponse->result);
1189 OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
1192 return OC_STACK_DELETE_TRANSACTION;
1196 * Response handler for update owner crendetial request.
1198 * @param[in] ctx ctx value passed to callback from calling function.
1199 * @param[in] UNUSED handle to an invocation
1200 * @param[in] clientResponse Response from queries to remote servers.
1201 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1202 * and OC_STACK_KEEP_TRANSACTION to keep it.
1204 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
1205 OCClientResponse *clientResponse)
1207 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1208 VERIFY_NON_NULL(TAG, ctx, WARNING);
1210 OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
1212 OCStackResult res = OC_STACK_OK;
1213 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1214 otmCtx->ocDoHandle = NULL;
1216 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1218 if(otmCtx && otmCtx->selectedDeviceInfo)
1220 //Close the temporal secure session to verify the owner credential
1221 CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
1222 endpoint->port = otmCtx->selectedDeviceInfo->securePort;
1223 CAResult_t caResult = CA_STATUS_OK;
1224 caResult = CAcloseSslConnection(endpoint);
1226 if(CA_STATUS_OK != caResult)
1228 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
1229 SetResult(otmCtx, caResult);
1230 return OC_STACK_DELETE_TRANSACTION;
1234 * If we select NULL cipher,
1235 * client will select appropriate cipher suite according to server's cipher-suite list.
1237 // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
1238 caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
1239 if(CA_STATUS_OK != caResult)
1241 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
1242 SetResult(otmCtx, caResult);
1243 return OC_STACK_DELETE_TRANSACTION;
1247 * in case of random PIN based OxM,
1248 * revert get_psk_info callback of tinyDTLS to use owner credential.
1250 if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1252 OicUuid_t emptyUuid = { .id={0}};
1253 SetUuidForPinBasedOxm(&emptyUuid);
1255 caResult = CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
1257 if(CA_STATUS_OK != caResult)
1259 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1260 SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
1261 return OC_STACK_DELETE_TRANSACTION;
1265 otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
1267 res = PostOwnerAcl(otmCtx);
1268 if(OC_STACK_OK != res)
1270 OIC_LOG(ERROR, TAG, "Failed to update owner ACL to new device");
1271 SetResult(otmCtx, res);
1272 return OC_STACK_DELETE_TRANSACTION;
1278 res = clientResponse->result;
1279 OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
1280 SetResult(otmCtx, res);
1283 OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
1286 return OC_STACK_DELETE_TRANSACTION;
1290 * Response handler for update owner ACL request.
1292 * @param[in] ctx ctx value passed to callback from calling function.
1293 * @param[in] UNUSED handle to an invocation
1294 * @param[in] clientResponse Response from queries to remote servers.
1295 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1296 * and OC_STACK_KEEP_TRANSACTION to keep it.
1298 static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle UNUSED,
1299 OCClientResponse *clientResponse)
1301 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1302 VERIFY_NON_NULL(TAG, ctx, WARNING);
1304 OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler");
1306 OCStackResult res = OC_STACK_OK;
1307 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1308 otmCtx->ocDoHandle = NULL;
1310 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1312 if(otmCtx && otmCtx->selectedDeviceInfo)
1314 //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }]
1315 res = PostOwnershipInformation(otmCtx);
1316 if(OC_STACK_OK != res)
1318 OIC_LOG(ERROR, TAG, "Failed to update ownership information to new device");
1319 SetResult(otmCtx, res);
1325 res = clientResponse->result;
1326 OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res);
1327 SetResult(otmCtx, res);
1330 OIC_LOG(DEBUG, TAG, "OUT OwnerAclHandler");
1333 return OC_STACK_DELETE_TRANSACTION;
1338 * Response handler for update owner information request.
1340 * @param[in] ctx ctx value passed to callback from calling function.
1341 * @param[in] UNUSED handle to an invocation
1342 * @param[in] clientResponse Response from queries to remote servers.
1343 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1344 * and OC_STACK_KEEP_TRANSACTION to keep it.
1346 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
1347 OCClientResponse *clientResponse)
1349 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1350 VERIFY_NON_NULL(TAG, ctx, WARNING);
1352 OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
1354 OCStackResult res = OC_STACK_OK;
1355 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1356 otmCtx->ocDoHandle = NULL;
1358 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1360 if(otmCtx && otmCtx->selectedDeviceInfo)
1362 OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
1363 OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
1365 res = PostProvisioningStatus(otmCtx);
1366 if(OC_STACK_OK != res)
1368 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1369 SetResult(otmCtx, res);
1375 res = clientResponse->result;
1376 OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
1377 SetResult(otmCtx, res);
1380 OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
1383 return OC_STACK_DELETE_TRANSACTION;
1387 * Response handler of update provisioning status.
1389 * @param[in] ctx ctx value passed to callback from calling function.
1390 * @param[in] UNUSED handle to an invocation
1391 * @param[in] clientResponse Response from queries to remote servers.
1392 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1393 * and OC_STACK_KEEP_TRANSACTION to keep it.
1395 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
1396 OCClientResponse *clientResponse)
1398 OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
1400 VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1401 VERIFY_NON_NULL(TAG, ctx, ERROR);
1403 OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1404 otmCtx->ocDoHandle = NULL;
1406 OCStackResult res = OC_STACK_OK;
1408 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1410 if(otmCtx && otmCtx->selectedDeviceInfo)
1412 OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
1414 res = PostNormalOperationStatus(otmCtx);
1415 if(OC_STACK_OK != res)
1417 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1418 SetResult(otmCtx, res);
1424 OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1425 clientResponse->result);
1426 SetResult(otmCtx, clientResponse->result);
1430 OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
1431 return OC_STACK_DELETE_TRANSACTION;
1435 * Response handler of update provisioning status to Ready for Normal..
1437 * @param[in] ctx ctx value passed to callback from calling function.
1438 * @param[in] UNUSED handle to an invocation
1439 * @param[in] clientResponse Response from queries to remote servers.
1440 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1441 * and OC_STACK_KEEP_TRANSACTION to keep it.
1443 static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
1444 OCClientResponse *clientResponse)
1446 OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
1448 VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1449 VERIFY_NON_NULL(TAG, ctx, ERROR);
1451 OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1452 otmCtx->ocDoHandle = NULL;
1455 if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1457 OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
1458 OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
1460 if (OC_STACK_OK == res)
1462 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1463 SetResult(otmCtx, OC_STACK_OK);
1464 return OC_STACK_DELETE_TRANSACTION;
1468 OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1473 OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1474 clientResponse->result);
1475 SetResult(otmCtx, clientResponse->result);
1479 OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
1480 return OC_STACK_DELETE_TRANSACTION;
1483 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx)
1485 OIC_LOG(DEBUG, TAG, "IN PostOwnerCredential");
1487 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1489 OIC_LOG(ERROR, TAG, "Invalid parameters");
1490 return OC_STACK_INVALID_PARAM;
1493 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1494 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1496 if(!PMGenerateQuery(true,
1497 deviceInfo->endpoint.addr, deviceInfo->securePort,
1498 deviceInfo->connType,
1499 query, sizeof(query), OIC_RSRC_CRED_URI))
1501 OIC_LOG(ERROR, TAG, "PostOwnerCredential : Failed to generate query");
1502 return OC_STACK_ERROR;
1504 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1505 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1508 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1509 return OC_STACK_NO_MEMORY;
1512 //Generate owner credential for new device
1513 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1514 const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
1515 if(!ownerCredential)
1517 OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
1518 return OC_STACK_NO_RESOURCE;
1521 OicUuid_t credSubjectId = {.id={0}};
1522 if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
1524 OicSecCred_t newCredential;
1525 memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
1526 newCredential.next = NULL;
1528 //Set subject ID as PT's ID
1529 memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
1531 //Fill private data as empty string
1532 newCredential.privateData.data = (uint8_t*)"";
1533 newCredential.privateData.len = 0;
1534 newCredential.privateData.encoding = ownerCredential->privateData.encoding;
1536 newCredential.publicData.data = NULL;
1537 newCredential.publicData.len = 0;
1538 newCredential.publicData.encoding = ownerCredential->publicData.encoding;
1541 //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
1542 if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
1543 &secPayload->payloadSize, secureFlag))
1545 OICFree(secPayload);
1546 OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1547 return OC_STACK_ERROR;
1549 OIC_LOG(DEBUG, TAG, "Cred Payload:");
1550 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1552 OCCallbackData cbData;
1553 cbData.cb = &OwnerCredentialHandler;
1554 cbData.context = (void *)otmCtx;
1556 OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1557 &deviceInfo->endpoint, (OCPayload*)secPayload,
1558 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1559 if (res != OC_STACK_OK)
1561 OIC_LOG(ERROR, TAG, "OCStack resource error");
1566 OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
1567 return OC_STACK_NO_RESOURCE;
1570 OIC_LOG(DEBUG, TAG, "OUT PostOwnerCredential");
1575 static OicSecAcl_t* GenerateOwnerAcl(const OicUuid_t* owner)
1577 OicSecAcl_t* ownerAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
1578 OicSecAce_t* ownerAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1579 OicSecRsrc_t* wildcardRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1580 if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1582 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1585 LL_APPEND(ownerAcl->aces, ownerAce);
1586 LL_APPEND(ownerAce->resources, wildcardRsrc);
1588 //Set resource owner as PT
1589 memcpy(ownerAcl->rownerID.id, owner->id, sizeof(owner->id));
1591 //PT has full permission.
1592 ownerAce->permission = PERMISSION_FULL_CONTROL;
1594 //Set subject as PT's UUID
1595 memcpy(ownerAce->subjectuuid.id, owner->id, sizeof(owner->id));
1597 wildcardRsrc->href = OICStrdup(WILDCARD_RESOURCE_URI);
1598 if(NULL == wildcardRsrc->href)
1603 wildcardRsrc->interfaceLen = 1;
1604 wildcardRsrc->interfaces = (char**)OICMalloc(wildcardRsrc->interfaceLen * sizeof(char*));
1605 if(NULL == wildcardRsrc->interfaces)
1609 wildcardRsrc->interfaces[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1610 if(NULL == wildcardRsrc->interfaces[0])
1615 wildcardRsrc->typeLen = 1;
1616 wildcardRsrc->types = (char**)OICMalloc(wildcardRsrc->typeLen * sizeof(char*));
1617 if(NULL == wildcardRsrc->types)
1621 wildcardRsrc->types[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1622 if(NULL == wildcardRsrc->types[0])
1630 //in case of memory allocation failed, each resource should be removed individually.
1631 if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1635 OICFree(wildcardRsrc);
1639 DeleteACLList(ownerAcl);
1645 * Function to update the owner ACL to new device.
1647 * @param[in] otmCtx Context value of ownership transfer.
1648 * @return OC_STACK_OK on success
1650 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx)
1652 OCStackResult res = OC_STACK_ERROR;
1654 OIC_LOG(DEBUG, TAG, "IN PostOwnerAcl");
1656 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1658 OIC_LOG(ERROR, TAG, "Invalid parameters");
1659 return OC_STACK_INVALID_PARAM;
1662 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1663 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1664 OicSecAcl_t* ownerAcl = NULL;
1666 if(!PMGenerateQuery(true,
1667 deviceInfo->endpoint.addr, deviceInfo->securePort,
1668 deviceInfo->connType,
1669 query, sizeof(query), OIC_RSRC_ACL_URI))
1671 OIC_LOG(ERROR, TAG, "Failed to generate query");
1672 return OC_STACK_ERROR;
1674 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1677 res = GetDoxmDeviceID(&ownerID);
1678 if(OC_STACK_OK != res)
1680 OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1684 //Generate owner ACL for new device
1685 ownerAcl = GenerateOwnerAcl(&ownerID);
1686 if(NULL == ownerAcl)
1688 OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1689 return OC_STACK_NO_MEMORY;
1692 //Generate ACL payload
1693 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1696 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1697 res = OC_STACK_NO_MEMORY;
1701 res = AclToCBORPayload(ownerAcl, &secPayload->securityData, &secPayload->payloadSize);
1702 if (OC_STACK_OK != res)
1704 OICFree(secPayload);
1705 OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1708 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1710 OIC_LOG(DEBUG, TAG, "Owner ACL Payload:");
1711 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1713 //Send owner ACL to new device : POST /oic/sec/cred [ owner credential ]
1714 OCCallbackData cbData;
1715 cbData.cb = &OwnerAclHandler;
1716 cbData.context = (void *)otmCtx;
1718 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1719 &deviceInfo->endpoint, (OCPayload*)secPayload,
1720 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1721 if (res != OC_STACK_OK)
1723 OIC_LOG(ERROR, TAG, "OCStack resource error");
1727 OIC_LOG(DEBUG, TAG, "OUT PostOwnerAcl");
1730 DeleteACLList(ownerAcl);
1735 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx)
1737 OIC_LOG(DEBUG, TAG, "IN PostOwnerTransferModeToResource");
1739 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1741 OIC_LOG(ERROR, TAG, "Invalid parameters");
1742 return OC_STACK_INVALID_PARAM;
1745 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1746 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1748 if(!PMGenerateQuery(false,
1749 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1750 deviceInfo->connType,
1751 query, sizeof(query), OIC_RSRC_DOXM_URI))
1753 OIC_LOG(ERROR, TAG, "PostOwnerTransferModeToResource : Failed to generate query");
1754 return OC_STACK_ERROR;
1756 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1758 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1761 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1762 return OC_STACK_NO_MEMORY;
1765 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1766 OCStackResult res = otmCtx->otmCallback.createSelectOxmPayloadCB(otmCtx,
1767 &secPayload->securityData, &secPayload->payloadSize);
1768 if (OC_STACK_OK != res && NULL == secPayload->securityData)
1770 OCPayloadDestroy((OCPayload *)secPayload);
1771 OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
1772 return OC_STACK_ERROR;
1775 OCCallbackData cbData;
1776 cbData.cb = &OwnerTransferModeHandler;
1777 cbData.context = (void *)otmCtx;
1779 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1780 &deviceInfo->endpoint, (OCPayload *)secPayload,
1781 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1782 if (res != OC_STACK_OK)
1784 OIC_LOG(ERROR, TAG, "OCStack resource error");
1787 OIC_LOG(DEBUG, TAG, "OUT PostOwnerTransferModeToResource");
1792 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1794 OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1796 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1798 OIC_LOG(ERROR, TAG, "Invailed parameters");
1799 return OC_STACK_INVALID_PARAM;
1802 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1803 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1804 if(!PMGenerateQuery(false,
1805 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1806 deviceInfo->connType,
1807 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1809 OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1810 return OC_STACK_ERROR;
1812 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1814 OCCallbackData cbData;
1815 cbData.cb = &ListMethodsHandler;
1816 cbData.context = (void *)otmCtx;
1818 OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
1819 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1820 if (res != OC_STACK_OK)
1822 OIC_LOG(ERROR, TAG, "OCStack resource error");
1825 OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1830 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
1832 OIC_LOG(DEBUG, TAG, "IN PostOwnerUuid");
1834 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1836 OIC_LOG(ERROR, TAG, "Invailed parameters");
1837 return OC_STACK_INVALID_PARAM;
1840 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1841 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1842 if(!PMGenerateQuery(true,
1843 deviceInfo->endpoint.addr, deviceInfo->securePort,
1844 deviceInfo->connType,
1845 query, sizeof(query), OIC_RSRC_DOXM_URI))
1847 OIC_LOG(ERROR, TAG, "PostOwnerUuid : Failed to generate query");
1848 return OC_STACK_ERROR;
1850 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1852 //Post PT's uuid to new device
1853 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1856 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1857 return OC_STACK_NO_MEMORY;
1859 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1860 OCStackResult res = otmCtx->otmCallback.createOwnerTransferPayloadCB(
1861 otmCtx, &secPayload->securityData, &secPayload->payloadSize);
1862 if (OC_STACK_OK != res && NULL == secPayload->securityData)
1864 OCPayloadDestroy((OCPayload *)secPayload);
1865 OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
1866 return OC_STACK_INVALID_PARAM;
1868 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1870 OCCallbackData cbData;
1871 cbData.cb = &OwnerUuidUpdateHandler;
1872 cbData.context = (void *)otmCtx;
1875 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1876 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1877 if (res != OC_STACK_OK)
1879 OIC_LOG(ERROR, TAG, "OCStack resource error");
1882 OIC_LOG(DEBUG, TAG, "OUT PostOwnerUuid");
1887 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
1889 OIC_LOG(DEBUG, TAG, "IN PostOwnershipInformation");
1891 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1893 OIC_LOG(ERROR, TAG, "Invailed parameters");
1894 return OC_STACK_INVALID_PARAM;
1897 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1898 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1899 if(!PMGenerateQuery(true,
1900 deviceInfo->endpoint.addr, deviceInfo->securePort,
1901 deviceInfo->connType,
1902 query, sizeof(query), OIC_RSRC_DOXM_URI))
1904 OIC_LOG(ERROR, TAG, "PostOwnershipInformation : Failed to generate query");
1905 return OC_STACK_ERROR;
1907 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1909 //OwnershipInformationHandler
1910 OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1913 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1914 return OC_STACK_NO_MEMORY;
1917 otmCtx->selectedDeviceInfo->doxm->owned = true;
1919 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1920 OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
1921 &secPayload->securityData, &secPayload->payloadSize, true);
1922 if (OC_STACK_OK != res && NULL == secPayload->securityData)
1924 OCPayloadDestroy((OCPayload *)secPayload);
1925 OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1926 return OC_STACK_INVALID_PARAM;
1929 OCCallbackData cbData;
1930 cbData.cb = &OwnershipInformationHandler;
1931 cbData.context = (void *)otmCtx;
1934 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
1935 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1936 if (res != OC_STACK_OK)
1938 OIC_LOG(ERROR, TAG, "OCStack resource error");
1941 OIC_LOG(DEBUG, TAG, "OUT PostOwnershipInformation");
1946 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
1948 OIC_LOG(DEBUG, TAG, "IN PostUpdateOperationMode");
1950 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1952 return OC_STACK_INVALID_PARAM;
1955 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1956 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1957 if(!PMGenerateQuery(false,
1958 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1959 deviceInfo->connType,
1960 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1962 OIC_LOG(ERROR, TAG, "PostUpdateOperationMode : Failed to generate query");
1963 return OC_STACK_ERROR;
1965 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1967 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1970 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1971 return OC_STACK_NO_MEMORY;
1973 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1974 OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
1975 &secPayload->payloadSize, true);
1976 if (OC_STACK_OK != res)
1978 OCPayloadDestroy((OCPayload *)secPayload);
1979 OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
1980 return OC_STACK_INVALID_PARAM;
1983 OCCallbackData cbData;
1984 cbData.cb = &OperationModeUpdateHandler;
1985 cbData.context = (void *)otmCtx;
1987 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1988 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1989 if (res != OC_STACK_OK)
1991 OIC_LOG(ERROR, TAG, "OCStack resource error");
1994 OIC_LOG(DEBUG, TAG, "OUT PostUpdateOperationMode");
1999 static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice)
2001 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2003 PdmDeviceState_t pdmState = PDM_DEVICE_UNKNOWN;
2004 OCStackResult res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState);
2005 if (OC_STACK_OK != res)
2007 OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res);
2011 char* strUuid = NULL;
2012 bool removeCredReq = false;
2013 if (OC_STACK_OK != ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid))
2015 OIC_LOG(WARNING, TAG, "Failed to covert uuid to string");
2016 return OC_STACK_NO_MEMORY;
2019 if (PDM_DEVICE_UNKNOWN == pdmState && !selectedDevice->doxm->owned)
2021 removeCredReq = true;
2023 else if (PDM_DEVICE_ACTIVE == pdmState && !selectedDevice->doxm->owned)
2025 OIC_LOG_V(WARNING, TAG, "Unowned device[%s] dectected from PDM.", strUuid);
2026 OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", strUuid);
2027 res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
2028 if(OC_STACK_OK != res)
2030 OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", strUuid);
2034 removeCredReq = true;
2039 OIC_LOG_V(WARNING, TAG, "[%s]'s credential will be removed.", strUuid);
2040 res = RemoveCredential(&selectedDevice->doxm->deviceID);
2041 if (OC_STACK_RESOURCE_DELETED != res)
2043 OIC_LOG_V(WARNING, TAG, "Can not find [%s]'s credential.", strUuid);
2047 //Checking duplication of Device ID.
2048 bool isDuplicate = true;
2049 res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
2050 if (OC_STACK_OK != res)
2052 OIC_LOG_V(ERROR, TAG, "Internal error in PDMIsDuplicateDevice : %d", res);
2058 char* strUuid = NULL;
2059 res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
2060 if (OC_STACK_OK != res)
2062 OIC_LOG_V(ERROR, TAG, "Failed to convert UUID to str : %d", res);
2066 if (PDM_DEVICE_STALE == pdmState)
2068 OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
2069 "device status will revert back to initial status.");
2070 res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
2071 if (OC_STACK_OK != res)
2073 OIC_LOG_V(ERROR, TAG, "Internal error in PDMSetDeviceState : %d", res);
2077 else if (PDM_DEVICE_INIT == pdmState)
2079 OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
2081 res = OC_STACK_DUPLICATE_REQUEST;
2086 OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
2088 res = OC_STACK_ERROR;
2094 res = PDMAddDevice(&selectedDevice->doxm->deviceID);
2095 if (OC_STACK_OK != res)
2097 OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res);
2104 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2108 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
2110 OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
2111 OCStackResult res = OC_STACK_INVALID_PARAM;
2112 OicUuid_t emptyOwner = {.id = {0} };
2114 VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
2115 VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
2117 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
2118 otmCtx->selectedDeviceInfo = selectedDevice;
2120 //If devowneruuid of selectedDevice is not emtry, PostOwnerUuid does not triggered in DTLSHandshakeCB
2121 if (memcmp(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
2123 OIC_LOG(DEBUG, TAG, "Set devowneruuid of selectedDevice to empty for OwnershipTransfer");
2124 memcpy(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t));
2127 //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
2128 res = SetupPDM(selectedDevice);
2129 if(OC_STACK_OK != res)
2131 OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
2132 SetResult(otmCtx, res);
2136 //Select the OxM to performing ownership transfer
2137 res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
2138 selectedDevice->doxm->oxmLen,
2139 &selectedDevice->doxm->oxmSel,
2141 if(OC_STACK_OK != res)
2143 OIC_LOG_V(ERROR, TAG, "Failed to select the provisioning method : %d", res);
2144 SetResult(otmCtx, res);
2147 OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
2149 res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
2150 if(OC_STACK_OK != res)
2152 OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
2156 //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
2157 res = PostOwnerTransferModeToResource(otmCtx);
2158 if(OC_STACK_OK != res)
2160 OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
2161 SetResult(otmCtx, res);
2165 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2166 //Register TLS event handler to catch the tls event while handshake
2167 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2169 OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2171 #endif // __WITH_DTLS__ or __WITH_TLS__
2172 OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2178 static OCStackResult StartCustomOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice,const OicSecOxm_t method)
2180 OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
2181 OCStackResult res = OC_STACK_INVALID_PARAM;
2183 VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
2184 VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
2186 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
2187 otmCtx->selectedDeviceInfo = selectedDevice;
2189 //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
2190 res = SetupPDM(selectedDevice);
2191 if(OC_STACK_OK != res)
2193 OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
2194 SetResult(otmCtx, res);
2198 //Select the OxM to performing ownership transfer
2199 selectedDevice->doxm->oxmSel = method;
2200 OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
2202 res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
2203 if(OC_STACK_OK != res)
2205 OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
2209 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2210 //Register TLS event handler, to catch the TLS handshake event
2211 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2213 OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2215 #endif // __WITH_DTLS__ or __WITH_TLS__
2217 //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
2218 res = PostOwnerTransferModeToResource(otmCtx);
2219 if(OC_STACK_OK != res)
2221 OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
2222 SetResult(otmCtx, res);
2226 OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2232 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
2234 OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
2238 OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
2239 return OC_STACK_INVALID_PARAM;
2241 if(oxmType >= OIC_OXM_COUNT)
2243 OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
2244 return OC_STACK_INVALID_PARAM;
2247 // TODO: Remove this API, Please see the jira ticket IOT-1484
2249 OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
2254 OCStackResult OTMDoCustomOwnershipTransfer(void* ctx,
2255 OCProvisionDev_t *selectedDevice,
2256 OCProvisionResultCB resultCallback,
2257 const OicSecOxm_t method)
2259 OIC_LOG(DEBUG, TAG, "IN OTMDoCustomOwnershipTransfer");
2261 if (NULL == selectedDevice)
2263 return OC_STACK_INVALID_PARAM;
2265 if (NULL == resultCallback)
2267 return OC_STACK_INVALID_CALLBACK;
2270 OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2273 OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2274 return OC_STACK_NO_MEMORY;
2277 otmCtx->ctxResultCallback = resultCallback;
2278 otmCtx->ctxHasError = false;
2279 otmCtx->userCtx = ctx;
2281 //Setting number of selected device.
2282 otmCtx->ctxResultArraySize = 1;
2284 otmCtx->ctxResultArray =
2285 (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2286 if(NULL == otmCtx->ctxResultArray)
2288 OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2290 return OC_STACK_NO_MEMORY;
2293 //Fill the device UUID for result array.
2294 memcpy(otmCtx->ctxResultArray[0].deviceId.id,
2295 selectedDevice->doxm->deviceID.id,
2297 otmCtx->ctxResultArray[0].res = OC_STACK_CONTINUE;
2299 OCStackResult res = StartCustomOwnershipTransfer(otmCtx, selectedDevice, method);
2301 OIC_LOG(DEBUG, TAG, "OUT OTMDoCustomOwnershipTransfer");
2307 * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
2309 OCStackResult OTMDoOwnershipTransfer(void* ctx,
2310 OCProvisionDev_t *selectedDevicelist,
2311 OCProvisionResultCB resultCallback)
2313 OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
2315 if (NULL == selectedDevicelist)
2317 return OC_STACK_INVALID_PARAM;
2319 if (NULL == resultCallback)
2321 return OC_STACK_INVALID_CALLBACK;
2324 OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2327 OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2328 return OC_STACK_NO_MEMORY;
2330 otmCtx->ctxResultCallback = resultCallback;
2331 otmCtx->ctxHasError = false;
2332 otmCtx->userCtx = ctx;
2333 OCProvisionDev_t* pCurDev = selectedDevicelist;
2335 //Counting number of selected devices.
2336 otmCtx->ctxResultArraySize = 0;
2337 while(NULL != pCurDev)
2339 otmCtx->ctxResultArraySize++;
2340 pCurDev = pCurDev->next;
2343 otmCtx->ctxResultArray =
2344 (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2345 if(NULL == otmCtx->ctxResultArray)
2347 OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2349 return OC_STACK_NO_MEMORY;
2351 pCurDev = selectedDevicelist;
2353 //Fill the device UUID for result array.
2354 for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
2356 memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
2357 pCurDev->doxm->deviceID.id,
2359 otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
2360 pCurDev = pCurDev->next;
2363 OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist);
2365 OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
2370 OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
2372 OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
2373 __func__, oxm, (allowStatus ? "true" : "false"));
2375 #ifdef MULTIPLE_OWNER
2376 if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
2378 if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
2381 return OC_STACK_INVALID_PARAM;
2384 OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
2385 if(OXM_IDX_COUNT <= oxmIdx)
2387 OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
2388 return OC_STACK_ERROR;
2390 g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
2392 OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2397 OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
2399 OIC_LOG(INFO, TAG, "IN PostProvisioningStatus");
2401 if(!otmCtx || !otmCtx->selectedDeviceInfo)
2403 OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2404 return OC_STACK_INVALID_PARAM;
2407 //Change the TAKE_OWNER bit of CM to 0.
2408 otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
2410 OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2413 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2414 return OC_STACK_NO_MEMORY;
2416 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2417 if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2418 &secPayload->securityData, &secPayload->payloadSize, true))
2420 OCPayloadDestroy((OCPayload *)secPayload);
2421 return OC_STACK_INVALID_JSON;
2423 OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2424 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2426 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2427 if(!PMGenerateQuery(true,
2428 otmCtx->selectedDeviceInfo->endpoint.addr,
2429 otmCtx->selectedDeviceInfo->securePort,
2430 otmCtx->selectedDeviceInfo->connType,
2431 query, sizeof(query), OIC_RSRC_PSTAT_URI))
2433 OIC_LOG(ERROR, TAG, "PostProvisioningStatus : Failed to generate query");
2434 return OC_STACK_ERROR;
2436 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2438 OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2439 cbData.cb = &ProvisioningStatusHandler;
2440 cbData.context = (void*)otmCtx;
2442 OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2443 otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2444 OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2445 if (ret != OC_STACK_OK)
2447 OIC_LOG(ERROR, TAG, "OCStack resource error");
2450 OIC_LOG(INFO, TAG, "OUT PostProvisioningStatus");
2455 OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
2457 OIC_LOG(INFO, TAG, "IN PostNormalOperationStatus");
2459 if(!otmCtx || !otmCtx->selectedDeviceInfo)
2461 OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2462 return OC_STACK_INVALID_PARAM;
2466 otmCtx->selectedDeviceInfo->pstat->isOp = true;
2468 OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2471 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2472 return OC_STACK_NO_MEMORY;
2474 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2475 if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2476 &secPayload->securityData, &secPayload->payloadSize, true))
2478 OCPayloadDestroy((OCPayload *)secPayload);
2479 return OC_STACK_INVALID_JSON;
2481 OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2482 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2484 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2485 if(!PMGenerateQuery(true,
2486 otmCtx->selectedDeviceInfo->endpoint.addr,
2487 otmCtx->selectedDeviceInfo->securePort,
2488 otmCtx->selectedDeviceInfo->connType,
2489 query, sizeof(query), OIC_RSRC_PSTAT_URI))
2491 OIC_LOG(ERROR, TAG, "PostNormalOperationStatus : Failed to generate query");
2492 return OC_STACK_ERROR;
2494 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2496 OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2497 cbData.cb = &ReadyForNomalStatusHandler;
2498 cbData.context = (void*)otmCtx;
2500 OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2501 otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2502 OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2503 if (ret != OC_STACK_OK)
2505 OIC_LOG(ERROR, TAG, "OCStack resource error");
2508 OIC_LOG(INFO, TAG, "OUT PostNormalOperationStatus");
2513 OCStackResult ConfigSelfOwnership(void)
2515 OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership");
2517 bool isDeviceOwned = true;
2518 if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned))
2520 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state");
2521 return OC_STACK_ERROR;
2523 if( (true == isDeviceOwned) ||(true == GetPstatIsop()) )
2525 OIC_LOG(ERROR, TAG, "The state of device is not Ready for Ownership transfer.");
2526 return OC_STACK_ERROR;
2528 OicUuid_t deviceID = {.id={0}};
2529 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2531 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2532 return OC_STACK_ERROR;
2535 OCStackResult ret = OC_STACK_OK;
2536 //Update the pstat resource as Normal Operation.
2537 ret = SetPstatSelfOwnership(&deviceID);
2538 if(OC_STACK_OK != ret)
2540 OIC_LOG (ERROR, TAG, "Unable to update pstat resource as Normal Operation");
2543 //Update the doxm resource as Normal Operation.
2544 ret = SetDoxmSelfOwnership(&deviceID);
2545 if(OC_STACK_OK != ret)
2547 OIC_LOG (ERROR, TAG, "Unable to update doxm resource as Normal Operation");
2550 //Update default ACE of security resource to prevent anonymous user access.
2551 ret = UpdateDefaultSecProvACE();
2552 if(OC_STACK_OK != ret)
2554 OIC_LOG (ERROR, TAG, "Unable to update default ace in ConfigSelfOwnership");
2557 //Update the acl resource owner as owner device.
2558 ret = SetAclRownerId(&deviceID);
2559 if(OC_STACK_OK != ret)
2561 OIC_LOG (ERROR, TAG, "Unable to update acl resource in ConfigSelfOwnership");
2564 //Update the cred resource owner as owner device.
2565 ret = SetCredRownerId(&deviceID);
2566 if(OC_STACK_OK != ret)
2568 // Cred resouce may be empty in Ready for Ownership transfer state.
2569 if (OC_STACK_NO_RESOURCE == ret)
2571 OIC_LOG (INFO, TAG, "Cred resource is empty");
2575 OIC_LOG (ERROR, TAG, "Unable to update cred resource in ConfigSelfOwnership");
2579 if(OC_STACK_OK != ret)
2582 * If some error is occured while configure self-ownership,
2583 * ownership related resource should be revert back to initial status.
2585 ResetSecureResourceInPS();
2594 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2595 DeleteOTMContextList();
2597 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2598 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(NULL))
2600 OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback.");
2602 #endif // __WITH_DTLS__ or __WITH_TLS__
2604 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);