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
40 #include "oic_malloc.h"
41 #include "oic_string.h"
43 #include "cainterface.h"
48 #include "srmresourcestrings.h"
49 #include "doxmresource.h"
50 #include "pstatresource.h"
51 #include "credresource.h"
52 #include "aclresource.h"
53 #include "ownershiptransfermanager.h"
54 #include "securevirtualresourcetypes.h"
55 #include "oxmjustworks.h"
57 #include "pmutility.h"
58 #include "srmutility.h"
59 #include "provisioningdatabasemanager.h"
60 #include "oxmrandompin.h"
65 * Array to store the callbacks for each owner transfer method.
67 static OTMCallbackData_t g_OTMDatas[OIC_OXM_COUNT];
70 * Variable for storing provisioning tool's provisioning capabilities
71 * Must be in decreasing order of preference. More prefered method should
72 * have lower array index.
74 static OicSecDpom_t gProvisioningToolCapability[] = { SINGLE_SERVICE_CLIENT_DRIVEN };
77 * Number of supported provisioning methods
78 * current version supports only one.
80 static size_t gNumOfProvisioningMethodsPT = 1;
83 * Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
85 static OTMContext_t* g_otmCtx = NULL;
88 * Function to select appropriate provisioning method.
90 * @param[in] supportedMethods Array of supported methods
91 * @param[in] numberOfMethods number of supported methods
92 * @param[out] selectedMethod Selected methods
93 * @return OC_STACK_OK on success
95 static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
96 size_t numberOfMethods,
97 OicSecOxm_t *selectedMethod)
99 OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
101 if(numberOfMethods == 0 || !supportedMethods)
103 OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
104 return OC_STACK_ERROR;
107 *selectedMethod = supportedMethods[0];
108 for(size_t i = 0; i < numberOfMethods; i++)
110 if(*selectedMethod < supportedMethods[i])
112 *selectedMethod = supportedMethods[i];
120 * Function to select operation mode.This function will return most secure common operation mode.
122 * @param[in] selectedDeviceInfo selected device information to performing provisioning.
123 * @param[out] selectedMode selected operation mode
124 * @return OC_STACK_OK on success
126 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
127 OicSecDpom_t *selectedMode)
129 OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
134 while (i < gNumOfProvisioningMethodsPT && j < selectedDeviceInfo->pstat->smLen)
136 if (gProvisioningToolCapability[i] < selectedDeviceInfo->pstat->sm[j])
140 else if (selectedDeviceInfo->pstat->sm[j] < gProvisioningToolCapability[i])
144 else /* if gProvisioningToolCapability[i] == deviceSupportedMethods[j] */
146 *selectedMode = gProvisioningToolCapability[j];
150 OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
152 OIC_LOG(DEBUG, TAG, "OUT SelectOperationMode");
156 * Function to start ownership transfer.
157 * This function will send the first request for provisioning,
158 * The next request message is sent from the response handler for this request.
160 * @param[in] ctx context value passed to callback from calling function.
161 * @param[in] selectedDevice selected device information to performing provisioning.
162 * @return OC_STACK_OK on success
164 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
167 * Function to update owner transfer mode
169 * @param[in] otmCtx Context value of ownership transfer.
170 * @return OC_STACK_OK on success
172 static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx);
175 * Function to send request to resource to get its pstat resource information.
177 * @param[in] otmCtx Context value of ownership transfer.
178 * @return OC_STACK_OK on success
180 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
184 * Function to send uuid of owner device to new device.
185 * This function would update 'owner of doxm' as UUID for provisioning tool.
187 * @param[in] otmCtx Context value of ownership transfer.
188 * @return OC_STACK_OK on success
190 static OCStackResult PutOwnerUuid(OTMContext_t* otmCtx);
193 * Function to update the operation mode. As per the spec. Operation mode in client driven
194 * single service provisioning it will be updated to 0x3
196 * @param[in] otmCtx Context value of ownership transfer.
197 * @return OC_STACK_OK on success
199 static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx);
202 * Function to update the owner credential to new device
204 * @param[in] otmCtx Context value of ownership transfer.
205 * @param[in] selectedOperationMode selected operation mode
206 * @return OC_STACK_OK on success
208 static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx);
211 * Function to send ownerShip info.
212 * This function would update 'owned of doxm' as true.
214 * @param[in] otmCtx Context value of ownership transfer.
215 * @return OC_STACK_OK on success
217 static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx);
220 * Function to update pstat when finalize provisioning.
221 * This function would update 'cm' as bx0011,1100 and 'tm' as bx0000,0000.
223 * @param[in] ctx context value passed to callback from calling function.
224 * @param[in] selectedDevice selected device information to performing provisioning.
225 * @return OC_STACK_OK on success
227 static OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx);
230 * Function to finalize provisioning.
231 * This function will send default ACL and commit hash.
233 * @param[in] otmCtx Context value of ownership transfer.
234 * @return OC_STACK_OK on success
236 static OCStackResult FinalizeProvisioning(OTMContext_t* otmCtx);
239 static bool IsComplete(OTMContext_t* otmCtx)
241 for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
243 if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
253 * Function to save the result of provisioning.
255 * @param[in,out] otmCtx Context value of ownership transfer.
256 * @param[in] res result of provisioning
258 static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
260 OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
264 OIC_LOG(WARNING, TAG, "OTMContext is NULL");
268 if(otmCtx->selectedDeviceInfo)
270 //Revert psk_info callback and new deivce uuid in case of random PIN OxM
271 if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
273 if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
275 OIC_LOG(WARNING, TAG, "Failed to revert is DTLS credential handler.");
277 OicUuid_t emptyUuid = { .id={0}};
278 SetUuidForRandomPinOxm(&emptyUuid);
281 for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
283 if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
284 otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
286 otmCtx->ctxResultArray[i].res = res;
287 if(OC_STACK_OK != res)
289 otmCtx->ctxHasError = true;
296 //If all request is completed, invoke the user callback.
297 if(IsComplete(otmCtx))
299 otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
300 otmCtx->ctxResultArray, otmCtx->ctxHasError);
301 OICFree(otmCtx->ctxResultArray);
306 if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
307 otmCtx->selectedDeviceInfo->next))
309 OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
314 OIC_LOG(DEBUG, TAG, "OUT SetResult");
318 * Function to handle the handshake result in OTM.
319 * This function will be invoked after DTLS handshake
320 * @param endPoint [IN] The remote endpoint.
321 * @param errorInfo [IN] Error information from the endpoint.
324 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
326 if(g_otmCtx && endpoint && info)
328 OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
329 endpoint->addr, endpoint->port, info->result);
331 //Make sure the address matches.
332 if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr,
334 sizeof(endpoint->addr)) == 0 &&
335 g_otmCtx->selectedDeviceInfo->securePort == endpoint->port)
337 OCStackResult res = OC_STACK_ERROR;
339 //In case of success, send next coaps request.
340 if(CA_STATUS_OK == info->result)
342 //Send request : PUT /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
343 res = PutOwnerUuid(g_otmCtx);
344 if(OC_STACK_OK != res)
346 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
347 SetResult(g_otmCtx, res);
350 //In case of failure, re-start the ownership transfer in case of PIN OxM
351 else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
353 g_otmCtx->selectedDeviceInfo->doxm->owned = false;
354 g_otmCtx->attemptCnt++;
356 if(g_otmCtx->selectedDeviceInfo->doxm->oxmSel == OIC_RANDOM_DEVICE_PIN)
359 res = RemoveCredential(&g_otmCtx->subIdForPinOxm);
360 if(OC_STACK_RESOURCE_DELETED != res)
362 OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
363 SetResult(g_otmCtx, res);
367 if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt)
369 res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo);
370 if(OC_STACK_OK != res)
372 SetResult(g_otmCtx, res);
373 OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
378 SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
383 SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
391 * Function to save ownerPSK at provisioning tool end.
393 * @param[in] selectedDeviceInfo selected device information to performing provisioning.
394 * @return OC_STACK_OK on success
396 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
398 OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
400 OCStackResult res = OC_STACK_ERROR;
402 CAEndpoint_t endpoint;
403 memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
404 OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
405 endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
406 endpoint.port = selectedDeviceInfo->securePort;
408 OicUuid_t ptDeviceID = {.id={0}};
409 if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
411 OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
415 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
417 //Generating OwnerPSK
418 CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
419 (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
420 strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
421 ptDeviceID.id, sizeof(ptDeviceID.id),
422 selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
423 ownerPSK, OWNER_PSK_LENGTH_128);
425 if (CA_STATUS_OK == pskRet)
427 OIC_LOG(INFO, TAG,"ownerPSK dump:\n");
428 OIC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
429 //Generating new credential for provisioning tool
433 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
434 B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff),
436 VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
438 OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
439 SYMMETRIC_PAIR_WISE_KEY, NULL,
440 base64Buff, ownLen, &ptDeviceID);
441 VERIFY_NON_NULL(TAG, cred, ERROR);
443 res = AddCredential(cred);
444 if(res != OC_STACK_OK)
446 DeleteCredList(cred);
452 OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
455 OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
461 * Callback handler for OwnerShipTransferModeHandler API.
463 * @param[in] ctx ctx value passed to callback from calling function.
464 * @param[in] UNUSED handle to an invocation
465 * @param[in] clientResponse Response from queries to remote servers.
466 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
467 * and OC_STACK_KEEP_TRANSACTION to keep it.
469 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
470 OCClientResponse *clientResponse)
472 OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
474 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
475 VERIFY_NON_NULL(TAG, ctx, WARNING);
477 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
479 if(clientResponse->result == OC_STACK_OK)
481 OIC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
482 //Send request : GET /oic/sec/pstat
483 OCStackResult res = GetProvisioningStatusResource(otmCtx);
484 if(OC_STACK_OK != res)
486 OIC_LOG(WARNING, TAG, "Failed to get pstat information");
487 SetResult(otmCtx, res);
492 OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
493 clientResponse->result);
494 SetResult(otmCtx, clientResponse->result);
497 OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
500 return OC_STACK_DELETE_TRANSACTION;
504 * Callback handler for ProvisioningStatusResouceHandler API.
506 * @param[in] ctx ctx value passed to callback from calling function.
507 * @param[in] UNUSED handle to an invocation
508 * @param[in] clientResponse Response from queries to remote servers.
509 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
510 * and OC_STACK_KEEP_TRANSACTION to keep it.
512 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
513 OCClientResponse *clientResponse)
515 OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
517 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
518 VERIFY_NON_NULL(TAG, ctx, WARNING);
520 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
522 if (OC_STACK_OK == clientResponse->result)
524 if (NULL == clientResponse->payload)
526 OIC_LOG(INFO, TAG, "Skiping Null payload");
527 SetResult(otmCtx, OC_STACK_ERROR);
528 return OC_STACK_DELETE_TRANSACTION;
531 if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
533 OIC_LOG(INFO, TAG, "Unknown payload type");
534 SetResult(otmCtx, OC_STACK_ERROR);
535 return OC_STACK_DELETE_TRANSACTION;
538 OicSecPstat_t* pstat = JSONToPstatBin(
539 ((OCSecurityPayload*)clientResponse->payload)->securityData);
542 OIC_LOG(ERROR, TAG, "Error while converting json to pstat bin");
543 SetResult(otmCtx, OC_STACK_ERROR);
544 return OC_STACK_DELETE_TRANSACTION;
546 otmCtx->selectedDeviceInfo->pstat = pstat;
548 //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
549 SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
551 //Send request : PUT /oic/sec/pstat [{"om":"bx11", .. }]
552 OCStackResult res = PutUpdateOperationMode(otmCtx);
553 if (OC_STACK_OK != res)
555 OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
556 SetResult(otmCtx, res);
561 OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
562 clientResponse->result);
563 SetResult(otmCtx, clientResponse->result);
566 OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
568 return OC_STACK_DELETE_TRANSACTION;
572 * Response handler for update owner uuid request.
574 * @param[in] ctx ctx value passed to callback from calling function.
575 * @param[in] UNUSED handle to an invocation
576 * @param[in] clientResponse Response from queries to remote servers.
577 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
578 * and OC_STACK_KEEP_TRANSACTION to keep it.
580 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
581 OCClientResponse *clientResponse)
583 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
584 VERIFY_NON_NULL(TAG, ctx, WARNING);
586 OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
588 OCStackResult res = OC_STACK_OK;
589 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
591 if(OC_STACK_OK == clientResponse->result)
593 if(otmCtx && otmCtx->selectedDeviceInfo)
595 res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
596 if(OC_STACK_OK != res)
598 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
599 SetResult(otmCtx, res);
600 return OC_STACK_DELETE_TRANSACTION;
603 //PUT owner credential to new device according to security spec B.
604 res = PutOwnerCredential(otmCtx);
605 if(OC_STACK_OK != res)
608 "OwnerUuidUpdateHandler:Failed to send PUT request for onwer credential");
609 SetResult(otmCtx, res);
610 return OC_STACK_DELETE_TRANSACTION;
616 res = clientResponse->result;
617 OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
618 SetResult(otmCtx, res);
621 OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
624 return OC_STACK_DELETE_TRANSACTION;
628 * Response handler for update operation mode.
630 * @param[in] ctx ctx value passed to callback from calling function.
631 * @param[in] UNUSED handle to an invocation
632 * @param[in] clientResponse Response from queries to remote servers.
633 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
634 * and OC_STACK_KEEP_TRANSACTION to keep it.
636 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
637 OCClientResponse *clientResponse)
639 OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
641 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
642 VERIFY_NON_NULL(TAG, ctx, WARNING);
644 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
646 if (OC_STACK_OK == clientResponse->result)
648 OCStackResult res = OC_STACK_ERROR;
649 OicSecOxm_t selOxm = otmCtx->selectedDeviceInfo->doxm->oxmSel;
651 //Load secret for temporal secure session.
652 if(g_OTMDatas[selOxm].loadSecretCB)
654 res = g_OTMDatas[selOxm].loadSecretCB(otmCtx);
655 if(OC_STACK_OK != res)
657 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
658 SetResult(otmCtx, res);
659 return OC_STACK_DELETE_TRANSACTION;
663 //It will be used in handshake event handler
666 //Try DTLS handshake to generate secure session
667 if(g_OTMDatas[selOxm].createSecureSessionCB)
669 res = g_OTMDatas[selOxm].createSecureSessionCB(otmCtx);
670 if(OC_STACK_OK != res)
672 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
673 SetResult(otmCtx, res);
674 return OC_STACK_DELETE_TRANSACTION;
680 OIC_LOG(ERROR, TAG, "Error while update operation mode");
681 SetResult(otmCtx, clientResponse->result);
684 OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
687 return OC_STACK_DELETE_TRANSACTION;
691 * Response handler for update owner crendetial request.
693 * @param[in] ctx ctx value passed to callback from calling function.
694 * @param[in] UNUSED handle to an invocation
695 * @param[in] clientResponse Response from queries to remote servers.
696 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
697 * and OC_STACK_KEEP_TRANSACTION to keep it.
699 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
700 OCClientResponse *clientResponse)
702 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
703 VERIFY_NON_NULL(TAG, ctx, WARNING);
705 OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
707 OCStackResult res = OC_STACK_OK;
708 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
710 if(OC_STACK_RESOURCE_CREATED == clientResponse->result)
712 if(otmCtx && otmCtx->selectedDeviceInfo)
714 //PUT /oic/sec/doxm [{ ..., "owned":"TRUE" }]
715 res = PutOwnershipInformation(otmCtx);
716 if(OC_STACK_OK != res)
718 OIC_LOG(ERROR, TAG, "Failed to put ownership information to new device");
719 SetResult(otmCtx, res);
720 return OC_STACK_DELETE_TRANSACTION;
726 res = clientResponse->result;
727 OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
728 SetResult(otmCtx, res);
731 OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
734 return OC_STACK_DELETE_TRANSACTION;
739 * Response handler for update owner information request.
741 * @param[in] ctx ctx value passed to callback from calling function.
742 * @param[in] UNUSED handle to an invocation
743 * @param[in] clientResponse Response from queries to remote servers.
744 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
745 * and OC_STACK_KEEP_TRANSACTION to keep it.
747 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
748 OCClientResponse *clientResponse)
750 VERIFY_NON_NULL(TAG, clientResponse, WARNING);
751 VERIFY_NON_NULL(TAG, ctx, WARNING);
753 OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
755 OCStackResult res = OC_STACK_OK;
756 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
758 if(OC_STACK_OK == clientResponse->result)
760 if(otmCtx && otmCtx->selectedDeviceInfo)
762 OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
763 OIC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
765 res = PutProvisioningStatus(otmCtx);
766 if(OC_STACK_OK != res)
768 OIC_LOG(ERROR, TAG, "Failed to update pstat");
769 SetResult(otmCtx, res);
775 res = clientResponse->result;
776 OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
777 SetResult(otmCtx, res);
780 OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
783 return OC_STACK_DELETE_TRANSACTION;
787 * Response handler of update provisioning status.
789 * @param[in] ctx ctx value passed to callback from calling function.
790 * @param[in] UNUSED handle to an invocation
791 * @param[in] clientResponse Response from queries to remote servers.
792 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
793 * and OC_STACK_KEEP_TRANSACTION to keep it.
795 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
796 OCClientResponse *clientResponse)
798 OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
800 VERIFY_NON_NULL(TAG, clientResponse, ERROR);
801 VERIFY_NON_NULL(TAG, ctx, ERROR);
803 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
805 if(OC_STACK_OK == clientResponse->result)
807 OCStackResult res = FinalizeProvisioning(otmCtx);
808 if (OC_STACK_OK != res)
810 OIC_LOG_V(INFO, TAG, "Failed to finalize provisioning.");
811 SetResult(otmCtx, res);
812 return OC_STACK_DELETE_TRANSACTION;
817 OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
818 return OC_STACK_DELETE_TRANSACTION;
822 * Callback handler of finalize provisioning.
824 * @param[in] ctx ctx value passed to callback from calling function.
825 * @param[in] UNUSED handle to an invocation
826 * @param[in] clientResponse Response from queries to remote servers.
827 * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
828 * and OC_STACK_KEEP_TRANSACTION to keep it.
830 static OCStackApplicationResult FinalizeProvisioningCB(void *ctx, OCDoHandle UNUSED,
831 OCClientResponse *clientResponse)
833 OIC_LOG_V(INFO, TAG, "IN ProvisionDefaultACLCB.");
835 VERIFY_NON_NULL(TAG, clientResponse, ERROR);
836 VERIFY_NON_NULL(TAG, ctx, ERROR);
838 OTMContext_t* otmCtx = (OTMContext_t*) ctx;
841 if (OC_STACK_RESOURCE_CREATED == clientResponse->result)
843 OCStackResult res = PDMAddDevice(&otmCtx->selectedDeviceInfo->doxm->deviceID);
844 if (OC_STACK_OK == res)
846 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
847 SetResult(otmCtx, OC_STACK_OK);
848 return OC_STACK_DELETE_TRANSACTION;
852 OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
857 OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
858 clientResponse->result);
859 SetResult(otmCtx, clientResponse->result);
862 return OC_STACK_DELETE_TRANSACTION;
865 static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx)
867 OIC_LOG(DEBUG, TAG, "IN PutOwnerCredential");
869 if(!otmCtx || !otmCtx->selectedDeviceInfo)
871 OIC_LOG(ERROR, TAG, "Invalid parameters");
872 return OC_STACK_INVALID_PARAM;
875 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
876 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
878 if(!PMGenerateQuery(true,
879 deviceInfo->endpoint.addr, deviceInfo->securePort,
880 deviceInfo->connType,
881 query, sizeof(query), OIC_RSRC_CRED_URI))
883 OIC_LOG(ERROR, TAG, "PutOwnerCredential : Failed to generate query");
884 return OC_STACK_ERROR;
886 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
887 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
890 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
891 return OC_STACK_NO_MEMORY;
894 //Generate owner credential for new device
895 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
896 OicSecCred_t* ownerCredential =
897 GetCredResourceData(&(deviceInfo->doxm->deviceID));
900 OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
901 return OC_STACK_NO_RESOURCE;
904 OicUuid_t credSubjectId = {.id={0}};
905 if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
907 OicSecCred_t newCredential;
908 memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
909 newCredential.next = NULL;
910 memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
912 //Send owner credential to new device : PUT /oic/sec/cred [ owner credential ]
913 secPayload->securityData = BinToCredJSON(&newCredential);
914 if (NULL == secPayload->securityData)
917 OIC_LOG(ERROR, TAG, "Error while converting bin to json");
918 return OC_STACK_ERROR;
920 OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData);
922 OCCallbackData cbData;
923 cbData.cb = &OwnerCredentialHandler;
924 cbData.context = (void *)otmCtx;
926 OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query,
927 &deviceInfo->endpoint, (OCPayload*)secPayload,
928 deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
929 if (res != OC_STACK_OK)
931 OIC_LOG(ERROR, TAG, "OCStack resource error");
936 OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
937 return OC_STACK_NO_RESOURCE;
940 OIC_LOG(DEBUG, TAG, "OUT PutOwnerCredential");
945 static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx)
947 OIC_LOG(DEBUG, TAG, "IN PutOwnerTransferModeToResource");
949 if(!otmCtx || !otmCtx->selectedDeviceInfo)
951 OIC_LOG(ERROR, TAG, "Invalid parameters");
952 return OC_STACK_INVALID_PARAM;
955 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
956 OicSecOxm_t selectedOxm = deviceInfo->doxm->oxmSel;
957 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
959 if(!PMGenerateQuery(false,
960 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
961 deviceInfo->connType,
962 query, sizeof(query), OIC_RSRC_DOXM_URI))
964 OIC_LOG(ERROR, TAG, "PutOwnerTransferModeToResource : Failed to generate query");
965 return OC_STACK_ERROR;
967 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
968 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
971 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
972 return OC_STACK_NO_MEMORY;
974 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
975 secPayload->securityData = g_OTMDatas[selectedOxm].createSelectOxmPayloadCB(otmCtx);
976 if (NULL == secPayload->securityData)
979 OIC_LOG(ERROR, TAG, "Error while converting bin to json");
980 return OC_STACK_ERROR;
983 OCCallbackData cbData;
984 cbData.cb = &OwnerTransferModeHandler;
985 cbData.context = (void *)otmCtx;
987 OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query,
988 &deviceInfo->endpoint, (OCPayload*)secPayload,
989 deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
990 if (res != OC_STACK_OK)
992 OIC_LOG(ERROR, TAG, "OCStack resource error");
995 OIC_LOG(DEBUG, TAG, "OUT PutOwnerTransferModeToResource");
1000 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1002 OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1004 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1006 OIC_LOG(ERROR, TAG, "Invailed parameters");
1007 return OC_STACK_INVALID_PARAM;
1010 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1011 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1012 if(!PMGenerateQuery(false,
1013 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1014 deviceInfo->connType,
1015 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1017 OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1018 return OC_STACK_ERROR;
1020 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1022 OCCallbackData cbData;
1023 cbData.cb = &ListMethodsHandler;
1024 cbData.context = (void *)otmCtx;
1026 OCStackResult res = OCDoResource(NULL, OC_REST_GET, query, NULL, NULL,
1027 deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1028 if (res != OC_STACK_OK)
1030 OIC_LOG(ERROR, TAG, "OCStack resource error");
1033 OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1038 static OCStackResult PutOwnerUuid(OTMContext_t* otmCtx)
1040 OIC_LOG(DEBUG, TAG, "IN PutOwnerUuid");
1042 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1044 OIC_LOG(ERROR, TAG, "Invailed parameters");
1045 return OC_STACK_INVALID_PARAM;
1048 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1049 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1050 if(!PMGenerateQuery(true,
1051 deviceInfo->endpoint.addr, deviceInfo->securePort,
1052 deviceInfo->connType,
1053 query, sizeof(query), OIC_RSRC_DOXM_URI))
1055 OIC_LOG(ERROR, TAG, "PutOwnershipInformation : Failed to generate query");
1056 return OC_STACK_ERROR;
1058 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1060 //PUT PT's uuid to new device
1061 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1064 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1065 return OC_STACK_NO_MEMORY;
1067 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1068 secPayload->securityData =
1069 g_OTMDatas[deviceInfo->doxm->oxmSel].createOwnerTransferPayloadCB(otmCtx);
1070 if (NULL == secPayload->securityData)
1072 OICFree(secPayload);
1073 OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1074 return OC_STACK_INVALID_PARAM;
1076 OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData);
1078 OCCallbackData cbData;
1079 cbData.cb = &OwnerUuidUpdateHandler;
1080 cbData.context = (void *)otmCtx;
1083 OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1084 deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1085 if (res != OC_STACK_OK)
1087 OIC_LOG(ERROR, TAG, "OCStack resource error");
1090 OIC_LOG(DEBUG, TAG, "OUT PutOwnerUuid");
1095 static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx)
1097 OIC_LOG(DEBUG, TAG, "IN PutOwnershipInformation");
1099 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1101 OIC_LOG(ERROR, TAG, "Invailed parameters");
1102 return OC_STACK_INVALID_PARAM;
1105 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1106 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1107 if(!PMGenerateQuery(true,
1108 deviceInfo->endpoint.addr, deviceInfo->securePort,
1109 deviceInfo->connType,
1110 query, sizeof(query), OIC_RSRC_DOXM_URI))
1112 OIC_LOG(ERROR, TAG, "PutOwnershipInformation : Failed to generate query");
1113 return OC_STACK_ERROR;
1115 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1117 //OwnershipInformationHandler
1118 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1121 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1122 return OC_STACK_NO_MEMORY;
1125 otmCtx->selectedDeviceInfo->doxm->owned = true;
1126 secPayload->securityData = BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
1127 if (NULL == secPayload->securityData)
1129 OICFree(secPayload);
1130 OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1131 return OC_STACK_INVALID_PARAM;
1133 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1135 OCCallbackData cbData;
1136 cbData.cb = &OwnershipInformationHandler;
1137 cbData.context = (void *)otmCtx;
1140 OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1141 deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1142 if (res != OC_STACK_OK)
1144 OIC_LOG(ERROR, TAG, "OCStack resource error");
1147 OIC_LOG(DEBUG, TAG, "OUT PutOwnershipInformation");
1152 static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx)
1154 OIC_LOG(DEBUG, TAG, "IN PutUpdateOperationMode");
1156 if(!otmCtx || !otmCtx->selectedDeviceInfo)
1158 return OC_STACK_INVALID_PARAM;
1161 OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1162 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1163 if(!PMGenerateQuery(false,
1164 deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1165 deviceInfo->connType,
1166 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1168 OIC_LOG(ERROR, TAG, "PutUpdateOperationMode : Failed to generate query");
1169 return OC_STACK_ERROR;
1171 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1173 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1176 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1177 return OC_STACK_NO_MEMORY;
1179 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1180 secPayload->securityData = BinToPstatJSON(deviceInfo->pstat);
1181 if (NULL == secPayload->securityData)
1183 OICFree(secPayload);
1184 OIC_LOG(ERROR, TAG, "Error while converting pstat bin to json");
1185 return OC_STACK_INVALID_PARAM;
1188 OCCallbackData cbData;
1189 cbData.cb = &OperationModeUpdateHandler;
1190 cbData.context = (void *)otmCtx;
1192 OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1193 deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1194 if (res != OC_STACK_OK)
1196 OIC_LOG(ERROR, TAG, "OCStack resource error");
1199 OIC_LOG(DEBUG, TAG, "OUT PutUpdateOperationMode");
1204 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
1206 OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
1207 OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1208 otmCtx->selectedDeviceInfo = selectedDevice;
1210 //Set to the lowest level OxM, and then find more higher level OxM.
1211 OCStackResult res = SelectProvisioningMethod(selectedDevice->doxm->oxm,
1212 selectedDevice->doxm->oxmLen,
1213 &selectedDevice->doxm->oxmSel);
1214 if(OC_STACK_OK != res)
1216 OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
1217 SetResult(otmCtx, res);
1220 OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
1222 //Send Req: PUT /oic/sec/doxm [{..."OxmSel" :g_OTMDatas[Index of Selected OxM].OXMString,...}]
1223 res = PutOwnerTransferModeToResource(otmCtx);
1224 if(OC_STACK_OK != res)
1226 OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
1227 SetResult(otmCtx, res);
1231 //Register DTLS event handler to catch the dtls event while handshake
1232 if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DTLSHandshakeCB))
1234 OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register DTLS handshake callback.");
1237 OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
1243 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
1245 OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
1249 OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
1250 return OC_STACK_INVALID_PARAM;
1252 if(oxmType >= OIC_OXM_COUNT)
1254 OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
1255 return OC_STACK_INVALID_PARAM;
1258 g_OTMDatas[oxmType].loadSecretCB= data->loadSecretCB;
1259 g_OTMDatas[oxmType].createSecureSessionCB = data->createSecureSessionCB;
1260 g_OTMDatas[oxmType].createSelectOxmPayloadCB = data->createSelectOxmPayloadCB;
1261 g_OTMDatas[oxmType].createOwnerTransferPayloadCB = data->createOwnerTransferPayloadCB;
1263 OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
1269 * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
1271 OCStackResult OTMDoOwnershipTransfer(void* ctx,
1272 OCProvisionDev_t *selectedDevicelist,
1273 OCProvisionResultCB resultCallback)
1275 OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
1277 if (NULL == selectedDevicelist)
1279 return OC_STACK_INVALID_PARAM;
1281 if (NULL == resultCallback)
1283 return OC_STACK_INVALID_CALLBACK;
1286 OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
1289 OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
1290 return OC_STACK_NO_MEMORY;
1292 otmCtx->ctxResultCallback = resultCallback;
1293 otmCtx->ctxHasError = false;
1294 otmCtx->userCtx = ctx;
1295 OCProvisionDev_t* pCurDev = selectedDevicelist;
1297 //Counting number of selected devices.
1298 otmCtx->ctxResultArraySize = 0;
1299 while(NULL != pCurDev)
1301 otmCtx->ctxResultArraySize++;
1302 pCurDev = pCurDev->next;
1305 otmCtx->ctxResultArray =
1306 (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
1307 if(NULL == otmCtx->ctxResultArray)
1309 OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
1311 return OC_STACK_NO_MEMORY;
1313 pCurDev = selectedDevicelist;
1315 OCStackResult res = OC_STACK_OK;
1316 //Fill the device UUID for result array.
1317 for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
1319 //Checking duplication of Device ID.
1320 bool isDuplicate = true;
1321 res = PDMIsDuplicateDevice(&pCurDev->doxm->deviceID, &isDuplicate);
1322 if (OC_STACK_OK != res)
1328 OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Device ID is duplicated");
1329 res = OC_STACK_INVALID_PARAM;
1332 memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
1333 pCurDev->doxm->deviceID.id,
1335 otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
1336 pCurDev = pCurDev->next;
1339 StartOwnershipTransfer(otmCtx, selectedDevicelist);
1341 OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
1345 OICFree(otmCtx->ctxResultArray);
1351 OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx)
1353 OIC_LOG(INFO, TAG, "IN PutProvisioningStatus");
1357 OIC_LOG(ERROR, TAG, "OTMContext is NULL");
1358 return OC_STACK_INVALID_PARAM;
1360 if(!otmCtx->selectedDeviceInfo)
1362 OIC_LOG(ERROR, TAG, "Can't find device information in OTMContext");
1364 return OC_STACK_INVALID_PARAM;
1367 otmCtx->selectedDeviceInfo->pstat->tm = NORMAL;
1368 otmCtx->selectedDeviceInfo->pstat->cm = PROVISION_ACLS | PROVISION_CREDENTIALS |
1369 SECURITY_MANAGEMENT_SERVICES | BOOTSTRAP_SERVICE;
1370 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1373 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1374 return OC_STACK_NO_MEMORY;
1376 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1377 secPayload->securityData = BinToPstatJSON(otmCtx->selectedDeviceInfo->pstat);
1378 if (NULL == secPayload->securityData)
1380 OICFree(secPayload);
1381 SetResult(otmCtx, OC_STACK_INVALID_JSON);
1382 return OC_STACK_INVALID_JSON;
1384 OIC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData);
1386 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1387 if(!PMGenerateQuery(true,
1388 otmCtx->selectedDeviceInfo->endpoint.addr,
1389 otmCtx->selectedDeviceInfo->securePort,
1390 otmCtx->selectedDeviceInfo->connType,
1391 query, sizeof(query), OIC_RSRC_PSTAT_URI))
1393 OIC_LOG(ERROR, TAG, "PutProvisioningStatus : Failed to generate query");
1394 return OC_STACK_ERROR;
1396 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1398 OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1399 cbData.cb = &ProvisioningStatusHandler;
1400 cbData.context = (void*)otmCtx;
1402 OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1403 otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1404 OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
1405 if (ret != OC_STACK_OK)
1407 OIC_LOG(ERROR, TAG, "OCStack resource error");
1408 SetResult(otmCtx, ret);
1411 OIC_LOG(INFO, TAG, "OUT PutProvisioningStatus");
1416 OCStackResult FinalizeProvisioning(OTMContext_t* otmCtx)
1418 OIC_LOG(INFO, TAG, "IN FinalizeProvisioning");
1422 OIC_LOG(ERROR, TAG, "OTMContext is NULL");
1423 return OC_STACK_INVALID_PARAM;
1425 if(!otmCtx->selectedDeviceInfo)
1427 OIC_LOG(ERROR, TAG, "Can't find device information in OTMContext");
1429 return OC_STACK_INVALID_PARAM;
1431 // Provision Default ACL to device
1432 OicSecAcl_t defaultAcl =
1445 OicUuid_t provTooldeviceID = {.id={0}};
1446 if (OC_STACK_OK != GetDoxmDeviceID(&provTooldeviceID))
1448 OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
1449 SetResult(otmCtx, OC_STACK_ERROR);
1450 return OC_STACK_ERROR;
1452 OIC_LOG(INFO, TAG, "Retieved deviceID");
1453 memcpy(defaultAcl.subject.id, provTooldeviceID.id, sizeof(defaultAcl.subject.id));
1454 char *wildCardResource = "*";
1455 defaultAcl.resources = &wildCardResource;
1457 defaultAcl.owners = (OicUuid_t *) OICCalloc(1, UUID_LENGTH);
1458 if(!defaultAcl.owners)
1460 OIC_LOG(ERROR, TAG, "Failed to memory allocation for default ACL");
1461 SetResult(otmCtx, OC_STACK_NO_MEMORY);
1462 return OC_STACK_NO_MEMORY;
1464 memcpy(defaultAcl.owners->id, provTooldeviceID.id, UUID_LENGTH);
1465 OIC_LOG(INFO, TAG, "Provisioning default ACL");
1467 OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1470 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1471 return OC_STACK_NO_MEMORY;
1473 secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1474 secPayload->securityData = BinToAclJSON(&defaultAcl);
1475 OICFree(defaultAcl.owners);
1476 if(!secPayload->securityData)
1478 OICFree(secPayload);
1479 OIC_LOG(INFO, TAG, "FinalizeProvisioning : Failed to BinToAclJSON");
1480 SetResult(otmCtx, OC_STACK_ERROR);
1481 return OC_STACK_ERROR;
1483 OIC_LOG_V(INFO, TAG, "Provisioning default ACL : %s",secPayload->securityData);
1485 char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1486 if(!PMGenerateQuery(true,
1487 otmCtx->selectedDeviceInfo->endpoint.addr,
1488 otmCtx->selectedDeviceInfo->securePort,
1489 otmCtx->selectedDeviceInfo->connType,
1490 query, sizeof(query), OIC_RSRC_ACL_URI))
1492 OIC_LOG(ERROR, TAG, "FinalizeProvisioning : Failed to generate query");
1493 return OC_STACK_ERROR;
1495 OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1497 OIC_LOG_V(INFO, TAG, "Request URI for Provisioning default ACL : %s", query);
1499 OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1500 cbData.cb = &FinalizeProvisioningCB;
1501 cbData.context = (void *)otmCtx;
1503 OCStackResult ret = OCDoResource(NULL, OC_REST_POST, query,
1504 &otmCtx->selectedDeviceInfo->endpoint, (OCPayload*)secPayload,
1505 otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1506 if (OC_STACK_OK != ret)
1508 SetResult(otmCtx, ret);
1512 OIC_LOG(INFO, TAG, "OUT FinalizeProvisioning");