IOT-1583: Removing /W3 warning from resource/csdk/security.
[iotivity.git] / resource / csdk / security / provisioning / src / ownershiptransfermanager.c
1 /* *****************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * *****************************************************************/
20
21 // 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
25 //
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
31 #endif
32
33 #include "iotivity_config.h"
34 #ifdef HAVE_TIME_H
35 #include <time.h>
36 #endif
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40 #ifdef HAVE_SYS_TIME_H
41 #include <sys/time.h>
42 #endif
43 #include <stdbool.h>
44 #include <string.h>
45
46 #include "logger.h"
47 #include "oic_malloc.h"
48 #include "oic_string.h"
49 #include "cacommon.h"
50 #include "cainterface.h"
51 #include "base64.h"
52 #include "global.h"
53 #include "utlist.h"
54 #include "srmresourcestrings.h"
55 #include "doxmresource.h"
56 #include "pstatresource.h"
57 #include "credresource.h"
58 #include "aclresource.h"
59 #include "ownershiptransfermanager.h"
60 #include "secureresourceprovider.h"
61 #include "securevirtualresourcetypes.h"
62 #include "oxmjustworks.h"
63 #include "oxmrandompin.h"
64 #include "oxmmanufacturercert.h"
65 #ifdef MULTIPLE_OWNER
66 #include "oxmpreconfpin.h"
67 #endif //MULTIPLE_OWNER
68 #include "otmcontextlist.h"
69 #include "pmtypes.h"
70 #include "pmutility.h"
71 #include "srmutility.h"
72 #include "provisioningdatabasemanager.h"
73 #include "ocpayload.h"
74 #include "payload_logging.h"
75 #include "pkix_interface.h"
76 #include "oxmverifycommon.h"
77 #include "psinterface.h"
78
79 #define TAG "OIC_OTM"
80
81
82 #define ALLOWED_OXM         1
83 #define NOT_ALLOWED_OXM     0
84
85 /**
86  * List of allowed oxm list.
87  * All oxm methods are allowed as default.
88  */
89 #ifdef MULTIPLE_OWNER
90 static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
91                                                   ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
92                                                   NOT_ALLOWED_OXM};
93 #else
94 static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
95                                                   ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM};
96 #endif
97
98 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
99 {
100     OCStackResult res = OC_STACK_INVALID_PARAM;
101
102     OIC_LOG(INFO, TAG, "IN OTMSetOTCallback");
103
104     VERIFY_NOT_NULL(TAG, callbacks, ERROR);
105
106 #ifdef MULTIPLE_OWNER
107     VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm
108                     || OIC_CON_MFG_CERT == oxm), ERROR);
109 #else
110     VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm), ERROR);
111 #endif // MULTIPLE_OWNER
112
113     switch(oxm)
114     {
115     case OIC_JUST_WORKS:
116         callbacks->loadSecretCB = LoadSecretJustWorksCallback;
117         callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
118         callbacks->createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
119         callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
120         break;
121     case OIC_RANDOM_DEVICE_PIN:
122         callbacks->loadSecretCB = InputPinCodeCallback;
123         callbacks->createSecureSessionCB = CreateSecureSessionRandomPinCallback;
124         callbacks->createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
125         callbacks->createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
126         break;
127     case OIC_MANUFACTURER_CERTIFICATE:
128         callbacks->loadSecretCB = PrepareMCertificateCallback;
129         callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
130         callbacks->createSelectOxmPayloadCB = CreateMCertificateBasedSelectOxmPayload;
131         callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
132         break;
133     case OIC_DECENTRALIZED_PUBLIC_KEY:
134         OIC_LOG(ERROR, TAG, "OIC_DECENTRALIZED_PUBLIC_KEY not supported yet.");
135         return OC_STACK_INVALID_METHOD;
136 #ifdef MULTIPLE_OWNER
137     case OIC_PRECONFIG_PIN:
138         callbacks->loadSecretCB = LoadPreconfigPinCodeCallback;
139         callbacks->createSecureSessionCB = CreateSecureSessionPreconfigPinCallback;
140         callbacks->createSelectOxmPayloadCB = CreatePreconfigPinBasedSelectOxmPayload;
141         callbacks->createOwnerTransferPayloadCB = CreatePreconfigPinBasedOwnerTransferPayload;
142         break;
143 #endif //MULTIPLE_OWNER
144     case OIC_MV_JUST_WORKS:
145         callbacks->loadSecretCB = LoadSecretJustWorksCallback;
146         callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
147         callbacks->createSelectOxmPayloadCB = CreateMVJustWorksSelectOxmPayload;
148         callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
149         break;
150     case OIC_CON_MFG_CERT:
151         callbacks->loadSecretCB = PrepareMCertificateCallback;
152         callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
153         callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload;
154         callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
155         break;
156     default:
157         OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
158         return OC_STACK_INVALID_PARAM;
159         break;
160     }
161
162     res = OC_STACK_OK;
163 exit:
164     OIC_LOG(INFO, TAG, "OUT OTMSetOTCallback");
165     return res;
166 }
167
168 /**
169  * Internal API to convert OxM value to index of oxm allow table.
170  */
171 static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm)
172 {
173     switch(oxm)
174     {
175         case OIC_JUST_WORKS:
176             return OXM_IDX_JUST_WORKS;
177         case OIC_RANDOM_DEVICE_PIN:
178             return OXM_IDX_RANDOM_DEVICE_PIN;
179         case OIC_MANUFACTURER_CERTIFICATE:
180             return OXM_IDX_MANUFACTURER_CERTIFICATE;
181         case OIC_DECENTRALIZED_PUBLIC_KEY:
182             return OXM_IDX_DECENTRALIZED_PUBLIC_KEY;
183         case OIC_MV_JUST_WORKS:
184             return OXM_IDX_MV_JUST_WORKS;
185         case OIC_CON_MFG_CERT:
186             return OXM_IDX_CON_MFG_CERT;
187 #ifdef MULTIPLE_OWNER
188         case OIC_PRECONFIG_PIN:
189             return OXM_IDX_PRECONFIG_PIN;
190 #endif
191         default:
192             return OXM_IDX_UNKNOWN;
193     }
194 }
195
196 /**
197  * Function to select appropriate  provisioning method.
198  *
199  * @param[in] supportedMethods   Array of supported methods
200  * @param[in] numberOfMethods   number of supported methods
201  * @param[out]  selectedMethod         Selected methods
202  * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)
203  * @return  OC_STACK_OK on success
204  */
205 OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
206         size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType)
207 {
208     bool isOxmSelected = false;
209     OxmAllowTableIdx_t selectedOxmIdx = OXM_IDX_UNKNOWN;
210
211     OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
212
213     if (numberOfMethods == 0 || !supportedMethods)
214     {
215         OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
216         return OC_STACK_ERROR;
217     }
218
219     switch(ownerType)
220     {
221         case SUPER_OWNER:
222         {
223             for (size_t i = 0; i < numberOfMethods; i++)
224             {
225                 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
226                 if (OXM_IDX_COUNT <= selectedOxmIdx)
227                 {
228                     OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
229                     continue;
230                 }
231
232 #ifdef MULTIPLE_OWNER
233                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
234                    OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
235 #else
236                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
237 #endif //MULTIPLE_OWNER
238                 {
239                     *selectedMethod  = supportedMethods[i];
240                     isOxmSelected = true;
241                 }
242             }
243         }
244         break;
245 #ifdef MULTIPLE_OWNER
246         case SUB_OWNER:
247         {
248             for (size_t i = 0; i < numberOfMethods; i++)
249             {
250                 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
251                 if (OXM_IDX_COUNT <= selectedOxmIdx)
252                 {
253                     OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
254                     continue;
255                 }
256
257                 //in case of MOT, only Random PIN & Preconfigured PIN based OxM is allowed
258                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
259                     (OXM_IDX_RANDOM_DEVICE_PIN == selectedOxmIdx ||
260                      OXM_IDX_PRECONFIG_PIN == selectedOxmIdx))
261                 {
262                     *selectedMethod  = supportedMethods[i];
263                     isOxmSelected = true;
264                 }
265             }
266         }
267         break;
268 #endif
269         default:
270         {
271             OIC_LOG_V(ERROR, TAG, "Unknown owner type or Not supported owner type : %d", ownerType);
272             return OC_STACK_INVALID_PARAM;
273         }
274     }
275
276     if (!isOxmSelected)
277     {
278         OIC_LOG(ERROR, TAG, "Can not find the allowed OxM.");
279         return OC_STACK_NOT_ALLOWED_OXM;
280     }
281
282     OIC_LOG(DEBUG, TAG, "OUT SelectProvisioningMethod");
283
284     return OC_STACK_OK;
285 }
286
287 /**
288  * Function to select operation mode.This function will return most secure common operation mode.
289  *
290  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
291  * @param[out]   selectedMode   selected operation mode
292  * @return  OC_STACK_OK on success
293  */
294 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
295                                 OicSecDpom_t *selectedMode)
296 {
297     OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
298     *selectedMode = selectedDeviceInfo->pstat->sm[0];
299     OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
300 }
301
302 /**
303  * Function to start ownership transfer.
304  * This function will send the first request for provisioning,
305  * The next request message is sent from the response handler for this request.
306  *
307  * @param[in] ctx   context value passed to callback from calling function.
308  * @param[in] selectedDevice   selected device information to performing provisioning.
309  * @return  OC_STACK_OK on success
310  */
311 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
312
313 /**
314  * Function to update owner transfer mode
315  *
316  * @param[in]  otmCtx  Context value of ownership transfer.
317  * @return  OC_STACK_OK on success
318  */
319 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx);
320
321 /**
322  * Function to send request to resource to get its pstat resource information.
323  *
324  * @param[in]  otmCtx  Context value of ownership transfer.
325  * @return  OC_STACK_OK on success
326  */
327 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
328
329
330 /**
331  * Function to send  uuid of owner device to new device.
332  * This function would update 'owner of doxm' as UUID for provisioning tool.
333  *
334  * @param[in]  otmCtx  Context value of ownership transfer.
335  * @return  OC_STACK_OK on success
336  */
337 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx);
338
339 /**
340  * Function to update the operation mode. As per the spec. Operation mode in client driven
341  * single service provisioning it will be updated to 0x3
342  *
343  * @param[in]  otmCtx  Context value of ownership transfer.
344  * @return  OC_STACK_OK on success
345  */
346 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx);
347
348 /**
349  * Function to update the owner credential to new device
350  *
351  * @param[in]  otmCtx  Context value of ownership transfer.
352  * @param[in] selectedOperationMode selected operation mode
353  * @return  OC_STACK_OK on success
354  */
355 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx);
356
357 /**
358  * Function to update the owner ACL to new device.
359  *
360  * @param[in]  otmCtx  Context value of ownership transfer.
361  * @return  OC_STACK_OK on success
362  */
363 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx);
364
365 /**
366  * Function to send ownerShip info.
367  * This function would update 'owned of doxm' as true.
368  *
369  * @param[in]  otmCtx  Context value of ownership transfer.
370  * @return  OC_STACK_OK on success
371  */
372 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx);
373
374 /**
375  * Function to update pstat as Ready for provisioning.
376  * This function would update 'cm' from bx0000,0010 to bx0000,0000.
377  *
378  * @param[in] ctx   context value passed to callback from calling function.
379  * @param[in] selectedDevice   selected device information to performing provisioning.
380  * @return  OC_STACK_OK on success
381  */
382 static OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx);
383
384 /**
385  * Function to update pstat as Ready for Normal Operation.
386  * This function would update 'isop' from false to true.
387  *
388  * @param[in] ctx   context value passed to callback from calling function.
389  * @param[in] selectedDevice   selected device information to performing provisioning.
390  * @return  OC_STACK_OK on success
391  */
392 static OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx);
393
394 static bool IsComplete(OTMContext_t* otmCtx)
395 {
396     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
397     {
398         if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
399         {
400             return false;
401         }
402     }
403
404     return true;
405 }
406
407 /**
408  * Function to save the result of provisioning.
409  *
410  * @param[in,out] otmCtx   Context value of ownership transfer.
411  * @param[in] res   result of provisioning
412  */
413 static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
414 {
415     OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
416
417     if(NULL == otmCtx || NULL == otmCtx->selectedDeviceInfo)
418     {
419         OIC_LOG(WARNING, TAG, "OTMContext is NULL");
420         return;
421     }
422
423     //If OTM Context was removed from previous response handler, just exit the current OTM process.
424     if(NULL == GetOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
425                              otmCtx->selectedDeviceInfo->securePort))
426     {
427         OIC_LOG(WARNING, TAG, "Current OTM Process has already ended.");
428     }
429
430     //Revert psk_info callback and new deivce uuid in case of random PIN OxM
431     if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
432     {
433         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
434         {
435             OIC_LOG(WARNING, TAG, "Failed to revert  is DTLS credential handler.");
436         }
437         OicUuid_t emptyUuid = { .id={0}};
438         SetUuidForPinBasedOxm(&emptyUuid);
439     }
440     else if(OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel ||
441                         OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)
442     {
443         //Revert back certificate related callbacks.
444         if(CA_STATUS_OK != CAregisterPkixInfoHandler(GetPkixInfo))
445         {
446             OIC_LOG(WARNING, TAG, "Failed to revert PkixInfoHandler.");
447         }
448         if(CA_STATUS_OK != CAregisterGetCredentialTypesHandler(InitCipherSuiteList))
449         {
450             OIC_LOG(WARNING, TAG, "Failed to revert CredentialTypesHandler.");
451         }
452     }
453
454     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
455     {
456         if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
457                   otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
458         {
459             otmCtx->ctxResultArray[i].res = res;
460             if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res)
461             {
462                 otmCtx->ctxHasError = true;
463                 if (OC_STACK_OK != PDMDeleteDevice(&otmCtx->ctxResultArray[i].deviceId))
464                 {
465                     OIC_LOG(WARNING, TAG, "Internal error in PDMDeleteDevice");
466                 }
467                 CAEndpoint_t endpoint;
468                 memcpy(&endpoint, &(otmCtx->selectedDeviceInfo->endpoint), sizeof(CAEndpoint_t));
469                 if (CA_STATUS_OK != CAcloseSslConnection(&endpoint))
470                 {
471                     OIC_LOG(WARNING, TAG, "Failed to close Secure session");
472                 }
473             }
474         }
475     }
476
477     //In case of duplicated OTM process, OTMContext and OCDoHandle should not be removed.
478     if(OC_STACK_DUPLICATE_REQUEST != res)
479     {
480         //Remove the current OTM Context from OTM queue
481         RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
482                          otmCtx->selectedDeviceInfo->securePort);
483
484         //If there is a request being performed, cancel it to prevent retransmission.
485         if(otmCtx->ocDoHandle)
486         {
487             OIC_LOG_V(DEBUG, TAG, "OCCancel - %s : %d",
488                     otmCtx->selectedDeviceInfo->endpoint.addr,
489                     otmCtx->selectedDeviceInfo->securePort);
490             if(OC_STACK_OK != OCCancel(otmCtx->ocDoHandle, OC_HIGH_QOS, NULL, 0))
491             {
492                 OIC_LOG(WARNING, TAG, "Failed to remove registered callback");
493             }
494             else
495             {
496                 otmCtx->ocDoHandle = NULL;
497             }
498         }
499     }
500
501     //If all OTM process is complete, invoke the user callback.
502     if(IsComplete(otmCtx))
503     {
504         otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
505                                    otmCtx->ctxResultArray, otmCtx->ctxHasError);
506         OICFree(otmCtx->ctxResultArray);
507         OICFree(otmCtx);
508     }
509     else
510     {
511         if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
512                                                  otmCtx->selectedDeviceInfo->next))
513         {
514             OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
515         }
516     }
517
518     OIC_LOG(DEBUG, TAG, "OUT SetResult");
519 }
520
521 static void OwnershipTransferSessionEstablished(const CAEndpoint_t *endpoint,
522         OicSecDoxm_t *newDevDoxm, OTMContext_t *otmCtx)
523 {
524     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
525
526     //In case of Mutual Verified Just-Works, display mutualVerifNum
527     if (OIC_MV_JUST_WORKS == newDevDoxm->oxmSel)
528     {
529         uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
530         uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
531         OicUuid_t deviceID = {.id = {0}};
532
533         if (OC_STACK_OK != GetDoxmDeviceID(&deviceID))
534         {
535             OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
536             goto exit;
537         }
538
539         //Generate mutualVerifNum
540         char label[LABEL_LEN] = {0};
541         snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS);
542
543         CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
544                 (uint8_t *)label,
545                 strlen(label),
546                 deviceID.id, sizeof(deviceID.id),
547                 newDevDoxm->deviceID.id, sizeof(newDevDoxm->deviceID.id),
548                 preMutualVerifNum, sizeof(preMutualVerifNum));
549
550         if (CA_STATUS_OK != pskRet)
551         {
552             OIC_LOG(WARNING, TAG, "CAGenerateOwnerPSK failed");
553             goto exit;
554         }
555
556         memcpy(mutualVerifNum, preMutualVerifNum + sizeof(preMutualVerifNum) - sizeof(mutualVerifNum),
557                 sizeof(mutualVerifNum));
558         if (OC_STACK_OK != VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM))
559         {
560             OIC_LOG(ERROR, TAG, "Error while displaying mutualVerifNum");
561             goto exit;
562         }
563     }
564     //In case of confirmed manufacturer cert, display message
565     else if (OIC_CON_MFG_CERT == newDevDoxm->oxmSel)
566     {
567         if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, DISPLAY_NUM))
568         {
569             OIC_LOG(ERROR, TAG, "Error while displaying message");
570             goto exit;
571         }
572     }
573
574     //Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
575     OCStackResult res = PostOwnerUuid(otmCtx);
576     if(OC_STACK_OK != res)
577     {
578         OIC_LOG(ERROR, TAG, "Failed to send owner information");
579         SetResult(otmCtx, res);
580     }
581
582 exit:
583     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
584 }
585
586 static void OwnershipTransferSessionFailed(const CAEndpoint_t *endpoint,
587         const CAErrorInfo_t *info, OicSecDoxm_t *newDevDoxm, OTMContext_t *otmCtx, bool emptyOwnerUuid)
588 {
589     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
590
591     if (CA_DTLS_AUTHENTICATION_FAILURE != info->result)
592     {
593         OIC_LOG_V(ERROR, TAG, "Ownership Transfer session establishment failed, error %u", info->result);
594         goto exit;
595     }
596
597     //in case of error from owner credential
598     if (!emptyOwnerUuid && newDevDoxm->owned)
599     {
600         OIC_LOG(ERROR, TAG, "The local copy of the owner credential may be incorrect - removing it.");
601         if (OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID)))
602         {
603             OIC_LOG(WARNING, TAG, "Failed to remove the invalid owner credential");
604         }
605         SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
606         goto exit;
607     }
608
609     //in case of error from wrong PIN, re-start the ownership transfer
610     if (OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel)
611     {
612         OIC_LOG(ERROR, TAG, "The PIN number may be incorrect.");
613
614         OicUuid_t emptyUuid = {.id={0}};
615         memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
616         newDevDoxm->owned = false;
617         otmCtx->attemptCnt++;
618
619         // In order to re-start ownership transfer, device information should be deleted from PDM.
620         OCStackResult res = PDMDeleteDevice(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
621         if (OC_STACK_OK != res)
622         {
623             OIC_LOG(ERROR, TAG, "Failed to PDMDeleteDevice");
624             SetResult(otmCtx, res);
625         }
626         else
627         {
628             if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
629             {
630                 res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
631                 if(OC_STACK_OK != res)
632                 {
633                     OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
634                     SetResult(otmCtx, res);
635                 }
636             }
637             else
638             {
639                 OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
640                 SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
641             }
642         }
643         goto exit;
644     }
645
646     OIC_LOG(ERROR, TAG, "Failed to establish secure session.");
647     SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
648
649 exit:
650     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
651 }
652
653 /**
654  * Function to handle the handshake result in OTM.
655  * This function will be invoked after DTLS handshake
656  * @param   endPoint  [IN] The remote endpoint.
657  * @param   errorInfo [IN] Error information from the endpoint.
658  * @return  NONE
659  */
660 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
661 {
662     OIC_LOG_V(DEBUG, TAG, "In %s(endpoint = %p, info = %p)", __func__, endpoint, info);
663
664     if (NULL == endpoint || NULL == info)
665     {
666         goto exit;
667     }
668
669     OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
670               endpoint->addr, endpoint->port, info->result);
671
672     OTMContext_t* otmCtx = GetOTMContext(endpoint->addr, endpoint->port);
673     if (NULL == otmCtx)
674     {
675         OIC_LOG(ERROR, TAG, "OTM context not found!");
676         goto exit;
677     }
678
679     OicSecDoxm_t* newDevDoxm = otmCtx->selectedDeviceInfo->doxm;
680     if (NULL == newDevDoxm)
681     {
682         OIC_LOG(ERROR, TAG, "New device doxm not found!");
683         goto exit;
684     }
685
686     //Make sure the address matches.
687     bool matching = (0 == strncmp(otmCtx->selectedDeviceInfo->endpoint.addr,
688                                   endpoint->addr, sizeof(endpoint->addr)));
689     matching = (matching && (otmCtx->selectedDeviceInfo->securePort == endpoint->port));
690
691     if (!matching)
692     {
693         OIC_LOG_V(ERROR, TAG, "Mismatched: expected address %s:%u",
694                   otmCtx->selectedDeviceInfo->endpoint.addr, otmCtx->selectedDeviceInfo->securePort);
695         goto exit;
696     }
697
698     OicUuid_t emptyUuid = {.id={0}};
699     bool emptyOwnerUuid = (memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0);
700
701     //If temporal secure sesstion established successfully
702     if ((CA_STATUS_OK == info->result) && !newDevDoxm->owned && emptyOwnerUuid)
703     {
704         OwnershipTransferSessionEstablished(endpoint, newDevDoxm, otmCtx);
705     }
706     else
707     {
708         OwnershipTransferSessionFailed(endpoint, info, newDevDoxm, otmCtx, emptyOwnerUuid);
709     }
710
711 exit:
712     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
713 }
714
715 /**
716  * Function to save the Owner/SubOwner PSK.
717  *
718  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
719  * @return  OC_STACK_OK on success
720  */
721 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
722 {
723     OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
724
725     OCStackResult res = OC_STACK_ERROR;
726
727     CAEndpoint_t endpoint;
728     memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
729     OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
730     endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
731     endpoint.port = selectedDeviceInfo->securePort;
732     endpoint.adapter = selectedDeviceInfo->endpoint.adapter;
733
734     OicUuid_t ownerDeviceID = {.id={0}};
735     if (OC_STACK_OK != GetDoxmDeviceID(&ownerDeviceID))
736     {
737         OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
738         return res;
739     }
740
741     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
742     OicSecKey_t ownerKey = {.data=ownerPSK, .len=OWNER_PSK_LENGTH_128, .encoding=OIC_ENCODING_RAW};
743
744     //Generating OwnerPSK
745     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
746             (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
747             strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
748             ownerDeviceID.id, sizeof(ownerDeviceID.id),
749             selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
750             ownerPSK, OWNER_PSK_LENGTH_128);
751
752     if (CA_STATUS_OK == pskRet)
753     {
754         OIC_LOG(DEBUG, TAG,"Owner PSK dump:\n");
755         OIC_LOG_BUFFER(DEBUG, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
756         //Generating new credential for provisioning tool
757         OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
758                                   SYMMETRIC_PAIR_WISE_KEY, NULL,
759                                   &ownerKey, &ownerDeviceID, NULL);
760         OICClearMemory(ownerPSK, sizeof(ownerPSK));
761         VERIFY_NOT_NULL(TAG, cred, ERROR);
762
763         size_t outSize = 0;
764         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
765         char* b64Buf = (char *)OICCalloc(1, b64BufSize);
766         VERIFY_NOT_NULL(TAG, b64Buf, ERROR);
767         b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize);
768
769         OICFree( cred->privateData.data );
770         cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
771         VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
772
773         strncpy((char*)(cred->privateData.data), b64Buf, outSize);
774         cred->privateData.data[outSize] = '\0';
775         cred->privateData.encoding = OIC_ENCODING_BASE64;
776         cred->privateData.len = outSize;
777         OICFree(b64Buf);
778
779         //Finding previous ownerPSK.
780         const OicSecCred_t* credList = GetCredList();
781         const OicSecCred_t* prevCred = NULL;
782         uint16_t credId = 0;
783         LL_FOREACH(credList, prevCred)
784         {
785             //OwnerPSK's type is SYMMETRIC_PAIR_WISE_KEY
786             if (SYMMETRIC_PAIR_WISE_KEY == prevCred->credType &&
787                 0 == memcmp(prevCred->subject.id, cred->subject.id, sizeof(cred->subject.id)))
788             {
789                 credId = prevCred->credId;
790                 break;
791             }
792         }
793
794         //If duplicate owner PSK is exists, remove it.
795         if(0 < credId)
796         {
797             OIC_LOG(WARNING, TAG, "Duplicate OwnerPSK was detected.");
798             OIC_LOG(WARNING, TAG, "[Subject] : ");
799             OIC_LOG_BUFFER(WARNING, TAG, prevCred->subject.id, sizeof(prevCred->subject.id));
800             OIC_LOG_V(WARNING, TAG, "[Encoding Type] : %d", prevCred->privateData.encoding);
801             OIC_LOG(DEBUG, TAG, "[Private Data] : ");
802             OIC_LOG_BUFFER(DEBUG, TAG, prevCred->privateData.data, prevCred->privateData.len);
803             OIC_LOG(WARNING, TAG, "Previous OwnerPSK will be removed.");
804
805             res = RemoveCredentialByCredId(credId);
806             if(OC_STACK_RESOURCE_DELETED != res)
807             {
808                 OIC_LOG(ERROR, TAG, "Failed to remove the previous OwnerPSK");
809                 DeleteCredList(cred);
810                 goto exit;
811             }
812         }
813
814         res = AddCredential(cred);
815         if(res != OC_STACK_OK)
816         {
817             DeleteCredList(cred);
818             return res;
819         }
820     }
821     else
822     {
823         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
824     }
825
826     OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
827 exit:
828     return res;
829 }
830
831 /**
832  * Callback handler for OwnerShipTransferModeHandler API.
833  *
834  * @param[in] ctx             ctx value passed to callback from calling function.
835  * @param[in] UNUSED          handle to an invocation
836  * @param[in] clientResponse  Response from queries to remote servers.
837  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
838  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
839  */
840 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
841                                                          OCClientResponse *clientResponse)
842 {
843     OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
844
845     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
846     VERIFY_NOT_NULL(TAG, ctx, WARNING);
847
848     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
849     otmCtx->ocDoHandle = NULL;
850     (void)UNUSED;
851     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
852     {
853         OIC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
854         //Send request : GET /oic/sec/pstat
855         OCStackResult res = GetProvisioningStatusResource(otmCtx);
856         if(OC_STACK_OK != res)
857         {
858             OIC_LOG(WARNING, TAG, "Failed to get pstat information");
859             SetResult(otmCtx, res);
860         }
861     }
862     else
863     {
864         OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
865         clientResponse->result);
866         SetResult(otmCtx, clientResponse->result);
867     }
868
869     OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
870
871 exit:
872     return  OC_STACK_DELETE_TRANSACTION;
873 }
874
875 /**
876  * Callback handler for ProvisioningStatusResouceHandler API.
877  *
878  * @param[in] ctx             ctx value passed to callback from calling function.
879  * @param[in] UNUSED          handle to an invocation
880  * @param[in] clientResponse  Response from queries to remote servers.
881  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
882  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
883  */
884 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
885                                                     OCClientResponse *clientResponse)
886 {
887     OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
888
889     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
890     VERIFY_NOT_NULL(TAG, ctx, WARNING);
891
892     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
893     otmCtx->ocDoHandle = NULL;
894     (void)UNUSED;
895     if  (OC_STACK_OK == clientResponse->result)
896     {
897         if  (NULL == clientResponse->payload)
898         {
899             OIC_LOG(INFO, TAG, "Skiping Null payload");
900             SetResult(otmCtx, OC_STACK_ERROR);
901             return OC_STACK_DELETE_TRANSACTION;
902         }
903
904         if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
905         {
906             OIC_LOG(INFO, TAG, "Unknown payload type");
907             SetResult(otmCtx, OC_STACK_ERROR);
908             return OC_STACK_DELETE_TRANSACTION;
909         }
910         OicSecPstat_t* pstat = NULL;
911         OCStackResult result = CBORPayloadToPstat(
912                 ((OCSecurityPayload*)clientResponse->payload)->securityData,
913                 ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
914                 &pstat);
915         if(NULL == pstat || result != OC_STACK_OK)
916         {
917             OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
918             SetResult(otmCtx, OC_STACK_ERROR);
919             return OC_STACK_DELETE_TRANSACTION;
920         }
921         if(false == (TAKE_OWNER & pstat->cm))
922         {
923             OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
924             SetResult(otmCtx, OC_STACK_ERROR);
925             return OC_STACK_DELETE_TRANSACTION;
926         }
927         otmCtx->selectedDeviceInfo->pstat = pstat;
928
929         //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
930         SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
931
932         //Send request : POST /oic/sec/pstat [{"om":"bx11", .. }]
933         OCStackResult res = PostUpdateOperationMode(otmCtx);
934         if (OC_STACK_OK != res)
935         {
936             OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
937             SetResult(otmCtx, res);
938         }
939     }
940     else
941     {
942         OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
943             clientResponse->result);
944         SetResult(otmCtx, clientResponse->result);
945     }
946
947     OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
948 exit:
949     return  OC_STACK_DELETE_TRANSACTION;
950 }
951
952 /**
953  * Response handler for update owner uuid request.
954  *
955  * @param[in] ctx             ctx value passed to callback from calling function.
956  * @param[in] UNUSED          handle to an invocation
957  * @param[in] clientResponse  Response from queries to remote servers.
958  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
959  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
960  */
961 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
962                                 OCClientResponse *clientResponse)
963 {
964     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
965     VERIFY_NOT_NULL(TAG, ctx, WARNING);
966
967     OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
968     (void)UNUSED;
969     OCStackResult res = OC_STACK_OK;
970     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
971     otmCtx->ocDoHandle = NULL;
972
973     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
974     {
975         if(otmCtx && otmCtx->selectedDeviceInfo)
976         {
977             //In case of Mutual Verified Just-Works, wait for user confirmation
978             if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel)
979             {
980                 res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
981                 if (OC_STACK_OK != res)
982                 {
983                     if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, otmCtx->ctxResultCallback))
984                     {
985                         OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error");
986                     }
987                 }
988             }
989
990             res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
991             if(OC_STACK_OK != res)
992             {
993                 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
994                 SetResult(otmCtx, res);
995                 return OC_STACK_DELETE_TRANSACTION;
996             }
997
998             //POST owner credential to new device according to security spec B.
999             res = PostOwnerCredential(otmCtx);
1000             if(OC_STACK_OK != res)
1001             {
1002                 OIC_LOG(ERROR, TAG,
1003                         "OwnerUuidUpdateHandler:Failed to send PosT request for onwer credential");
1004                 SetResult(otmCtx, res);
1005                 return OC_STACK_DELETE_TRANSACTION;
1006             }
1007         }
1008     }
1009     else
1010     {
1011         res = clientResponse->result;
1012         OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
1013         SetResult(otmCtx, res);
1014     }
1015
1016     OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
1017
1018 exit:
1019     return  OC_STACK_DELETE_TRANSACTION;
1020 }
1021
1022 /**
1023  * Response handler for update operation mode.
1024  *
1025  * @param[in] ctx             ctx value passed to callback from calling function.
1026  * @param[in] UNUSED          handle to an invocation
1027  * @param[in] clientResponse  Response from queries to remote servers.
1028  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1029  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1030  */
1031 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
1032                                 OCClientResponse *clientResponse)
1033 {
1034     OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
1035
1036     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1037     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1038
1039     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1040     otmCtx->ocDoHandle = NULL;
1041     (void) UNUSED;
1042     if  (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1043     {
1044         OCStackResult res = OC_STACK_ERROR;
1045
1046         //DTLS Handshake
1047         //Load secret for temporal secure session.
1048         if(otmCtx->otmCallback.loadSecretCB)
1049         {
1050             res = otmCtx->otmCallback.loadSecretCB(otmCtx);
1051             if(OC_STACK_OK != res)
1052             {
1053                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
1054                 SetResult(otmCtx, res);
1055                 return  OC_STACK_DELETE_TRANSACTION;
1056             }
1057         }
1058
1059         //Save the current context instance to use on the dtls handshake callback
1060         if(OC_STACK_OK != AddOTMContext(otmCtx,
1061                                          otmCtx->selectedDeviceInfo->endpoint.addr,
1062                                          otmCtx->selectedDeviceInfo->securePort))
1063         {
1064             OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List.");
1065             SetResult(otmCtx, res);
1066             return OC_STACK_DELETE_TRANSACTION;
1067         }
1068
1069         //Try DTLS handshake to generate secure session
1070         if(otmCtx->otmCallback.createSecureSessionCB)
1071         {
1072             res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
1073             if(OC_STACK_OK != res)
1074             {
1075                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
1076                 SetResult(otmCtx, res);
1077                 return OC_STACK_DELETE_TRANSACTION;
1078             }
1079         }
1080     }
1081     else
1082     {
1083         OIC_LOG(ERROR, TAG, "Error while update operation mode");
1084         SetResult(otmCtx, clientResponse->result);
1085     }
1086
1087     OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
1088
1089 exit:
1090     return  OC_STACK_DELETE_TRANSACTION;
1091 }
1092
1093 /**
1094  * Response handler for update owner crendetial request.
1095  *
1096  * @param[in] ctx             ctx value passed to callback from calling function.
1097  * @param[in] UNUSED          handle to an invocation
1098  * @param[in] clientResponse  Response from queries to remote servers.
1099  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1100  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1101  */
1102 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
1103                                 OCClientResponse *clientResponse)
1104 {
1105     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1106     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1107
1108     OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
1109     (void)UNUSED;
1110     OCStackResult res = OC_STACK_OK;
1111     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1112     otmCtx->ocDoHandle = NULL;
1113
1114     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1115     {
1116         if(otmCtx && otmCtx->selectedDeviceInfo)
1117         {
1118             //Close the temporal secure session to verify the owner credential
1119             CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
1120             endpoint->port = otmCtx->selectedDeviceInfo->securePort;
1121             CAResult_t caResult = CA_STATUS_OK;
1122             caResult = CAcloseSslConnection(endpoint);
1123
1124             if(CA_STATUS_OK != caResult)
1125             {
1126                 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
1127                 SetResult(otmCtx, caResult);
1128                 return OC_STACK_DELETE_TRANSACTION;
1129             }
1130
1131             /**
1132              * If we select NULL cipher,
1133              * client will select appropriate cipher suite according to server's cipher-suite list.
1134              */
1135             // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
1136             caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
1137             if(CA_STATUS_OK != caResult)
1138             {
1139                 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
1140                 SetResult(otmCtx, caResult);
1141                 return OC_STACK_DELETE_TRANSACTION;
1142             }
1143
1144             /**
1145              * in case of random PIN based OxM,
1146              * revert get_psk_info callback of tinyDTLS to use owner credential.
1147              */
1148             if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1149             {
1150                 OicUuid_t emptyUuid = { .id={0}};
1151                 SetUuidForPinBasedOxm(&emptyUuid);
1152
1153                 caResult = CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
1154
1155                 if(CA_STATUS_OK != caResult)
1156                 {
1157                     OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1158                     SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
1159                     return OC_STACK_DELETE_TRANSACTION;
1160                 }
1161             }
1162 #ifdef __WITH_TLS__
1163            otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
1164 #endif
1165             res = PostOwnerAcl(otmCtx);
1166             if(OC_STACK_OK != res)
1167             {
1168                 OIC_LOG(ERROR, TAG, "Failed to update owner ACL to new device");
1169                 SetResult(otmCtx, res);
1170                 return OC_STACK_DELETE_TRANSACTION;
1171             }
1172         }
1173     }
1174     else
1175     {
1176         res = clientResponse->result;
1177         OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
1178         SetResult(otmCtx, res);
1179     }
1180
1181     OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
1182
1183 exit:
1184     return  OC_STACK_DELETE_TRANSACTION;
1185 }
1186
1187 /**
1188  * Response handler for update owner ACL request.
1189  *
1190  * @param[in] ctx             ctx value passed to callback from calling function.
1191  * @param[in] UNUSED          handle to an invocation
1192  * @param[in] clientResponse  Response from queries to remote servers.
1193  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1194  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1195  */
1196 static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle UNUSED,
1197                                 OCClientResponse *clientResponse)
1198 {
1199     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1200     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1201
1202     OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler");
1203     (void)UNUSED;
1204     OCStackResult res = OC_STACK_OK;
1205     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1206     otmCtx->ocDoHandle = NULL;
1207
1208     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1209     {
1210         if(otmCtx && otmCtx->selectedDeviceInfo)
1211         {
1212             //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }]
1213             res = PostOwnershipInformation(otmCtx);
1214             if(OC_STACK_OK != res)
1215             {
1216                 OIC_LOG(ERROR, TAG, "Failed to update ownership information to new device");
1217                 SetResult(otmCtx, res);
1218             }
1219         }
1220     }
1221     else
1222     {
1223         res = clientResponse->result;
1224         OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res);
1225         SetResult(otmCtx, res);
1226     }
1227
1228     OIC_LOG(DEBUG, TAG, "OUT OwnerAclHandler");
1229
1230 exit:
1231     return  OC_STACK_DELETE_TRANSACTION;
1232 }
1233
1234
1235 /**
1236  * Response handler for update owner information request.
1237  *
1238  * @param[in] ctx             ctx value passed to callback from calling function.
1239  * @param[in] UNUSED          handle to an invocation
1240  * @param[in] clientResponse  Response from queries to remote servers.
1241  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1242  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1243  */
1244 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
1245                                 OCClientResponse *clientResponse)
1246 {
1247     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1248     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1249
1250     OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
1251     (void)UNUSED;
1252     OCStackResult res = OC_STACK_OK;
1253     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1254     otmCtx->ocDoHandle = NULL;
1255
1256     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1257     {
1258         if(otmCtx && otmCtx->selectedDeviceInfo)
1259         {
1260             OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
1261             OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
1262
1263             res = PostProvisioningStatus(otmCtx);
1264             if(OC_STACK_OK != res)
1265             {
1266                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1267                 SetResult(otmCtx, res);
1268             }
1269         }
1270     }
1271     else
1272     {
1273         res = clientResponse->result;
1274         OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
1275         SetResult(otmCtx, res);
1276     }
1277
1278     OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
1279
1280 exit:
1281     return  OC_STACK_DELETE_TRANSACTION;
1282 }
1283
1284 /**
1285  * Response handler of update provisioning status.
1286  *
1287  * @param[in] ctx             ctx value passed to callback from calling function.
1288  * @param[in] UNUSED          handle to an invocation
1289  * @param[in] clientResponse  Response from queries to remote servers.
1290  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1291  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1292  */
1293 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
1294                                                        OCClientResponse *clientResponse)
1295 {
1296     OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
1297
1298     VERIFY_NOT_NULL(TAG, clientResponse, ERROR);
1299     VERIFY_NOT_NULL(TAG, ctx, ERROR);
1300
1301     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1302     otmCtx->ocDoHandle = NULL;
1303     (void)UNUSED;
1304     OCStackResult res = OC_STACK_OK;
1305
1306     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1307     {
1308         if(otmCtx && otmCtx->selectedDeviceInfo)
1309         {
1310             OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
1311
1312             res = PostNormalOperationStatus(otmCtx);
1313             if(OC_STACK_OK != res)
1314             {
1315                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
1316                 SetResult(otmCtx, res);
1317             }
1318         }
1319     }
1320     else
1321     {
1322         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1323                             clientResponse->result);
1324         SetResult(otmCtx, clientResponse->result);
1325     }
1326
1327 exit:
1328     OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
1329     return OC_STACK_DELETE_TRANSACTION;
1330 }
1331
1332 /**
1333  * Response handler of update provisioning status to Ready for Normal..
1334  *
1335  * @param[in] ctx             ctx value passed to callback from calling function.
1336  * @param[in] UNUSED          handle to an invocation
1337  * @param[in] clientResponse  Response from queries to remote servers.
1338  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1339  *          and OC_STACK_KEEP_TRANSACTION to keep it.
1340  */
1341 static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
1342                                                        OCClientResponse *clientResponse)
1343 {
1344     OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
1345
1346     VERIFY_NOT_NULL(TAG, clientResponse, ERROR);
1347     VERIFY_NOT_NULL(TAG, ctx, ERROR);
1348
1349     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1350     otmCtx->ocDoHandle = NULL;
1351     (void)UNUSED;
1352
1353     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1354     {
1355         OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
1356         OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
1357                                               PDM_DEVICE_ACTIVE);
1358          if (OC_STACK_OK == res)
1359          {
1360                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1361                 SetResult(otmCtx, OC_STACK_OK);
1362                 return OC_STACK_DELETE_TRANSACTION;
1363          }
1364           else
1365          {
1366               OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1367          }
1368     }
1369     else
1370     {
1371         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1372                             clientResponse->result);
1373         SetResult(otmCtx, clientResponse->result);
1374     }
1375
1376 exit:
1377     OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
1378     return OC_STACK_DELETE_TRANSACTION;
1379 }
1380
1381 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx)
1382 {
1383     OIC_LOG(DEBUG, TAG, "IN PostOwnerCredential");
1384
1385     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1386     {
1387         OIC_LOG(ERROR, TAG, "Invalid parameters");
1388         return OC_STACK_INVALID_PARAM;
1389     }
1390
1391     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1392     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1393
1394     if(!PMGenerateQuery(true,
1395                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1396                         deviceInfo->connType,
1397                         query, sizeof(query), OIC_RSRC_CRED_URI))
1398     {
1399         OIC_LOG(ERROR, TAG, "PostOwnerCredential : Failed to generate query");
1400         return OC_STACK_ERROR;
1401     }
1402     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1403     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1404     if(!secPayload)
1405     {
1406         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1407         return OC_STACK_NO_MEMORY;
1408     }
1409
1410     //Generate owner credential for new device
1411     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1412     const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
1413     if(!ownerCredential)
1414     {
1415         OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
1416         return OC_STACK_NO_RESOURCE;
1417     }
1418
1419     OicUuid_t credSubjectId = {.id={0}};
1420     if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
1421     {
1422         OicSecCred_t newCredential;
1423         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
1424         newCredential.next = NULL;
1425
1426         //Set subject ID as PT's ID
1427         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
1428
1429         //Fill private data as empty string
1430         newCredential.privateData.data = (uint8_t*)"";
1431         newCredential.privateData.len = 0;
1432         newCredential.privateData.encoding = ownerCredential->privateData.encoding;
1433
1434         newCredential.publicData.data = NULL;
1435         newCredential.publicData.len = 0;
1436         newCredential.publicData.encoding = ownerCredential->publicData.encoding;
1437
1438         int secureFlag = 0;
1439         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
1440         if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
1441                                         &secPayload->payloadSize, secureFlag))
1442         {
1443             OICFree(secPayload);
1444             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1445             return OC_STACK_ERROR;
1446         }
1447         OIC_LOG(DEBUG, TAG, "Cred Payload:");
1448         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1449
1450         OCCallbackData cbData;
1451         cbData.cb = &OwnerCredentialHandler;
1452         cbData.context = (void *)otmCtx;
1453         cbData.cd = NULL;
1454         OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1455                                          &deviceInfo->endpoint, (OCPayload*)secPayload,
1456                                          deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1457         if (res != OC_STACK_OK)
1458         {
1459             OIC_LOG(ERROR, TAG, "OCStack resource error");
1460         }
1461     }
1462     else
1463     {
1464         OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
1465         return OC_STACK_NO_RESOURCE;
1466     }
1467
1468     OIC_LOG(DEBUG, TAG, "OUT PostOwnerCredential");
1469
1470     return OC_STACK_OK;
1471 }
1472
1473 static OicSecAcl_t* GenerateOwnerAcl(const OicUuid_t* owner)
1474 {
1475     OicSecAcl_t* ownerAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
1476     OicSecAce_t* ownerAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1477     OicSecRsrc_t* wildcardRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1478     if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1479     {
1480         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1481         goto error;
1482     }
1483     LL_APPEND(ownerAcl->aces, ownerAce);
1484     LL_APPEND(ownerAce->resources, wildcardRsrc);
1485
1486     //Set resource owner as PT
1487     memcpy(ownerAcl->rownerID.id, owner->id, sizeof(owner->id));
1488
1489     //PT has full permission.
1490     ownerAce->permission = PERMISSION_FULL_CONTROL;
1491
1492     //Set subject as PT's UUID
1493     memcpy(ownerAce->subjectuuid.id, owner->id, sizeof(owner->id));
1494
1495     wildcardRsrc->href = OICStrdup(WILDCARD_RESOURCE_URI);
1496     if(NULL == wildcardRsrc->href)
1497     {
1498         goto error;
1499     }
1500
1501     wildcardRsrc->interfaceLen = 1;
1502     wildcardRsrc->interfaces = (char**)OICMalloc(wildcardRsrc->interfaceLen * sizeof(char*));
1503     if(NULL == wildcardRsrc->interfaces)
1504     {
1505         goto error;
1506     }
1507     wildcardRsrc->interfaces[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1508     if(NULL == wildcardRsrc->interfaces[0])
1509     {
1510         goto error;
1511     }
1512
1513     wildcardRsrc->typeLen = 1;
1514     wildcardRsrc->types = (char**)OICMalloc(wildcardRsrc->typeLen * sizeof(char*));
1515     if(NULL == wildcardRsrc->types)
1516     {
1517         goto error;
1518     }
1519     wildcardRsrc->types[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1520     if(NULL == wildcardRsrc->types[0])
1521     {
1522         goto error;
1523     }
1524
1525     return ownerAcl;
1526
1527 error:
1528     //in case of memory allocation failed, each resource should be removed individually.
1529     if(NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1530     {
1531         OICFree(ownerAcl);
1532         OICFree(ownerAce);
1533         OICFree(wildcardRsrc);
1534     }
1535     else
1536     {
1537         DeleteACLList(ownerAcl);
1538     }
1539     return NULL;
1540 }
1541
1542 /**
1543  * Function to update the owner ACL to new device.
1544  *
1545  * @param[in]  otmCtx  Context value of ownership transfer.
1546  * @return  OC_STACK_OK on success
1547  */
1548 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx)
1549 {
1550     OCStackResult res = OC_STACK_ERROR;
1551
1552     OIC_LOG(DEBUG, TAG, "IN PostOwnerAcl");
1553
1554     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1555     {
1556         OIC_LOG(ERROR, TAG, "Invalid parameters");
1557         return OC_STACK_INVALID_PARAM;
1558     }
1559
1560     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1561     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1562     OicSecAcl_t* ownerAcl = NULL;
1563
1564     if(!PMGenerateQuery(true,
1565                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1566                         deviceInfo->connType,
1567                         query, sizeof(query), OIC_RSRC_ACL_URI))
1568     {
1569         OIC_LOG(ERROR, TAG, "Failed to generate query");
1570         return OC_STACK_ERROR;
1571     }
1572     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1573
1574     OicUuid_t ownerID;
1575     res = GetDoxmDeviceID(&ownerID);
1576     if(OC_STACK_OK != res)
1577     {
1578         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1579         return res;
1580     }
1581
1582     //Generate owner ACL for new device
1583     ownerAcl = GenerateOwnerAcl(&ownerID);
1584     if(NULL == ownerAcl)
1585     {
1586         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1587         return OC_STACK_NO_MEMORY;
1588     }
1589
1590     //Generate ACL payload
1591     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1592     if(!secPayload)
1593     {
1594         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1595         res = OC_STACK_NO_MEMORY;
1596         goto error;
1597     }
1598
1599     res = AclToCBORPayload(ownerAcl, &secPayload->securityData, &secPayload->payloadSize);
1600     if (OC_STACK_OK != res)
1601     {
1602         OICFree(secPayload);
1603         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1604         goto error;
1605     }
1606     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1607
1608     OIC_LOG(DEBUG, TAG, "Owner ACL Payload:");
1609     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1610
1611     //Send owner ACL to new device : POST /oic/sec/cred [ owner credential ]
1612     OCCallbackData cbData;
1613     cbData.cb = &OwnerAclHandler;
1614     cbData.context = (void *)otmCtx;
1615     cbData.cd = NULL;
1616     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1617                                      &deviceInfo->endpoint, (OCPayload*)secPayload,
1618                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1619     if (res != OC_STACK_OK)
1620     {
1621         OIC_LOG(ERROR, TAG, "OCStack resource error");
1622         goto error;
1623     }
1624
1625     OIC_LOG(DEBUG, TAG, "OUT PostOwnerAcl");
1626
1627 error:
1628     DeleteACLList(ownerAcl);
1629
1630     return OC_STACK_OK;
1631 }
1632
1633 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx)
1634 {
1635     OIC_LOG(DEBUG, TAG, "IN PostOwnerTransferModeToResource");
1636
1637     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1638     {
1639         OIC_LOG(ERROR, TAG, "Invalid parameters");
1640         return OC_STACK_INVALID_PARAM;
1641     }
1642
1643     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1644     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1645
1646     if(!PMGenerateQuery(false,
1647                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1648                         deviceInfo->connType,
1649                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1650     {
1651         OIC_LOG(ERROR, TAG, "PostOwnerTransferModeToResource : Failed to generate query");
1652         return OC_STACK_ERROR;
1653     }
1654     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1655
1656     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1657     if(!secPayload)
1658     {
1659         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1660         return OC_STACK_NO_MEMORY;
1661     }
1662
1663     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1664     OCStackResult res = otmCtx->otmCallback.createSelectOxmPayloadCB(otmCtx,
1665             &secPayload->securityData, &secPayload->payloadSize);
1666     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1667     {
1668         OCPayloadDestroy((OCPayload *)secPayload);
1669         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
1670         return OC_STACK_ERROR;
1671     }
1672
1673     OCCallbackData cbData;
1674     cbData.cb = &OwnerTransferModeHandler;
1675     cbData.context = (void *)otmCtx;
1676     cbData.cd = NULL;
1677     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1678                        &deviceInfo->endpoint, (OCPayload *)secPayload,
1679                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1680     if (res != OC_STACK_OK)
1681     {
1682         OIC_LOG(ERROR, TAG, "OCStack resource error");
1683     }
1684
1685     OIC_LOG(DEBUG, TAG, "OUT PostOwnerTransferModeToResource");
1686
1687     return res;
1688 }
1689
1690 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1691 {
1692     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1693
1694     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1695     {
1696         OIC_LOG(ERROR, TAG, "Invailed parameters");
1697         return OC_STACK_INVALID_PARAM;
1698     }
1699
1700     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1701     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1702     if(!PMGenerateQuery(false,
1703                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1704                         deviceInfo->connType,
1705                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1706     {
1707         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1708         return OC_STACK_ERROR;
1709     }
1710     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1711
1712     OCCallbackData cbData;
1713     cbData.cb = &ListMethodsHandler;
1714     cbData.context = (void *)otmCtx;
1715     cbData.cd = NULL;
1716     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
1717                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1718     if (res != OC_STACK_OK)
1719     {
1720         OIC_LOG(ERROR, TAG, "OCStack resource error");
1721     }
1722
1723     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1724
1725     return res;
1726 }
1727
1728 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
1729 {
1730     OIC_LOG(DEBUG, TAG, "IN PostOwnerUuid");
1731
1732     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1733     {
1734         OIC_LOG(ERROR, TAG, "Invailed parameters");
1735         return OC_STACK_INVALID_PARAM;
1736     }
1737
1738     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1739     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1740     if(!PMGenerateQuery(true,
1741                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1742                         deviceInfo->connType,
1743                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1744     {
1745         OIC_LOG(ERROR, TAG, "PostOwnerUuid : Failed to generate query");
1746         return OC_STACK_ERROR;
1747     }
1748     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1749
1750     //Post PT's uuid to new device
1751     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1752     if(!secPayload)
1753     {
1754         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1755         return OC_STACK_NO_MEMORY;
1756     }
1757     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1758     OCStackResult res = otmCtx->otmCallback.createOwnerTransferPayloadCB(
1759             otmCtx, &secPayload->securityData, &secPayload->payloadSize);
1760     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1761     {
1762         OCPayloadDestroy((OCPayload *)secPayload);
1763         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
1764         return OC_STACK_INVALID_PARAM;
1765     }
1766     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1767
1768     OCCallbackData cbData;
1769     cbData.cb = &OwnerUuidUpdateHandler;
1770     cbData.context = (void *)otmCtx;
1771     cbData.cd = NULL;
1772
1773     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1774             deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1775     if (res != OC_STACK_OK)
1776     {
1777         OIC_LOG(ERROR, TAG, "OCStack resource error");
1778     }
1779
1780     OIC_LOG(DEBUG, TAG, "OUT PostOwnerUuid");
1781
1782     return res;
1783 }
1784
1785 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
1786 {
1787     OIC_LOG(DEBUG, TAG, "IN PostOwnershipInformation");
1788
1789     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1790     {
1791         OIC_LOG(ERROR, TAG, "Invailed parameters");
1792         return OC_STACK_INVALID_PARAM;
1793     }
1794
1795     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1796     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1797     if(!PMGenerateQuery(true,
1798                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1799                         deviceInfo->connType,
1800                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1801     {
1802         OIC_LOG(ERROR, TAG, "PostOwnershipInformation : Failed to generate query");
1803         return OC_STACK_ERROR;
1804     }
1805     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1806
1807     //OwnershipInformationHandler
1808     OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1809     if (!secPayload)
1810     {
1811         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1812         return OC_STACK_NO_MEMORY;
1813     }
1814
1815     otmCtx->selectedDeviceInfo->doxm->owned = true;
1816
1817     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1818     OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
1819             &secPayload->securityData, &secPayload->payloadSize, true);
1820     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1821     {
1822         OCPayloadDestroy((OCPayload *)secPayload);
1823         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1824         return OC_STACK_INVALID_PARAM;
1825     }
1826
1827     OCCallbackData cbData;
1828     cbData.cb = &OwnershipInformationHandler;
1829     cbData.context = (void *)otmCtx;
1830     cbData.cd = NULL;
1831
1832     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
1833                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1834     if (res != OC_STACK_OK)
1835     {
1836         OIC_LOG(ERROR, TAG, "OCStack resource error");
1837     }
1838
1839     OIC_LOG(DEBUG, TAG, "OUT PostOwnershipInformation");
1840
1841     return res;
1842 }
1843
1844 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
1845 {
1846     OIC_LOG(DEBUG, TAG, "IN PostUpdateOperationMode");
1847
1848     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1849     {
1850         return OC_STACK_INVALID_PARAM;
1851     }
1852
1853     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1854     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1855     if(!PMGenerateQuery(false,
1856                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1857                         deviceInfo->connType,
1858                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1859     {
1860         OIC_LOG(ERROR, TAG, "PostUpdateOperationMode : Failed to generate query");
1861         return OC_STACK_ERROR;
1862     }
1863     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1864
1865     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1866     if(!secPayload)
1867     {
1868         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1869         return OC_STACK_NO_MEMORY;
1870     }
1871     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1872     OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
1873                                            &secPayload->payloadSize, true);
1874    if (OC_STACK_OK != res)
1875     {
1876         OCPayloadDestroy((OCPayload *)secPayload);
1877         OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
1878         return OC_STACK_INVALID_PARAM;
1879     }
1880
1881     OCCallbackData cbData;
1882     cbData.cb = &OperationModeUpdateHandler;
1883     cbData.context = (void *)otmCtx;
1884     cbData.cd = NULL;
1885     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
1886                        deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1887     if (res != OC_STACK_OK)
1888     {
1889         OIC_LOG(ERROR, TAG, "OCStack resource error");
1890     }
1891
1892     OIC_LOG(DEBUG, TAG, "OUT PostUpdateOperationMode");
1893
1894     return res;
1895 }
1896
1897 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
1898 {
1899     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
1900     OCStackResult res = OC_STACK_INVALID_PARAM;
1901
1902     VERIFY_NOT_NULL(TAG, selectedDevice, ERROR);
1903     VERIFY_NOT_NULL(TAG, selectedDevice->doxm, ERROR);
1904
1905     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1906     otmCtx->selectedDeviceInfo = selectedDevice;
1907
1908     //Checking duplication of Device ID.
1909     bool isDuplicate = true;
1910     res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
1911     if (OC_STACK_OK != res)
1912     {
1913         OIC_LOG(ERROR, TAG, "Internal error in PDMIsDuplicateDevice");
1914         return res;
1915     }
1916     if (isDuplicate)
1917     {
1918         PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
1919         res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &state);
1920         if(OC_STACK_OK != res)
1921         {
1922             OIC_LOG(ERROR, TAG, "Internal error in PDMGetDeviceState");
1923             SetResult(otmCtx, res);
1924             return res;
1925         }
1926
1927         char* strUuid = NULL;
1928         res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
1929         if(OC_STACK_OK != res)
1930         {
1931             OIC_LOG(ERROR, TAG, "Failed to convert UUID to str");
1932             SetResult(otmCtx, res);
1933             return res;
1934         }
1935
1936         if(PDM_DEVICE_STALE == state)
1937         {
1938             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
1939                                "device status will revert back to initial status.");
1940             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
1941             if(OC_STACK_OK != res)
1942             {
1943                 OIC_LOG(ERROR, TAG, "Internal error in PDMSetDeviceState");
1944                 OICFree(strUuid);
1945                 SetResult(otmCtx, res);
1946                 return res;
1947             }
1948         }
1949         else if(PDM_DEVICE_INIT == state)
1950         {
1951             OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
1952             OICFree(strUuid);
1953             SetResult(otmCtx, OC_STACK_DUPLICATE_REQUEST);
1954             return OC_STACK_OK;
1955         }
1956         else
1957         {
1958             OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
1959             OICFree(strUuid);
1960             SetResult(otmCtx, OC_STACK_ERROR);
1961             return OC_STACK_ERROR;
1962         }
1963     }
1964     else
1965     {
1966         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
1967         if(OC_STACK_OK != res)
1968         {
1969             OIC_LOG(ERROR, TAG, "Internal error in PDMAddDevice");
1970             SetResult(otmCtx, res);
1971             return res;
1972         }
1973     }
1974
1975     //Select the OxM to performing ownership transfer
1976     res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
1977                                           selectedDevice->doxm->oxmLen,
1978                                           &selectedDevice->doxm->oxmSel,
1979                                           SUPER_OWNER);
1980     if(OC_STACK_OK != res)
1981     {
1982         OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
1983         SetResult(otmCtx, res);
1984         return res;
1985     }
1986     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
1987
1988     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
1989     if(OC_STACK_OK != res)
1990     {
1991         OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
1992         return res;
1993     }
1994
1995     //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
1996     res = PostOwnerTransferModeToResource(otmCtx);
1997     if(OC_STACK_OK != res)
1998     {
1999         OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
2000         SetResult(otmCtx, res);
2001         return res;
2002     }
2003
2004 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2005     //Register TLS event handler to catch the tls event while handshake
2006     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2007     {
2008         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2009     }
2010 #endif // __WITH_DTLS__ or __WITH_TLS__
2011     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2012
2013 exit:
2014     return res;
2015 }
2016
2017 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
2018 {
2019     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
2020
2021     if(!data)
2022     {
2023         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
2024         return OC_STACK_INVALID_PARAM;
2025     }
2026     if(oxmType >= OIC_OXM_COUNT)
2027     {
2028         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
2029         return OC_STACK_INVALID_PARAM;
2030     }
2031
2032     // TODO: Remove this API, Please see the jira ticket IOT-1484
2033
2034     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
2035
2036     return OC_STACK_OK;
2037 }
2038
2039 /**
2040  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
2041  */
2042 OCStackResult OTMDoOwnershipTransfer(void* ctx,
2043                                      OCProvisionDev_t *selectedDevicelist,
2044                                      OCProvisionResultCB resultCallback)
2045 {
2046     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
2047
2048     if (NULL == selectedDevicelist)
2049     {
2050         return OC_STACK_INVALID_PARAM;
2051     }
2052     if (NULL == resultCallback)
2053     {
2054         return OC_STACK_INVALID_CALLBACK;
2055     }
2056
2057     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2058     if(!otmCtx)
2059     {
2060         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2061         return OC_STACK_NO_MEMORY;
2062     }
2063     otmCtx->ctxResultCallback = resultCallback;
2064     otmCtx->ctxHasError = false;
2065     otmCtx->userCtx = ctx;
2066     OCProvisionDev_t* pCurDev = selectedDevicelist;
2067
2068     //Counting number of selected devices.
2069     otmCtx->ctxResultArraySize = 0;
2070     while(NULL != pCurDev)
2071     {
2072         otmCtx->ctxResultArraySize++;
2073         pCurDev = pCurDev->next;
2074     }
2075
2076     otmCtx->ctxResultArray =
2077         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2078     if(NULL == otmCtx->ctxResultArray)
2079     {
2080         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2081         OICFree(otmCtx);
2082         return OC_STACK_NO_MEMORY;
2083     }
2084     pCurDev = selectedDevicelist;
2085
2086     //Fill the device UUID for result array.
2087     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
2088     {
2089         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
2090                pCurDev->doxm->deviceID.id,
2091                UUID_LENGTH);
2092         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
2093         pCurDev = pCurDev->next;
2094     }
2095
2096     OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist);
2097
2098     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
2099
2100     return res;
2101 }
2102
2103 OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
2104 {
2105     OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
2106               __func__, oxm, (allowStatus ? "true" : "false"));
2107
2108 #ifdef MULTIPLE_OWNER
2109     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
2110 #else
2111     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
2112 #endif
2113     {
2114         return OC_STACK_INVALID_PARAM;
2115     }
2116
2117     OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
2118     if(OXM_IDX_COUNT <= oxmIdx)
2119     {
2120         OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
2121         return OC_STACK_ERROR;
2122     }
2123     g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
2124
2125     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2126
2127     return OC_STACK_OK;
2128 }
2129
2130 OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
2131 {
2132     OIC_LOG(INFO, TAG, "IN PostProvisioningStatus");
2133
2134     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2135     {
2136         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2137         return OC_STACK_INVALID_PARAM;
2138     }
2139
2140     //Change the TAKE_OWNER bit of CM to 0.
2141     otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
2142
2143     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2144     if (!secPayload)
2145     {
2146         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2147         return OC_STACK_NO_MEMORY;
2148     }
2149     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2150     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2151             &secPayload->securityData, &secPayload->payloadSize, true))
2152     {
2153         OCPayloadDestroy((OCPayload *)secPayload);
2154         return OC_STACK_INVALID_JSON;
2155     }
2156     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2157     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2158
2159     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2160     if(!PMGenerateQuery(true,
2161                         otmCtx->selectedDeviceInfo->endpoint.addr,
2162                         otmCtx->selectedDeviceInfo->securePort,
2163                         otmCtx->selectedDeviceInfo->connType,
2164                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2165     {
2166         OIC_LOG(ERROR, TAG, "PostProvisioningStatus : Failed to generate query");
2167         return OC_STACK_ERROR;
2168     }
2169     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2170
2171     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2172     cbData.cb = &ProvisioningStatusHandler;
2173     cbData.context = (void*)otmCtx;
2174     cbData.cd = NULL;
2175     OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2176             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2177     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2178     if (ret != OC_STACK_OK)
2179     {
2180         OIC_LOG(ERROR, TAG, "OCStack resource error");
2181     }
2182
2183     OIC_LOG(INFO, TAG, "OUT PostProvisioningStatus");
2184
2185     return ret;
2186 }
2187
2188 OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
2189 {
2190     OIC_LOG(INFO, TAG, "IN PostNormalOperationStatus");
2191
2192     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2193     {
2194         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2195         return OC_STACK_INVALID_PARAM;
2196     }
2197
2198     //Set isop to true.
2199     otmCtx->selectedDeviceInfo->pstat->isOp = true;
2200
2201     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2202     if (!secPayload)
2203     {
2204         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2205         return OC_STACK_NO_MEMORY;
2206     }
2207     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2208     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
2209             &secPayload->securityData, &secPayload->payloadSize, true))
2210     {
2211         OCPayloadDestroy((OCPayload *)secPayload);
2212         return OC_STACK_INVALID_JSON;
2213     }
2214     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2215     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2216
2217     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2218     if(!PMGenerateQuery(true,
2219                         otmCtx->selectedDeviceInfo->endpoint.addr,
2220                         otmCtx->selectedDeviceInfo->securePort,
2221                         otmCtx->selectedDeviceInfo->connType,
2222                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2223     {
2224         OIC_LOG(ERROR, TAG, "PostNormalOperationStatus : Failed to generate query");
2225         return OC_STACK_ERROR;
2226     }
2227     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2228
2229     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
2230     cbData.cb = &ReadyForNomalStatusHandler;
2231     cbData.context = (void*)otmCtx;
2232     cbData.cd = NULL;
2233     OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2234             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
2235     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
2236     if (ret != OC_STACK_OK)
2237     {
2238         OIC_LOG(ERROR, TAG, "OCStack resource error");
2239     }
2240
2241     OIC_LOG(INFO, TAG, "OUT PostNormalOperationStatus");
2242
2243     return ret;
2244 }
2245
2246 OCStackResult ConfigSelfOwnership(void)
2247 {
2248     OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership");
2249
2250     bool isDeviceOwned = true;
2251     if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned))
2252     {
2253         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state");
2254         return OC_STACK_ERROR;
2255     }
2256     if( (true == isDeviceOwned) ||(true == GetPstatIsop()) )
2257     {
2258         OIC_LOG(ERROR, TAG, "The state of device is not Ready for Ownership transfer.");
2259         return OC_STACK_ERROR;
2260     }
2261     OicUuid_t deviceID = {.id={0}};
2262     if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2263     {
2264         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2265         return OC_STACK_ERROR;
2266     }
2267
2268     OCStackResult ret = OC_STACK_OK;
2269     //Update the pstat resource as Normal Operation.
2270     ret = SetPstatSelfOwnership(&deviceID);
2271     if(OC_STACK_OK != ret)
2272     {
2273         OIC_LOG (ERROR, TAG, "Unable to update pstat resource as Normal Operation");
2274         goto exit;
2275     }
2276     //Update the doxm resource as Normal Operation.
2277     ret = SetDoxmSelfOwnership(&deviceID);
2278     if(OC_STACK_OK != ret)
2279     {
2280         OIC_LOG (ERROR, TAG, "Unable to update doxm resource as Normal Operation");
2281         goto exit;
2282     }
2283     //Update default ACE of security resource to prevent anonymous user access.
2284     ret = UpdateDefaultSecProvACE();
2285     if(OC_STACK_OK != ret)
2286     {
2287         OIC_LOG (ERROR, TAG, "Unable to update default ace in ConfigSelfOwnership");
2288         goto exit;
2289     }
2290     //Update the acl resource owner as owner device.
2291     ret = SetAclRownerId(&deviceID);
2292     if(OC_STACK_OK != ret)
2293     {
2294         OIC_LOG (ERROR, TAG, "Unable to update acl resource in ConfigSelfOwnership");
2295         goto exit;
2296     }
2297     //Update the cred resource owner as owner device.
2298     ret = SetCredRownerId(&deviceID);
2299     if(OC_STACK_OK != ret)
2300     {
2301         // Cred resouce may be empty in Ready for Ownership transfer state.
2302         if (OC_STACK_NO_RESOURCE == ret)
2303         {
2304             OIC_LOG (INFO, TAG, "Cred resource is empty");
2305             ret = OC_STACK_OK;
2306             goto exit;
2307         }
2308         OIC_LOG (ERROR, TAG, "Unable to update cred resource in ConfigSelfOwnership");
2309     }
2310
2311 exit:
2312     if(OC_STACK_OK != ret)
2313     {
2314         /*
2315          * If some error is occured while configure self-ownership,
2316          * ownership related resource should be revert back to initial status.
2317         */
2318         ResetSecureResourceInPS();
2319     }
2320
2321     return ret;
2322 }