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