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
47 #include "oic_malloc.h"
48 #include "oic_string.h"
50 #include "cainterface.h"
55 #include "srmresourcestrings.h"
56 #include "doxmresource.h"
57 #include "pstatresource.h"
58 #include "credresource.h"
59 #include "aclresource.h"
60 #include "ownershiptransfermanager.h"
61 #include "securevirtualresourcetypes.h"
62 #include "oxmjustworks.h"
63 #ifdef _ENABLE_MULTIPLE_OWNER_
64 #include "oxmrandompin.h"
65 #include "oxmpreconfpin.h"
66 #endif //_ENABLE_MULTIPLE_OWNER_
67 #include "otmcontextlist.h"
69 #include "pmutility.h"
70 #include "srmutility.h"
71 #include "provisioningdatabasemanager.h"
72 #include "oxmrandompin.h"
73 #include "ocpayload.h"
74 #include "payload_logging.h"
79 * Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
81 static OTMContext_t* g_otmCtx = NULL;
83 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
85 OCStackResult res = OC_STACK_INVALID_PARAM;
87 OIC_LOG(INFO, TAG, "IN OTMSetOTCallback");
89 VERIFY_NON_NULL(TAG, callbacks, ERROR);
90 #ifdef _ENABLE_MULTIPLE_OWNER_
91 VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm), ERROR);
93 VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm), ERROR);
94 #endif //_ENABLE_MULTIPLE_OWNER_
99 callbacks->loadSecretCB = LoadSecretJustWorksCallback;
100 callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
101 callbacks->createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
102 callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
104 case OIC_RANDOM_DEVICE_PIN:
105 callbacks->loadSecretCB = InputPinCodeCallback;
106 callbacks->createSecureSessionCB = CreateSecureSessionRandomPinCallback;
107 callbacks->createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
108 callbacks->createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
110 case OIC_MANUFACTURER_CERTIFICATE:
111 OIC_LOG(ERROR, TAG, "OIC_MANUFACTURER_CERTIFICATE not supported yet.");
112 return OC_STACK_INVALID_METHOD;
113 case OIC_DECENTRALIZED_PUBLIC_KEY:
114 OIC_LOG(ERROR, TAG, "OIC_DECENTRALIZED_PUBLIC_KEY not supported yet.");
115 return OC_STACK_INVALID_METHOD;
116 #ifdef _ENABLE_MULTIPLE_OWNER_
117 case OIC_PRECONFIG_PIN:
118 callbacks->loadSecretCB = LoadPreconfigPinCodeCallback;
119 callbacks->createSecureSessionCB = CreateSecureSessionPreconfigPinCallback;
120 callbacks->createSelectOxmPayloadCB = CreatePreconfigPinBasedSelectOxmPayload;
121 callbacks->createOwnerTransferPayloadCB = CreatePreconfigPinBasedOwnerTransferPayload;
123 #endif //_ENABLE_MULTIPLE_OWNER_
125 OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
126 return OC_STACK_INVALID_PARAM;
132 OIC_LOG(INFO, TAG, "OUT OTMSetOTCallback");
137 * Function to select appropriate provisioning method.
139 * @param[in] supportedMethods Array of supported methods
140 * @param[in] numberOfMethods number of supported methods
141 * @param[out] selectedMethod Selected methods
142 * @return OC_STACK_OK on success
144 static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
145 size_t numberOfMethods, OicSecOxm_t *selectedMethod)
147 OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
149 if(numberOfMethods == 0 || !supportedMethods)
151 OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
152 return OC_STACK_ERROR;
155 *selectedMethod = supportedMethods[0];
156 for(size_t i = 0; i < numberOfMethods; i++)
158 if(*selectedMethod < supportedMethods[i])
160 *selectedMethod = supportedMethods[i];
164 OIC_LOG(DEBUG, TAG, "OUT SelectProvisioningMethod");
170 * Function to select operation mode.This function will return most secure common operation mode.
172 * @param[in] selectedDeviceInfo selected device information to performing provisioning.
173 * @param[out] selectedMode selected operation mode
174 * @return OC_STACK_OK on success
176 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
177 OicSecDpom_t *selectedMode)
179 OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
180 *selectedMode = selectedDeviceInfo->pstat->sm[0];
181 OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
185 * Function to start ownership transfer.
186 * This function will send the first request for provisioning,
187 * The next request message is sent from the response handler for this request.
189 * @param[in] ctx context value passed to callback from calling function.
190 * @param[in] selectedDevice selected device information to performing provisioning.
191 * @return OC_STACK_OK on success
193 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
196 * Function to update owner transfer mode
198 * @param[in] otmCtx Context value of ownership transfer.
199 * @return OC_STACK_OK on success
201 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx);
204 * Function to send request to resource to get its pstat resource information.
206 * @param[in] otmCtx Context value of ownership transfer.
207 * @return OC_STACK_OK on success
209 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
213 * Function to send uuid of owner device to new device.
214 * This function would update 'owner of doxm' as UUID for provisioning tool.
216 * @param[in] otmCtx Context value of ownership transfer.
217 * @return OC_STACK_OK on success
219 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx);
222 * Function to update the operation mode. As per the spec. Operation mode in client driven
223 * single service provisioning it will be updated to 0x3
225 * @param[in] otmCtx Context value of ownership transfer.
226 * @return OC_STACK_OK on success
228 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx);
231 * Function to update the owner credential to new device
233 * @param[in] otmCtx Context value of ownership transfer.
234 * @param[in] selectedOperationMode selected operation mode
235 * @return OC_STACK_OK on success
237 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx);
240 * Function to update the owner ACL to new device.
242 * @param[in] otmCtx Context value of ownership transfer.
243 * @return OC_STACK_OK on success
245 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx);
248 * Function to send ownerShip info.
249 * This function would update 'owned of doxm' as true.
251 * @param[in] otmCtx Context value of ownership transfer.
252 * @return OC_STACK_OK on success
254 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx);
257 * Function to update pstat as Ready for provisioning.
258 * This function would update 'cm' from bx0000,0010 to bx0000,0000.
260 * @param[in] ctx context value passed to callback from calling function.
261 * @param[in] selectedDevice selected device information to performing provisioning.
262 * @return OC_STACK_OK on success
264 static OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx);
267 * Function to update pstat as Ready for Normal Operation.
268 * This function would update 'isop' from false to true.
270 * @param[in] ctx context value passed to callback from calling function.
271 * @param[in] selectedDevice selected device information to performing provisioning.
272 * @return OC_STACK_OK on success
274 static OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx);
276 static bool IsComplete(OTMContext_t* otmCtx)
278 for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
280 if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
290 * Function to save the result of provisioning.
292 * @param[in,out] otmCtx Context value of ownership transfer.
293 * @param[in] res result of provisioning
295 static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
297 OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
299 if(NULL == otmCtx || NULL == otmCtx->selectedDeviceInfo)
301 OIC_LOG(WARNING, TAG, "OTMContext is NULL");
305 //If OTM Context was removed from previous response handler, just exit the current OTM process.
306 if(NULL == GetOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
307 otmCtx->selectedDeviceInfo->securePort))
309 OIC_LOG(WARNING, TAG, "Current OTM Process has already ended.");
313 //Revert psk_info callback and new deivce uuid in case of random PIN OxM
314 if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
316 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
318 OIC_LOG(WARNING, TAG, "Failed to revert is DTLS credential handler.");
320 OicUuid_t emptyUuid = { .id={0}};
321 SetUuidForPinBasedOxm(&emptyUuid);
324 for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
326 if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
327 otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
329 otmCtx->ctxResultArray[i].res = res;
330 if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res)
332 otmCtx->ctxHasError = true;
337 //In case of duplicated OTM process, OTMContext and OCDoHandle should not be removed.
338 if(OC_STACK_DUPLICATE_REQUEST != res)
340 //Remove the current OTM Context from OTM queue
341 RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
342 otmCtx->selectedDeviceInfo->securePort);
344 //If there is a request being performed, cancel it to prevent retransmission.
345 if(otmCtx->ocDoHandle)
347 OIC_LOG_V(DEBUG, TAG, "OCCancel - %s : %d",
348 otmCtx->selectedDeviceInfo->endpoint.addr,
349 otmCtx->selectedDeviceInfo->securePort);
350 if(OC_STACK_OK != OCCancel(otmCtx->ocDoHandle, OC_HIGH_QOS, NULL, 0))
352 OIC_LOG(WARNING, TAG, "Failed to remove registered callback");
356 otmCtx->ocDoHandle = NULL;
361 //If all OTM process is complete, invoke the user callback.
362 if(IsComplete(otmCtx))
364 otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
365 otmCtx->ctxResultArray, otmCtx->ctxHasError);
366 OICFree(otmCtx->ctxResultArray);
371 if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
372 otmCtx->selectedDeviceInfo->next))
374 OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
378 OIC_LOG(DEBUG, TAG, "OUT SetResult");
382 * Function to handle the handshake result in OTM.
383 * This function will be invoked after DTLS handshake
384 * @param endPoint [IN] The remote endpoint.
385 * @param errorInfo [IN] Error information from the endpoint.
388 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
390 if(NULL != endpoint && NULL != info)
392 OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
393 endpoint->addr, endpoint->port, info->result);
395 OTMContext_t* otmCtx = GetOTMContext(endpoint->addr, endpoint->port);
398 OicSecDoxm_t* newDevDoxm = otmCtx->selectedDeviceInfo->doxm;
399 if(NULL != newDevDoxm)
401 OicUuid_t emptyUuid = {.id={0}};
403 //Make sure the address matches.
404 if(strncmp(otmCtx->selectedDeviceInfo->endpoint.addr,
406 sizeof(endpoint->addr)) == 0 &&
407 otmCtx->selectedDeviceInfo->securePort == endpoint->port)
409 OCStackResult res = OC_STACK_ERROR;
411 //If temporal secure sesstion established successfully
412 if(CA_STATUS_OK == info->result &&
413 false == newDevDoxm->owned &&
414 memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0)
416 //Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
417 res = PostOwnerUuid(otmCtx);
418 if(OC_STACK_OK != res)
420 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
421 SetResult(otmCtx, res);
424 //In case of authentication failure
425 else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
427 //in case of error from owner credential
428 if(memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0 &&
429 true == newDevDoxm->owned)
431 OIC_LOG(ERROR, TAG, "The owner credential may incorrect.");
433 if(OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID)))
435 OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
437 SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
439 //in case of error from wrong PIN, re-start the ownership transfer
440 else if(OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel)
442 OIC_LOG(ERROR, TAG, "The PIN number may incorrect.");
444 memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
445 newDevDoxm->owned = false;
446 otmCtx->attemptCnt++;
448 if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
450 res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
451 if(OC_STACK_OK != res)
453 SetResult(otmCtx, res);
454 OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
459 OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
460 SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
465 OIC_LOG(ERROR, TAG, "Failed to establish secure session.");
466 SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
474 OIC_LOG(ERROR, TAG, "Can not find the OTM Context.");
480 * Function to save the Owner/SubOwner PSK.
482 * @param[in] selectedDeviceInfo selected device information to performing provisioning.
483 * @return OC_STACK_OK on success
485 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
487 OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
489 OCStackResult res = OC_STACK_ERROR;
491 CAEndpoint_t endpoint;
492 memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
493 OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
494 endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
495 endpoint.port = selectedDeviceInfo->securePort;
496 endpoint.adapter = selectedDeviceInfo->endpoint.adapter;
498 OicUuid_t ownerDeviceID = {.id={0}};
499 if (OC_STACK_OK != GetDoxmDeviceID(&ownerDeviceID))
501 OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
505 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
506 OicSecKey_t ownerKey = {ownerPSK, OWNER_PSK_LENGTH_128};
508 //Generating OwnerPSK
509 CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
510 (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
511 strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
512 ownerDeviceID.id, sizeof(ownerDeviceID.id),
513 selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
514 ownerPSK, OWNER_PSK_LENGTH_128);
516 if (CA_STATUS_OK == pskRet)
518 OIC_LOG(DEBUG, TAG,"Owner PSK dump:\n");
519 OIC_LOG_BUFFER(DEBUG, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
520 //Generating new credential for provisioning tool
521 OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
522 SYMMETRIC_PAIR_WISE_KEY, NULL,
523 &ownerKey, &ownerDeviceID, NULL);
524 OICClearMemory(ownerPSK, sizeof(ownerPSK));
525 VERIFY_NON_NULL(TAG, cred, ERROR);
527 // TODO: Added as workaround. Will be replaced soon.
528 cred->privateData.encoding = OIC_ENCODING_RAW;
531 // NOTE: Test codes to use BASE64 encoded owner PSK.
532 uint32_t outSize = 0;
533 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
534 char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
535 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
536 b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize);
538 OICFree( cred->privateData.data );
539 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
540 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
542 strncpy(cred->privateData.data, b64Buf, outSize);
543 cred->privateData.data[outSize] = '\0';
544 cred->privateData.encoding = OIC_ENCODING_BASE64;
545 cred->privateData.len = outSize;
547 #endif //End of Test codes
549 //Finding previous ownerPSK.
550 const OicSecCred_t* credList = GetCredList();
551 OicSecCred_t* prevCred = NULL;
553 LL_FOREACH(credList, prevCred)
555 //OwnerPSK's type is SYMMETRIC_PAIR_WISE_KEY
556 if (SYMMETRIC_PAIR_WISE_KEY == prevCred->credType &&
557 0 == memcmp(prevCred->subject.id, cred->subject.id, sizeof(cred->subject.id)))
559 credId = prevCred->credId;
564 //If duplicate owner PSK is exists, remove it.
567 OIC_LOG(WARNING, TAG, "Duplicate OwnerPSK was detected.");
568 OIC_LOG(WARNING, TAG, "[Subject] : ");
569 OIC_LOG_BUFFER(WARNING, TAG, prevCred->subject.id, sizeof(prevCred->subject.id));
570 OIC_LOG_V(WARNING, TAG, "[Encoding Type] : %d", prevCred->privateData.encoding);
571 OIC_LOG(DEBUG, TAG, "[Private Data] : ");
572 OIC_LOG_BUFFER(DEBUG, TAG, prevCred->privateData.data, prevCred->privateData.len);
573 OIC_LOG(WARNING, TAG, "Previous OwnerPSK will be removed.");
575 res = RemoveCredentialByCredId(credId);
576 if(OC_STACK_RESOURCE_DELETED != res)
578 OIC_LOG(ERROR, TAG, "Failed to remove the previous OwnerPSK");
579 DeleteCredList(cred);
584 res = AddCredential(cred);
585 if(res != OC_STACK_OK)
587 DeleteCredList(cred);
593 OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
596 OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
602 * Callback handler for OwnerShipTransferModeHandler API.
604 * @param[in] ctx ctx value passed to callback from calling function.
605 * @param[in] UNUSED handle to an invocation
606 * @param[in] clientResponse Response from queries to remote servers.
607 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
608 * and OC_STACK_KEEP_TRANSACTION to keep it.
610 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
611 OCClientResponse *clientResponse)
613 OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
615 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
616 VERIFY_NON_NULL(TAG, ctx, WARNING);
618 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
619 otmCtx->ocDoHandle = NULL;
621 if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
623 OIC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
624 //Send request : GET /oic/sec/pstat
625 OCStackResult res = GetProvisioningStatusResource(otmCtx);
626 if(OC_STACK_OK != res)
628 OIC_LOG(WARNING, TAG, "Failed to get pstat information");
629 SetResult(otmCtx, res);
634 OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
635 clientResponse->result);
636 SetResult(otmCtx, clientResponse->result);
639 OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
642 return OC_STACK_DELETE_TRANSACTION;
646 * Callback handler for ProvisioningStatusResouceHandler API.
648 * @param[in] ctx ctx value passed to callback from calling function.
649 * @param[in] UNUSED handle to an invocation
650 * @param[in] clientResponse Response from queries to remote servers.
651 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
652 * and OC_STACK_KEEP_TRANSACTION to keep it.
654 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
655 OCClientResponse *clientResponse)
657 OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
659 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
660 VERIFY_NON_NULL(TAG, ctx, WARNING);
662 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
663 otmCtx->ocDoHandle = NULL;
665 if (OC_STACK_OK == clientResponse->result)
667 if (NULL == clientResponse->payload)
669 OIC_LOG(INFO, TAG, "Skiping Null payload");
670 SetResult(otmCtx, OC_STACK_ERROR);
671 return OC_STACK_DELETE_TRANSACTION;
674 if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
676 OIC_LOG(INFO, TAG, "Unknown payload type");
677 SetResult(otmCtx, OC_STACK_ERROR);
678 return OC_STACK_DELETE_TRANSACTION;
680 OicSecPstat_t* pstat = NULL;
681 OCStackResult result = CBORPayloadToPstat(
682 ((OCSecurityPayload*)clientResponse->payload)->securityData,
683 ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
685 if(NULL == pstat || result != OC_STACK_OK)
687 OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
688 SetResult(otmCtx, OC_STACK_ERROR);
689 return OC_STACK_DELETE_TRANSACTION;
691 if(false == (TAKE_OWNER & pstat->cm))
693 OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
694 SetResult(otmCtx, OC_STACK_ERROR);
695 return OC_STACK_DELETE_TRANSACTION;
697 otmCtx->selectedDeviceInfo->pstat = pstat;
699 //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
700 SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
702 //Send request : POST /oic/sec/pstat [{"om":"bx11", .. }]
703 OCStackResult res = PostUpdateOperationMode(otmCtx);
704 if (OC_STACK_OK != res)
706 OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
707 SetResult(otmCtx, res);
712 OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
713 clientResponse->result);
714 SetResult(otmCtx, clientResponse->result);
717 OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
719 return OC_STACK_DELETE_TRANSACTION;
723 * Response handler for update owner uuid request.
725 * @param[in] ctx ctx value passed to callback from calling function.
726 * @param[in] UNUSED handle to an invocation
727 * @param[in] clientResponse Response from queries to remote servers.
728 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
729 * and OC_STACK_KEEP_TRANSACTION to keep it.
731 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
732 OCClientResponse *clientResponse)
734 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
735 VERIFY_NON_NULL(TAG, ctx, WARNING);
737 OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
739 OCStackResult res = OC_STACK_OK;
740 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
741 otmCtx->ocDoHandle = NULL;
743 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
745 if(otmCtx && otmCtx->selectedDeviceInfo)
747 res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
748 if(OC_STACK_OK != res)
750 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
751 SetResult(otmCtx, res);
752 return OC_STACK_DELETE_TRANSACTION;
755 //POST owner credential to new device according to security spec B.
756 res = PostOwnerCredential(otmCtx);
757 if(OC_STACK_OK != res)
760 "OwnerUuidUpdateHandler:Failed to send PosT request for onwer credential");
761 SetResult(otmCtx, res);
762 return OC_STACK_DELETE_TRANSACTION;
768 res = clientResponse->result;
769 OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
770 SetResult(otmCtx, res);
773 OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
776 return OC_STACK_DELETE_TRANSACTION;
780 * Response handler for update operation mode.
782 * @param[in] ctx ctx value passed to callback from calling function.
783 * @param[in] UNUSED handle to an invocation
784 * @param[in] clientResponse Response from queries to remote servers.
785 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
786 * and OC_STACK_KEEP_TRANSACTION to keep it.
788 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
789 OCClientResponse *clientResponse)
791 OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
793 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
794 VERIFY_NON_NULL(TAG, ctx, WARNING);
796 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
797 otmCtx->ocDoHandle = NULL;
799 if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
801 OCStackResult res = OC_STACK_ERROR;
802 OicSecOxm_t selOxm = otmCtx->selectedDeviceInfo->doxm->oxmSel;
805 //Load secret for temporal secure session.
806 if(otmCtx->otmCallback.loadSecretCB)
808 res = otmCtx->otmCallback.loadSecretCB(otmCtx);
809 if(OC_STACK_OK != res)
811 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
812 SetResult(otmCtx, res);
813 return OC_STACK_DELETE_TRANSACTION;
817 //Save the current context instance to use on the dtls handshake callback
818 if(OC_STACK_OK != AddOTMContext(otmCtx,
819 otmCtx->selectedDeviceInfo->endpoint.addr,
820 otmCtx->selectedDeviceInfo->securePort))
822 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List.");
823 SetResult(otmCtx, res);
824 return OC_STACK_DELETE_TRANSACTION;
827 //Try DTLS handshake to generate secure session
828 if(otmCtx->otmCallback.createSecureSessionCB)
830 res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
831 if(OC_STACK_OK != res)
833 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
834 SetResult(otmCtx, res);
835 return OC_STACK_DELETE_TRANSACTION;
841 OIC_LOG(ERROR, TAG, "Error while update operation mode");
842 SetResult(otmCtx, clientResponse->result);
845 OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
848 return OC_STACK_DELETE_TRANSACTION;
852 * Response handler for update owner crendetial request.
854 * @param[in] ctx ctx value passed to callback from calling function.
855 * @param[in] UNUSED handle to an invocation
856 * @param[in] clientResponse Response from queries to remote servers.
857 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
858 * and OC_STACK_KEEP_TRANSACTION to keep it.
860 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
861 OCClientResponse *clientResponse)
863 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
864 VERIFY_NON_NULL(TAG, ctx, WARNING);
866 OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
868 OCStackResult res = OC_STACK_OK;
869 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
870 otmCtx->ocDoHandle = NULL;
872 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
874 if(otmCtx && otmCtx->selectedDeviceInfo)
876 //Close the temporal secure session to verify the owner credential
877 CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
878 endpoint->port = otmCtx->selectedDeviceInfo->securePort;
879 CAResult_t caResult = CA_STATUS_OK;
880 caResult = CAcloseSslConnection(endpoint);
882 if(CA_STATUS_OK != caResult)
884 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
885 SetResult(otmCtx, caResult);
886 return OC_STACK_DELETE_TRANSACTION;
890 * If we select NULL cipher,
891 * client will select appropriate cipher suite according to server's cipher-suite list.
893 // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
894 caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
896 if(CA_STATUS_OK != caResult)
898 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
899 SetResult(otmCtx, caResult);
900 return OC_STACK_DELETE_TRANSACTION;
904 * in case of random PIN based OxM,
905 * revert get_psk_info callback of tinyDTLS to use owner credential.
907 if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
909 OicUuid_t emptyUuid = { .id={0}};
910 SetUuidForPinBasedOxm(&emptyUuid);
912 caResult = CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
914 if(CA_STATUS_OK != caResult)
916 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
917 SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
918 return OC_STACK_DELETE_TRANSACTION;
922 otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
924 res = PostOwnerAcl(otmCtx);
925 if(OC_STACK_OK != res)
927 OIC_LOG(ERROR, TAG, "Failed to update owner ACL to new device");
928 SetResult(otmCtx, res);
929 return OC_STACK_DELETE_TRANSACTION;
935 res = clientResponse->result;
936 OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
937 SetResult(otmCtx, res);
940 OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
943 return OC_STACK_DELETE_TRANSACTION;
947 * Response handler for update owner ACL request.
949 * @param[in] ctx ctx value passed to callback from calling function.
950 * @param[in] UNUSED handle to an invocation
951 * @param[in] clientResponse Response from queries to remote servers.
952 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
953 * and OC_STACK_KEEP_TRANSACTION to keep it.
955 static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle UNUSED,
956 OCClientResponse *clientResponse)
958 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
959 VERIFY_NON_NULL(TAG, ctx, WARNING);
961 OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler");
963 OCStackResult res = OC_STACK_OK;
964 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
965 otmCtx->ocDoHandle = NULL;
967 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
969 if(otmCtx && otmCtx->selectedDeviceInfo)
971 //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }]
972 res = PostOwnershipInformation(otmCtx);
973 if(OC_STACK_OK != res)
975 OIC_LOG(ERROR, TAG, "Failed to update ownership information to new device");
976 SetResult(otmCtx, res);
982 res = clientResponse->result;
983 OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res);
984 SetResult(otmCtx, res);
987 OIC_LOG(DEBUG, TAG, "OUT OwnerAclHandler");
990 return OC_STACK_DELETE_TRANSACTION;
995 * Response handler for update owner information request.
997 * @param[in] ctx ctx value passed to callback from calling function.
998 * @param[in] UNUSED handle to an invocation
999 * @param[in] clientResponse Response from queries to remote servers.
1000 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1001 * and OC_STACK_KEEP_TRANSACTION to keep it.
1003 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
1004 OCClientResponse *clientResponse)
1006 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
1007 VERIFY_NON_NULL(TAG, ctx, WARNING);
1009 OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
1011 OCStackResult res = OC_STACK_OK;
1012 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1013 otmCtx->ocDoHandle = NULL;
1015 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1017 if(otmCtx && otmCtx->selectedDeviceInfo)
1019 OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
1020 OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
1022 res = PostProvisioningStatus(otmCtx);
1023 if(OC_STACK_OK != res)
1025 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1026 SetResult(otmCtx, res);
1032 res = clientResponse->result;
1033 OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
1034 SetResult(otmCtx, res);
1037 OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
1040 return OC_STACK_DELETE_TRANSACTION;
1044 * Response handler of update provisioning status.
1046 * @param[in] ctx ctx value passed to callback from calling function.
1047 * @param[in] UNUSED handle to an invocation
1048 * @param[in] clientResponse Response from queries to remote servers.
1049 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1050 * and OC_STACK_KEEP_TRANSACTION to keep it.
1052 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
1053 OCClientResponse *clientResponse)
1055 OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
1057 VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1058 VERIFY_NON_NULL(TAG, ctx, ERROR);
1060 OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1061 otmCtx->ocDoHandle = NULL;
1063 OCStackResult res = OC_STACK_OK;
1065 if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1067 if(otmCtx && otmCtx->selectedDeviceInfo)
1069 OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
1071 res = PostNormalOperationStatus(otmCtx);
1072 if(OC_STACK_OK != res)
1074 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1075 SetResult(otmCtx, res);
1081 OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1082 clientResponse->result);
1083 SetResult(otmCtx, clientResponse->result);
1087 OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
1088 return OC_STACK_DELETE_TRANSACTION;
1092 * Response handler of update provisioning status to Ready for Normal..
1094 * @param[in] ctx ctx value passed to callback from calling function.
1095 * @param[in] UNUSED handle to an invocation
1096 * @param[in] clientResponse Response from queries to remote servers.
1097 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
1098 * and OC_STACK_KEEP_TRANSACTION to keep it.
1100 static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
1101 OCClientResponse *clientResponse)
1103 OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
1105 VERIFY_NON_NULL(TAG, clientResponse, ERROR);
1106 VERIFY_NON_NULL(TAG, ctx, ERROR);
1108 OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1109 otmCtx->ocDoHandle = NULL;
1112 if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1114 OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
1115 OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
1117 if (OC_STACK_OK == res)
1119 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1120 SetResult(otmCtx, OC_STACK_OK);
1121 return OC_STACK_DELETE_TRANSACTION;
1125 OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1130 OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1131 clientResponse->result);
1132 SetResult(otmCtx, clientResponse->result);
1136 OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
1137 return OC_STACK_DELETE_TRANSACTION;
1140 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx)
1142 OIC_LOG(DEBUG, TAG, "IN PostOwnerCredential");
1144 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1146 OIC_LOG(ERROR, TAG, "Invalid parameters");
1147 return OC_STACK_INVALID_PARAM;
1150 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1151 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1153 if(!PMGenerateQuery(true,
1154 deviceInfo->endpoint.addr, deviceInfo->securePort,
1155 deviceInfo->connType,
1156 query, sizeof(query), OIC_RSRC_CRED_URI))
1158 OIC_LOG(ERROR, TAG, "PostOwnerCredential : Failed to generate query");
1159 return OC_STACK_ERROR;
1161 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1162 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1165 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1166 return OC_STACK_NO_MEMORY;
1169 //Generate owner credential for new device
1170 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1171 const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
1172 if(!ownerCredential)
1174 OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
1175 return OC_STACK_NO_RESOURCE;
1178 OicUuid_t credSubjectId = {.id={0}};
1179 if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
1181 OicSecCred_t newCredential;
1182 memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
1183 newCredential.next = NULL;
1185 //Set subject ID as PT's ID
1186 memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
1188 //Fill private data as empty string
1189 newCredential.privateData.data = "";
1190 newCredential.privateData.len = 0;
1191 newCredential.privateData.encoding = ownerCredential->privateData.encoding;
1193 newCredential.publicData.data = NULL;
1194 newCredential.publicData.len = 0;
1197 //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
1198 if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
1199 &secPayload->payloadSize, secureFlag))
1201 OICFree(secPayload);
1202 OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1203 return OC_STACK_ERROR;
1205 OIC_LOG(DEBUG, TAG, "Cred Payload:");
1206 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1208 OCCallbackData cbData;
1209 cbData.cb = &OwnerCredentialHandler;
1210 cbData.context = (void *)otmCtx;
1212 OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1213 &deviceInfo->endpoint, (OCPayload*)secPayload,
1214 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1215 if (res != OC_STACK_OK)
1217 OIC_LOG(ERROR, TAG, "OCStack resource error");
1222 OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
1223 return OC_STACK_NO_RESOURCE;
1226 OIC_LOG(DEBUG, TAG, "OUT PostOwnerCredential");
1231 static OicSecAcl_t* GenerateOwnerAcl(const OicUuid_t* owner)
1233 OicSecAcl_t* ownerAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
1234 OicSecAce_t* ownerAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1235 OicSecRsrc_t* wildcardRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1236 if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1238 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1241 LL_APPEND(ownerAcl->aces, ownerAce);
1242 LL_APPEND(ownerAce->resources, wildcardRsrc);
1244 //Set resource owner as PT
1245 memcpy(ownerAcl->rownerID.id, owner->id, sizeof(owner->id));
1247 //PT has full permission.
1248 ownerAce->permission = PERMISSION_FULL_CONTROL;
1250 //Set subject as PT's UUID
1251 memcpy(ownerAce->subjectuuid.id, owner->id, sizeof(owner->id));
1253 wildcardRsrc->href = OICStrdup(WILDCARD_RESOURCE_URI);
1254 if(NULL == wildcardRsrc->href)
1259 wildcardRsrc->interfaceLen = 1;
1260 wildcardRsrc->interfaces = (char**)OICMalloc(wildcardRsrc->interfaceLen * sizeof(char*));
1261 if(NULL == wildcardRsrc->interfaces)
1265 wildcardRsrc->interfaces[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1266 if(NULL == wildcardRsrc->interfaces[0])
1271 wildcardRsrc->typeLen = 1;
1272 wildcardRsrc->types = (char**)OICMalloc(wildcardRsrc->typeLen * sizeof(char*));
1273 if(NULL == wildcardRsrc->types)
1277 wildcardRsrc->types[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1278 if(NULL == wildcardRsrc->types[0])
1286 //in case of memory allocation failed, each resource should be removed individually.
1287 if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1291 OICFree(wildcardRsrc);
1295 DeleteACLList(ownerAcl);
1301 * Function to update the owner ACL to new device.
1303 * @param[in] otmCtx Context value of ownership transfer.
1304 * @return OC_STACK_OK on success
1306 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx)
1308 OCStackResult res = OC_STACK_ERROR;
1310 OIC_LOG(DEBUG, TAG, "IN PostOwnerAcl");
1312 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1314 OIC_LOG(ERROR, TAG, "Invalid parameters");
1315 return OC_STACK_INVALID_PARAM;
1318 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1319 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1320 OicSecAcl_t* ownerAcl = NULL;
1322 if(!PMGenerateQuery(true,
1323 deviceInfo->endpoint.addr, deviceInfo->securePort,
1324 deviceInfo->connType,
1325 query, sizeof(query), OIC_RSRC_ACL_URI))
1327 OIC_LOG(ERROR, TAG, "Failed to generate query");
1328 return OC_STACK_ERROR;
1330 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1333 res = GetDoxmDeviceID(&ownerID);
1334 if(OC_STACK_OK != res)
1336 OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1340 //Generate owner ACL for new device
1341 ownerAcl = GenerateOwnerAcl(&ownerID);
1342 if(NULL == ownerAcl)
1344 OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1345 return OC_STACK_NO_MEMORY;
1348 //Generate ACL payload
1349 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1352 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1353 res = OC_STACK_NO_MEMORY;
1357 res = AclToCBORPayload(ownerAcl, &secPayload->securityData, &secPayload->payloadSize);
1358 if (OC_STACK_OK != res)
1360 OICFree(secPayload);
1361 OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1364 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1366 OIC_LOG(DEBUG, TAG, "Owner ACL Payload:");
1367 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1369 //Send owner ACL to new device : POST /oic/sec/cred [ owner credential ]
1370 OCCallbackData cbData;
1371 cbData.cb = &OwnerAclHandler;
1372 cbData.context = (void *)otmCtx;
1374 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1375 &deviceInfo->endpoint, (OCPayload*)secPayload,
1376 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1377 if (res != OC_STACK_OK)
1379 OIC_LOG(ERROR, TAG, "OCStack resource error");
1383 OIC_LOG(DEBUG, TAG, "OUT PostOwnerAcl");
1386 DeleteACLList(ownerAcl);
1391 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx)
1393 OIC_LOG(DEBUG, TAG, "IN PostOwnerTransferModeToResource");
1395 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1397 OIC_LOG(ERROR, TAG, "Invalid parameters");
1398 return OC_STACK_INVALID_PARAM;
1401 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1402 OicSecOxm_t selectedOxm = deviceInfo->doxm->oxmSel;
1403 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1405 if(!PMGenerateQuery(false,
1406 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1407 deviceInfo->connType,
1408 query, sizeof(query), OIC_RSRC_DOXM_URI))
1410 OIC_LOG(ERROR, TAG, "PostOwnerTransferModeToResource : Failed to generate query");
1411 return OC_STACK_ERROR;
1413 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1415 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1418 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1419 return OC_STACK_NO_MEMORY;
1422 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1423 OCStackResult res = otmCtx->otmCallback.createSelectOxmPayloadCB(otmCtx,
1424 &secPayload->securityData, &secPayload->payloadSize);
1425 if (OC_STACK_OK != res && NULL == secPayload->securityData)
1427 OCPayloadDestroy((OCPayload *)secPayload);
1428 OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
1429 return OC_STACK_ERROR;
1432 OCCallbackData cbData;
1433 cbData.cb = &OwnerTransferModeHandler;
1434 cbData.context = (void *)otmCtx;
1436 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1437 &deviceInfo->endpoint, (OCPayload *)secPayload,
1438 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1439 if (res != OC_STACK_OK)
1441 OIC_LOG(ERROR, TAG, "OCStack resource error");
1444 OIC_LOG(DEBUG, TAG, "OUT PostOwnerTransferModeToResource");
1449 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1451 OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1453 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1455 OIC_LOG(ERROR, TAG, "Invailed parameters");
1456 return OC_STACK_INVALID_PARAM;
1459 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1460 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1461 if(!PMGenerateQuery(false,
1462 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1463 deviceInfo->connType,
1464 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1466 OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1467 return OC_STACK_ERROR;
1469 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1471 OCCallbackData cbData;
1472 cbData.cb = &ListMethodsHandler;
1473 cbData.context = (void *)otmCtx;
1475 OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
1476 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1477 if (res != OC_STACK_OK)
1479 OIC_LOG(ERROR, TAG, "OCStack resource error");
1482 OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1487 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
1489 OIC_LOG(DEBUG, TAG, "IN PostOwnerUuid");
1491 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1493 OIC_LOG(ERROR, TAG, "Invailed parameters");
1494 return OC_STACK_INVALID_PARAM;
1497 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1498 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1499 if(!PMGenerateQuery(true,
1500 deviceInfo->endpoint.addr, deviceInfo->securePort,
1501 deviceInfo->connType,
1502 query, sizeof(query), OIC_RSRC_DOXM_URI))
1504 OIC_LOG(ERROR, TAG, "PostOwnerUuid : Failed to generate query");
1505 return OC_STACK_ERROR;
1507 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1509 //Post PT's uuid to new device
1510 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1513 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1514 return OC_STACK_NO_MEMORY;
1516 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1517 OCStackResult res = otmCtx->otmCallback.createOwnerTransferPayloadCB(
1518 otmCtx, &secPayload->securityData, &secPayload->payloadSize);
1519 if (OC_STACK_OK != res && NULL == secPayload->securityData)
1521 OCPayloadDestroy((OCPayload *)secPayload);
1522 OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
1523 return OC_STACK_INVALID_PARAM;
1525 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1527 OCCallbackData cbData;
1528 cbData.cb = &OwnerUuidUpdateHandler;
1529 cbData.context = (void *)otmCtx;
1532 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1533 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1534 if (res != OC_STACK_OK)
1536 OIC_LOG(ERROR, TAG, "OCStack resource error");
1539 OIC_LOG(DEBUG, TAG, "OUT PostOwnerUuid");
1544 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
1546 OIC_LOG(DEBUG, TAG, "IN PostOwnershipInformation");
1548 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1550 OIC_LOG(ERROR, TAG, "Invailed parameters");
1551 return OC_STACK_INVALID_PARAM;
1554 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1555 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1556 if(!PMGenerateQuery(true,
1557 deviceInfo->endpoint.addr, deviceInfo->securePort,
1558 deviceInfo->connType,
1559 query, sizeof(query), OIC_RSRC_DOXM_URI))
1561 OIC_LOG(ERROR, TAG, "PostOwnershipInformation : Failed to generate query");
1562 return OC_STACK_ERROR;
1564 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1566 //OwnershipInformationHandler
1567 OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1570 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1571 return OC_STACK_NO_MEMORY;
1574 otmCtx->selectedDeviceInfo->doxm->owned = true;
1576 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1577 OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
1578 &secPayload->securityData, &secPayload->payloadSize, true);
1579 if (OC_STACK_OK != res && NULL == secPayload->securityData)
1581 OCPayloadDestroy((OCPayload *)secPayload);
1582 OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1583 return OC_STACK_INVALID_PARAM;
1586 OCCallbackData cbData;
1587 cbData.cb = &OwnershipInformationHandler;
1588 cbData.context = (void *)otmCtx;
1591 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
1592 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1593 if (res != OC_STACK_OK)
1595 OIC_LOG(ERROR, TAG, "OCStack resource error");
1598 OIC_LOG(DEBUG, TAG, "OUT PostOwnershipInformation");
1603 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
1605 OIC_LOG(DEBUG, TAG, "IN PostUpdateOperationMode");
1607 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1609 return OC_STACK_INVALID_PARAM;
1612 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1613 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1614 if(!PMGenerateQuery(false,
1615 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1616 deviceInfo->connType,
1617 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1619 OIC_LOG(ERROR, TAG, "PostUpdateOperationMode : Failed to generate query");
1620 return OC_STACK_ERROR;
1622 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1624 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1627 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1628 return OC_STACK_NO_MEMORY;
1630 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1631 OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
1632 &secPayload->payloadSize, true);
1633 if (OC_STACK_OK != res)
1635 OCPayloadDestroy((OCPayload *)secPayload);
1636 OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
1637 return OC_STACK_INVALID_PARAM;
1640 OCCallbackData cbData;
1641 cbData.cb = &OperationModeUpdateHandler;
1642 cbData.context = (void *)otmCtx;
1644 res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1645 deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1646 if (res != OC_STACK_OK)
1648 OIC_LOG(ERROR, TAG, "OCStack resource error");
1651 OIC_LOG(DEBUG, TAG, "OUT PostUpdateOperationMode");
1656 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
1658 OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
1659 OCStackResult res = OC_STACK_INVALID_PARAM;
1661 VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
1662 VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
1664 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1665 otmCtx->selectedDeviceInfo = selectedDevice;
1667 //Checking duplication of Device ID.
1668 bool isDuplicate = true;
1669 res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
1670 if (OC_STACK_OK != res)
1672 OIC_LOG(ERROR, TAG, "Internal error in PDMIsDuplicateDevice");
1677 PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
1678 res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &state);
1679 if(OC_STACK_OK != res)
1681 OIC_LOG(ERROR, TAG, "Internal error in PDMGetDeviceState");
1682 SetResult(otmCtx, res);
1686 char* strUuid = NULL;
1687 res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
1688 if(OC_STACK_OK != res)
1690 OIC_LOG(ERROR, TAG, "Failed to convert UUID to str");
1691 SetResult(otmCtx, res);
1695 if(PDM_DEVICE_STALE == state)
1697 OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
1698 "this UUID will be removed from PDM");
1700 res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
1701 if(OC_STACK_OK != res)
1703 OIC_LOG(ERROR, TAG, "Internal error in PDMDeleteDevice");
1705 SetResult(otmCtx, res);
1709 else if(PDM_DEVICE_INIT == state)
1711 OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
1713 SetResult(otmCtx, OC_STACK_DUPLICATE_REQUEST);
1718 OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
1720 SetResult(otmCtx, OC_STACK_ERROR);
1721 return OC_STACK_ERROR;
1726 res = PDMAddDevice(&selectedDevice->doxm->deviceID);
1727 if(OC_STACK_OK != res)
1729 OIC_LOG(ERROR, TAG, "Internal error in PDMAddDevice");
1730 SetResult(otmCtx, res);
1736 //Set to the lowest level OxM, and then find more higher level OxM.
1737 res = SelectProvisioningMethod(selectedDevice->doxm->oxm,
1738 selectedDevice->doxm->oxmLen,
1739 &selectedDevice->doxm->oxmSel);
1740 if(OC_STACK_OK != res)
1742 OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
1743 SetResult(otmCtx, res);
1746 OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
1748 res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
1749 if(OC_STACK_OK != res)
1751 OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
1755 //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
1756 res = PostOwnerTransferModeToResource(otmCtx);
1757 if(OC_STACK_OK != res)
1759 OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
1760 SetResult(otmCtx, res);
1764 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1765 //Register TLS event handler to catch the tls event while handshake
1766 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
1768 OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
1770 #endif // __WITH_DTLS__ or __WITH_TLS__
1771 OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
1777 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
1779 OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
1783 OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
1784 return OC_STACK_INVALID_PARAM;
1786 if(oxmType >= OIC_OXM_COUNT)
1788 OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
1789 return OC_STACK_INVALID_PARAM;
1792 // TODO: Remove this API, Please see the jira ticket IOT-1484
1794 OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
1800 * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
1802 OCStackResult OTMDoOwnershipTransfer(void* ctx,
1803 OCProvisionDev_t *selectedDevicelist,
1804 OCProvisionResultCB resultCallback)
1806 OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
1808 if (NULL == selectedDevicelist)
1810 return OC_STACK_INVALID_PARAM;
1812 if (NULL == resultCallback)
1814 return OC_STACK_INVALID_CALLBACK;
1817 OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
1820 OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
1821 return OC_STACK_NO_MEMORY;
1823 otmCtx->ctxResultCallback = resultCallback;
1824 otmCtx->ctxHasError = false;
1825 otmCtx->userCtx = ctx;
1826 OCProvisionDev_t* pCurDev = selectedDevicelist;
1828 //Counting number of selected devices.
1829 otmCtx->ctxResultArraySize = 0;
1830 while(NULL != pCurDev)
1832 otmCtx->ctxResultArraySize++;
1833 pCurDev = pCurDev->next;
1836 otmCtx->ctxResultArray =
1837 (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
1838 if(NULL == otmCtx->ctxResultArray)
1840 OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
1842 return OC_STACK_NO_MEMORY;
1844 pCurDev = selectedDevicelist;
1846 OCStackResult res = OC_STACK_OK;
1847 //Fill the device UUID for result array.
1848 for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
1850 memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
1851 pCurDev->doxm->deviceID.id,
1853 otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
1854 pCurDev = pCurDev->next;
1857 StartOwnershipTransfer(otmCtx, selectedDevicelist);
1859 OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
1863 OICFree(otmCtx->ctxResultArray);
1868 OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
1870 OIC_LOG(INFO, TAG, "IN PostProvisioningStatus");
1872 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1874 OIC_LOG(ERROR, TAG, "OTMContext is NULL");
1875 return OC_STACK_INVALID_PARAM;
1878 //Change the TAKE_OWNER bit of CM to 0.
1879 otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
1881 OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
1884 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1885 return OC_STACK_NO_MEMORY;
1887 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1888 if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
1889 &secPayload->securityData, &secPayload->payloadSize, true))
1891 OCPayloadDestroy((OCPayload *)secPayload);
1892 return OC_STACK_INVALID_JSON;
1894 OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
1895 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1897 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1898 if(!PMGenerateQuery(true,
1899 otmCtx->selectedDeviceInfo->endpoint.addr,
1900 otmCtx->selectedDeviceInfo->securePort,
1901 otmCtx->selectedDeviceInfo->connType,
1902 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1904 OIC_LOG(ERROR, TAG, "PostProvisioningStatus : Failed to generate query");
1905 return OC_STACK_ERROR;
1907 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1909 OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1910 cbData.cb = &ProvisioningStatusHandler;
1911 cbData.context = (void*)otmCtx;
1913 OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
1914 otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1915 OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
1916 if (ret != OC_STACK_OK)
1918 OIC_LOG(ERROR, TAG, "OCStack resource error");
1921 OIC_LOG(INFO, TAG, "OUT PostProvisioningStatus");
1926 OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
1928 OIC_LOG(INFO, TAG, "IN PostNormalOperationStatus");
1930 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1932 OIC_LOG(ERROR, TAG, "OTMContext is NULL");
1933 return OC_STACK_INVALID_PARAM;
1937 otmCtx->selectedDeviceInfo->pstat->isOp = true;
1939 OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
1942 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1943 return OC_STACK_NO_MEMORY;
1945 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1946 if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
1947 &secPayload->securityData, &secPayload->payloadSize, true))
1949 OCPayloadDestroy((OCPayload *)secPayload);
1950 return OC_STACK_INVALID_JSON;
1952 OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
1953 OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1955 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1956 if(!PMGenerateQuery(true,
1957 otmCtx->selectedDeviceInfo->endpoint.addr,
1958 otmCtx->selectedDeviceInfo->securePort,
1959 otmCtx->selectedDeviceInfo->connType,
1960 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1962 OIC_LOG(ERROR, TAG, "PostNormalOperationStatus : Failed to generate query");
1963 return OC_STACK_ERROR;
1965 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1967 OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1968 cbData.cb = &ReadyForNomalStatusHandler;
1969 cbData.context = (void*)otmCtx;
1971 OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
1972 otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1973 OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
1974 if (ret != OC_STACK_OK)
1976 OIC_LOG(ERROR, TAG, "OCStack resource error");
1979 OIC_LOG(INFO, TAG, "OUT PostNormalOperationStatus");