some errors fix
[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 #include <assert.h>
46 #include <coap/pdu.h>
47
48 #include "experimental/logger.h"
49 #include "oic_malloc.h"
50 #include "oic_string.h"
51 #include "cacommon.h"
52 #include "cainterface.h"
53 #include "mbedtls/base64.h"
54 #include "utlist.h"
55 #include "srmresourcestrings.h"
56 #include "experimental/doxmresource.h"
57 #include "pstatresource.h"
58 #include "credresource.h"
59 #include "aclresource.h"
60 #include "ownershiptransfermanager.h"
61 #include "secureresourceprovider.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 "experimental/payload_logging.h"
75 #include "pkix_interface.h"
76 #include "oxmverifycommon.h"
77 #include "psinterface.h"
78 #include "ocstackinternal.h"
79 #include "deviceonboardingstate.h"
80
81 #define TAG "OIC_OTM"
82
83
84 #define ALLOWED_OXM         1
85 #define NOT_ALLOWED_OXM     0
86
87 /**
88  * List of allowed oxm list.
89  * All oxm methods are allowed as default.
90  */
91 #ifdef MULTIPLE_OWNER
92 static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
93                                                   ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
94                                                   NOT_ALLOWED_OXM};
95 #else
96 static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
97                                                   ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM};
98 #endif
99
100
101 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
102 {
103     OCStackResult res = OC_STACK_INVALID_PARAM;
104
105     OIC_LOG(INFO, TAG, "IN OTMSetOTCallback");
106
107     VERIFY_NOT_NULL(TAG, callbacks, ERROR);
108
109 #ifdef MULTIPLE_OWNER
110     VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm
111                     || OIC_CON_MFG_CERT == oxm), ERROR);
112 #else
113     VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm), ERROR);
114 #endif // MULTIPLE_OWNER
115
116     switch(oxm)
117     {
118     case OIC_JUST_WORKS:
119         callbacks->loadSecretCB = LoadSecretJustWorksCallback;
120         callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
121         callbacks->createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
122         callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
123         break;
124     case OIC_RANDOM_DEVICE_PIN:
125         callbacks->loadSecretCB = InputPinCodeCallback;
126         callbacks->createSecureSessionCB = CreateSecureSessionRandomPinCallback;
127         callbacks->createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
128         callbacks->createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
129         break;
130     case OIC_MANUFACTURER_CERTIFICATE:
131         callbacks->loadSecretCB = PrepareMCertificateCallback;
132         callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
133         callbacks->createSelectOxmPayloadCB = CreateMCertificateBasedSelectOxmPayload;
134         callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
135         break;
136     case OIC_DECENTRALIZED_PUBLIC_KEY:
137         OIC_LOG(ERROR, TAG, "OIC_DECENTRALIZED_PUBLIC_KEY not supported yet.");
138         return OC_STACK_INVALID_METHOD;
139 #ifdef MULTIPLE_OWNER
140     case OIC_PRECONFIG_PIN:
141         callbacks->loadSecretCB = LoadPreconfigPinCodeCallback;
142         callbacks->createSecureSessionCB = CreateSecureSessionPreconfigPinCallback;
143         callbacks->createSelectOxmPayloadCB = CreatePreconfigPinBasedSelectOxmPayload;
144         callbacks->createOwnerTransferPayloadCB = CreatePreconfigPinBasedOwnerTransferPayload;
145         break;
146 #endif //MULTIPLE_OWNER
147     case OIC_MV_JUST_WORKS:
148         callbacks->loadSecretCB = LoadSecretJustWorksCallback;
149         callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
150         callbacks->createSelectOxmPayloadCB = CreateMVJustWorksSelectOxmPayload;
151         callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
152         break;
153     case OIC_CON_MFG_CERT:
154         callbacks->loadSecretCB = PrepareMCertificateCallback;
155         callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
156         callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload;
157         callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
158         break;
159     default:
160         OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
161         return OC_STACK_INVALID_PARAM;
162         break;
163     }
164
165     res = OC_STACK_OK;
166 exit:
167     OIC_LOG(INFO, TAG, "OUT OTMSetOTCallback");
168     return res;
169 }
170
171 /**
172  * Internal API to convert OxM value to index of oxm allow table.
173  */
174 static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm)
175 {
176     switch(oxm)
177     {
178         case OIC_JUST_WORKS:
179             return OXM_IDX_JUST_WORKS;
180         case OIC_RANDOM_DEVICE_PIN:
181             return OXM_IDX_RANDOM_DEVICE_PIN;
182         case OIC_MANUFACTURER_CERTIFICATE:
183             return OXM_IDX_MANUFACTURER_CERTIFICATE;
184         case OIC_DECENTRALIZED_PUBLIC_KEY:
185             return OXM_IDX_DECENTRALIZED_PUBLIC_KEY;
186         case OIC_MV_JUST_WORKS:
187             return OXM_IDX_MV_JUST_WORKS;
188         case OIC_CON_MFG_CERT:
189             return OXM_IDX_CON_MFG_CERT;
190 #ifdef MULTIPLE_OWNER
191         case OIC_PRECONFIG_PIN:
192             return OXM_IDX_PRECONFIG_PIN;
193 #endif
194         default:
195             return OXM_IDX_UNKNOWN;
196     }
197 }
198
199 static uint16_t getSecurePort(const OCProvisionDev_t *device)
200 {
201     uint16_t port = 0;
202
203     if (NULL == device)
204     {
205         return port;
206     }
207
208     if (OC_ADAPTER_IP == device->endpoint.adapter)
209     {
210         port = device->securePort;
211     }
212 #ifdef WITH_TCP
213     else if (OC_ADAPTER_TCP == device->endpoint.adapter)
214     {
215         port = device->tcpSecurePort;
216     }
217 #endif
218
219     return port;
220 }
221
222 /**
223  * Internal API to close the secure Ownership Transfer session.
224  */
225 static bool CloseSslConnection(const OCProvisionDev_t *selectedDeviceInfo)
226 {
227     bool success = true;
228
229     CAEndpoint_t endpoint;
230     CopyDevAddrToEndpoint(&selectedDeviceInfo->endpoint, &endpoint);
231     endpoint.port = getSecurePort(selectedDeviceInfo);
232     CAResult_t caResult = CAcloseSslConnection(&endpoint);
233
234     if (CA_STATUS_OK != caResult)
235     {
236         OIC_LOG_V(ERROR, TAG, "%s: Failed to close DTLS session, caResult = %d",
237             __func__, caResult);
238         success = false;
239     }
240
241     return success;
242 }
243
244 static void SetCBORFormat(OCHeaderOption *options, uint8_t *numOptions)
245 {
246     options->optionID = COAP_OPTION_ACCEPT;
247     options->optionLength = sizeof(uint8_t);
248     options->optionData [0]= COAP_MEDIATYPE_APPLICATION_CBOR;
249     (*numOptions)++;
250 }
251
252 /**
253  * Function to select appropriate  provisioning method.
254  *
255  * @param[in] supportedMethods   Array of supported methods
256  * @param[in] numberOfMethods   number of supported methods
257  * @param[out]  selectedMethod         Selected methods
258  * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)
259  * @return  OC_STACK_OK on success
260  */
261 OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
262         size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType)
263 {
264     bool isOxmSelected = false;
265     OxmAllowTableIdx_t selectedOxmIdx = OXM_IDX_UNKNOWN;
266
267     OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
268
269     if (numberOfMethods == 0 || !supportedMethods)
270     {
271         OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
272         return OC_STACK_ERROR;
273     }
274
275     switch(ownerType)
276     {
277         case SUPER_OWNER:
278         {
279             for (size_t i = 0; i < numberOfMethods; i++)
280             {
281                 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
282                 if (OXM_IDX_COUNT <= selectedOxmIdx)
283                 {
284                     OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
285                     continue;
286                 }
287
288 #ifdef MULTIPLE_OWNER
289                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
290                    OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
291 #else
292                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
293 #endif //MULTIPLE_OWNER
294                 {
295                     *selectedMethod  = supportedMethods[i];
296                     isOxmSelected = true;
297                 }
298             }
299         }
300         break;
301 #ifdef MULTIPLE_OWNER
302         case SUB_OWNER:
303         {
304             for (size_t i = 0; i < numberOfMethods; i++)
305             {
306                 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
307                 if (OXM_IDX_COUNT <= selectedOxmIdx)
308                 {
309                     OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
310                     continue;
311                 }
312
313                 //in case of MOT, only Random PIN & Preconfigured PIN based OxM is allowed
314                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
315                     (OXM_IDX_RANDOM_DEVICE_PIN == selectedOxmIdx ||
316                      OXM_IDX_PRECONFIG_PIN == selectedOxmIdx))
317                 {
318                     *selectedMethod  = supportedMethods[i];
319                     isOxmSelected = true;
320                 }
321             }
322         }
323         break;
324 #endif
325         default:
326         {
327             OIC_LOG_V(ERROR, TAG, "Unknown owner type or Not supported owner type : %d", ownerType);
328             return OC_STACK_INVALID_PARAM;
329         }
330     }
331
332     if (!isOxmSelected)
333     {
334         OIC_LOG(ERROR, TAG, "Can not find the allowed OxM.");
335         return OC_STACK_NOT_ALLOWED_OXM;
336     }
337
338     OIC_LOG(DEBUG, TAG, "OUT SelectProvisioningMethod");
339
340     return OC_STACK_OK;
341 }
342
343 /**
344  * Function to select operation mode.This function will return most secure common operation mode.
345  *
346  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
347  * @param[out]   selectedMode   selected operation mode
348  * @return  OC_STACK_OK on success
349  */
350 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
351                                 OicSecDpom_t *selectedMode)
352 {
353     OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
354     *selectedMode = selectedDeviceInfo->pstat->sm[0];
355     OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
356 }
357
358 /**
359  * Function to start ownership transfer.
360  * This function will send the first request for provisioning,
361  * The next request message is sent from the response handler for this request.
362  *
363  * @param[in] ctx   context value passed to callback from calling function.
364  * @param[in] selectedDevice   selected device information to performing provisioning.
365  * @return  OC_STACK_OK on success
366  */
367 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
368
369 /*
370  * Internal function to setup & cleanup PDM to performing provisioning.
371  *
372  * @param[in] selectedDevice   selected device information to performing provisioning.
373  * @return  OC_STACK_OK on success
374  */
375 static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice);
376
377 /**
378  * Function to update owner transfer mode
379  *
380  * @param[in]  otmCtx  Context value of ownership transfer.
381  * @return  OC_STACK_OK on success
382  */
383 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx);
384
385 /**
386  * Function to send request to resource to get its pstat resource information.
387  *
388  * @param[in]  otmCtx  Context value of ownership transfer.
389  * @return  OC_STACK_OK on success
390  */
391 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
392
393 /**
394  * Function to send a GET request to /oic/sec/doxm, using the OTM-secured session.
395  * The property values obtained this way are then compared with the values obtained
396  * before establishing the secured session. If the two sets of values are different,
397  * ownership transfer is automatically cancelled.
398  *
399  * @param[in]  otmCtx  Context value of ownership transfer.
400  * @return  OC_STACK_OK on success
401  */
402 static OCStackResult GetAndVerifyDoxmResource(OTMContext_t* otmCtx);
403
404 /**
405  * Function to send an extra GET request to /oic/sec/doxm,
406  * for obtaining new device uuid.
407  *
408  * @param[in]  otmCtx  Context value of ownership transfer.
409  * @return  OC_STACK_OK on success
410  */
411 static OCStackResult GetRealUuid(OTMContext_t* otmCtx);
412
413 /**
414  * Function to send uuid of owner device to new device.
415  * This function would update 'owner of doxm' as UUID for provisioning tool.
416  *
417  * @param[in]  otmCtx  Context value of ownership transfer.
418  * @return  OC_STACK_OK on success
419  */
420 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx);
421
422 /**
423  * Function to update the operation mode. As per the spec. Operation mode in client driven
424  * single service provisioning it will be updated to 0x3
425  *
426  * @param[in]  otmCtx  Context value of ownership transfer.
427  * @return  OC_STACK_OK on success
428  */
429 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx);
430
431 /**
432  * Function to update the owner credential to new device
433  *
434  * @param[in]  otmCtx  Context value of ownership transfer.
435  * @param[in] selectedOperationMode selected operation mode
436  * @return  OC_STACK_OK on success
437  */
438 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx);
439
440 /**
441  * Function to update the owner ACL to new device.
442  *
443  * @param[in]  otmCtx  Context value of ownership transfer.
444  * @return  OC_STACK_OK on success
445  */
446 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx, OicSecAclVersion_t aclVer);
447
448 /**
449  * Function to send ownerShip info.
450  * This function would update 'owned of doxm' as true.
451  *
452  * @param[in]  otmCtx  Context value of ownership transfer.
453  * @return  OC_STACK_OK on success
454  */
455 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx);
456
457 /**
458  * Function to update pstat as Ready for provisioning.
459  * This function would update 'dos.s' to DOS_RFPRO.
460  *
461  * @param[in] ctx   context value passed to callback from calling function.
462  * @param[in] selectedDevice   selected device information to performing provisioning.
463  * @return  OC_STACK_OK on success
464  */
465 static OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx);
466
467 /**
468  * Function set pstat rowner uuid.
469  *
470  * @param[in] ctx   context value passed to callback from calling function.
471  * @param[in] selectedDevice   selected device information to performing provisioning.
472  * @return  OC_STACK_OK on success
473  */
474 static OCStackResult PostRownerUuid(OTMContext_t* otmCtx);
475
476 /**
477  * Function to update pstat as Ready for Normal Operation.
478  * This function would update 'dos.s' to DOS_RFNOP.
479  *
480  * @param[in] ctx   context value passed to callback from calling function.
481  * @param[in] selectedDevice   selected device information to performing provisioning.
482  * @return  OC_STACK_OK on success
483  */
484 static OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx);
485
486 static bool IsComplete(OTMContext_t* otmCtx)
487 {
488     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
489     {
490         if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
491         {
492             return false;
493         }
494     }
495
496     return true;
497 }
498
499 /**
500  * Function to save the result of provisioning.
501  *
502  * @param[in,out] otmCtx   Context value of ownership transfer.
503  * @param[in] res   result of provisioning
504  */
505 static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
506 {
507     OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
508
509     VERIFY_NOT_NULL(TAG, otmCtx, ERROR);
510     VERIFY_NOT_NULL(TAG, otmCtx->selectedDeviceInfo, ERROR);
511
512     //If OTM Context was removed from previous response handler, just exit the current OTM process.
513     if(NULL != GetOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
514                              getSecurePort(otmCtx->selectedDeviceInfo)))
515     {
516         OIC_LOG(WARNING, TAG, "Current OTM Process has already ended.");
517     }
518
519     VERIFY_NOT_NULL(TAG, otmCtx->selectedDeviceInfo->doxm, ERROR);
520
521     //Revert psk_info callback and new deivce uuid in case of random PIN OxM
522     if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
523     {
524         if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
525         {
526             OIC_LOG(WARNING, TAG, "Failed to revert  is DTLS credential handler.");
527         }
528         OicUuid_t emptyUuid = { .id={0}};
529         SetUuidForPinBasedOxm(&emptyUuid);
530     }
531     else if(OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel ||
532                         OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)
533     {
534         //Revert back certificate related callbacks.
535         if(CA_STATUS_OK != CAregisterPkixInfoHandler(GetPkixInfo))
536         {
537             OIC_LOG(WARNING, TAG, "Failed to revert PkixInfoHandler.");
538         }
539         if(CA_STATUS_OK != CAregisterIdentityHandler(GetIdentityHandler))
540         {
541             OIC_LOG(WARNING, TAG, "Failed to set IdentityHandler.");
542         }
543         if(CA_STATUS_OK != CAregisterGetCredentialTypesHandler(InitCipherSuiteList))
544         {
545             OIC_LOG(WARNING, TAG, "Failed to revert CredentialTypesHandler.");
546         }
547     }
548
549     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
550     {
551         if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
552                   otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
553         {
554             otmCtx->ctxResultArray[i].res = res;
555             if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res)
556             {
557                 otmCtx->ctxHasError = true;
558                 if (OC_STACK_OK != PDMDeleteDevice(&otmCtx->ctxResultArray[i].deviceId))
559                 {
560                     OIC_LOG(WARNING, TAG, "Internal error in PDMDeleteDevice");
561                 }
562                 CloseSslConnection(otmCtx->selectedDeviceInfo);
563             }
564         }
565     }
566
567     //In case of duplicated OTM process, OTMContext and OCDoHandle should not be removed.
568     if(OC_STACK_DUPLICATE_REQUEST != res)
569     {
570         //Remove the current OTM Context from OTM queue
571         RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
572                          getSecurePort(otmCtx->selectedDeviceInfo));
573
574         //If there is a request being performed, cancel it to prevent retransmission.
575         if(otmCtx->ocDoHandle)
576         {
577             OIC_LOG_V(DEBUG, TAG, "OCCancel - %s : %d",
578                     otmCtx->selectedDeviceInfo->endpoint.addr,
579                     getSecurePort(otmCtx->selectedDeviceInfo));
580             if(OC_STACK_OK != OCCancel(otmCtx->ocDoHandle, OC_HIGH_QOS, NULL, 0))
581             {
582                 OIC_LOG(WARNING, TAG, "Failed to remove registered callback");
583             }
584             else
585             {
586                 otmCtx->ocDoHandle = NULL;
587             }
588         }
589     }
590
591     //If all OTM process is complete, invoke the user callback.
592     if(IsComplete(otmCtx))
593     {
594         SetDosState(DOS_RFNOP);
595         otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
596                                    otmCtx->ctxResultArray, otmCtx->ctxHasError);
597         OICFree(otmCtx->ctxResultArray);
598         OICFree(otmCtx);
599     }
600     else
601     {
602         if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
603                                                  otmCtx->selectedDeviceInfo->next))
604         {
605             OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
606         }
607     }
608 exit:
609     OIC_LOG(DEBUG, TAG, "OUT SetResult");
610 }
611
612 static CAResult_t OwnershipTransferSessionEstablished(const CAEndpoint_t *endpoint,
613         OicSecDoxm_t *newDevDoxm, OTMContext_t *otmCtx)
614 {
615     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
616     CAResult_t result = CA_STATUS_OK;
617     OCStackResult res = OC_STACK_ERROR;
618     OC_UNUSED(otmCtx);
619
620     //In case of Mutual Verified Just-Works, display mutualVerifNum
621     if (OIC_MV_JUST_WORKS == newDevDoxm->oxmSel)
622     {
623         uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
624         uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
625         OicUuid_t deviceID = {.id = {0}};
626
627         //Generate mutualVerifNum
628         char label[LABEL_LEN] = {0};
629         snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS);
630         res = GetDoxmDeviceID(&deviceID);
631         if (OC_STACK_OK != res)
632         {
633             OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
634             result = CA_HANDLE_ERROR_OTHER_MODULE;
635             goto exit;
636         }
637         CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
638                 (uint8_t *)label,
639                 strlen(label),
640                 deviceID.id, sizeof(deviceID.id),
641                 newDevDoxm->deviceID.id, sizeof(newDevDoxm->deviceID.id),
642                 preMutualVerifNum, sizeof(preMutualVerifNum));
643
644         if (CA_STATUS_OK != pskRet)
645         {
646             OIC_LOG(WARNING, TAG, "CAGenerateOwnerPSK failed");
647             result = CA_HANDLE_ERROR_OTHER_MODULE;
648             goto exit;
649         }
650
651         memcpy(mutualVerifNum, preMutualVerifNum + sizeof(preMutualVerifNum) - sizeof(mutualVerifNum),
652                 sizeof(mutualVerifNum));
653         res = VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM);
654         if (OC_STACK_OK != res)
655         {
656             OIC_LOG(ERROR, TAG, "Error while displaying mutualVerifNum");
657             result = CA_HANDLE_ERROR_OTHER_MODULE;
658             goto exit;
659         }
660     }
661     //In case of confirmed manufacturer cert, display message
662     else if (OIC_CON_MFG_CERT == newDevDoxm->oxmSel)
663     {
664         res = VerifyOwnershipTransfer(NULL, DISPLAY_NUM);
665         if (OC_STACK_OK != res)
666         {
667             OIC_LOG(ERROR, TAG, "Error while displaying message");
668             result = CA_HANDLE_ERROR_OTHER_MODULE;
669             goto exit;
670         }
671     }
672
673 exit:
674     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
675     return result;
676 }
677
678 static CAResult_t OwnershipTransferSessionFailed(const CAEndpoint_t *endpoint,
679         const CAErrorInfo_t *info, OicSecDoxm_t *newDevDoxm, OTMContext_t *otmCtx, bool emptyOwnerUuid)
680 {
681     OC_UNUSED(endpoint);
682     CAResult_t result = CA_STATUS_OK;
683
684     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
685
686     if (CA_DTLS_AUTHENTICATION_FAILURE != info->result)
687     {
688         OIC_LOG_V(ERROR, TAG, "Ownership Transfer session establishment failed, error %u", info->result);
689         goto exit;
690     }
691
692     //in case of error from owner credential
693     if (!emptyOwnerUuid && newDevDoxm->owned)
694     {
695         OIC_LOG(ERROR, TAG, "The local copy of the owner credential may be incorrect - removing it.");
696         if (OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID)))
697         {
698             OIC_LOG(WARNING, TAG, "Failed to remove the invalid owner credential");
699         }
700         result = CA_HANDLE_ERROR_OTHER_MODULE;
701         goto exit;
702     }
703
704     //in case of error from wrong PIN, re-start the ownership transfer
705     if (OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel)
706     {
707         OIC_LOG(ERROR, TAG, "The PIN number may be incorrect.");
708
709         OicUuid_t emptyUuid = {.id={0}};
710         memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
711         newDevDoxm->owned = false;
712         otmCtx->attemptCnt++;
713
714         // In order to re-start ownership transfer, device information should be deleted from PDM.
715         OCStackResult res = PDMDeleteDevice(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
716         if (OC_STACK_OK != res)
717         {
718             OIC_LOG(ERROR, TAG, "Failed to PDMDeleteDevice");
719             result = CA_HANDLE_ERROR_OTHER_MODULE;
720         }
721         else
722         {
723             if (WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
724             {
725                 otmCtx->selectedDeviceInfo->connType = (OCConnectivityType)(otmCtx->selectedDeviceInfo->connType & ~CT_FLAG_SECURE);
726
727                 res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
728                 if (OC_STACK_OK != res)
729                 {
730                     OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
731                     result = CA_HANDLE_ERROR_OTHER_MODULE;
732                 }
733                 else
734                 {
735                     result = CA_CONTINUE_OPERATION;
736                 }
737             }
738             else
739             {
740                 OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
741                 result = CA_HANDLE_ERROR_OTHER_MODULE;
742             }
743         }
744         goto exit;
745     }
746
747     OIC_LOG(ERROR, TAG, "Failed to establish secure session.");
748
749 exit:
750     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
751     return result;
752 }
753
754 /**
755  * Function to handle the handshake result in OTM.
756  * This function will be invoked after DTLS handshake
757  * @param[in] endPoint   The remote endpoint.
758  * @param[in] errorInfo  Error information from the endpoint.
759  * @return  NONE
760  */
761 CAResult_t DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
762 {
763     OIC_LOG_V(DEBUG, TAG, "In %s(endpoint = %p, info = %p)", __func__, endpoint, info);
764
765     CAResult_t result = CA_STATUS_OK;
766     bool emptyOwnerUuid = false;
767     OicUuid_t emptyUuid = {.id={0}};
768     bool matching = false;
769     OicSecDoxm_t* newDevDoxm = NULL;
770     OTMContext_t* otmCtx = NULL;
771
772     if (NULL == endpoint || NULL == info)
773     {
774         goto exit;
775     }
776
777     OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
778               endpoint->addr, endpoint->port, info->result);
779
780     otmCtx = GetOTMContext(endpoint->addr, endpoint->port);
781     if (NULL == otmCtx)
782     {
783         OIC_LOG(ERROR, TAG, "OTM context not found!");
784         goto exit;
785     }
786
787     newDevDoxm = otmCtx->selectedDeviceInfo->doxm;
788     if (NULL == newDevDoxm)
789     {
790         OIC_LOG(ERROR, TAG, "New device doxm not found!");
791         goto exit;
792     }
793
794     //Make sure the address matches.
795     matching = (0 == strncmp(otmCtx->selectedDeviceInfo->endpoint.addr,
796                                   endpoint->addr, sizeof(endpoint->addr)));
797     matching = (matching && (getSecurePort(otmCtx->selectedDeviceInfo) == endpoint->port));
798
799     if (!matching)
800     {
801         OIC_LOG_V(ERROR, TAG, "Mismatched: expected address %s:%u",
802                   otmCtx->selectedDeviceInfo->endpoint.addr, getSecurePort(otmCtx->selectedDeviceInfo));
803         goto exit;
804     }
805
806     emptyOwnerUuid = (memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0);
807
808     //If temporal secure session established successfully
809     if ((CA_STATUS_OK == info->result) && !newDevDoxm->owned && emptyOwnerUuid)
810     {
811         result = OwnershipTransferSessionEstablished(endpoint, newDevDoxm, otmCtx);
812     }
813     else
814     {
815         result = OwnershipTransferSessionFailed(endpoint, info, newDevDoxm, otmCtx, emptyOwnerUuid);
816     }
817
818 exit:
819     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
820     return result;
821 }
822
823 /**
824  * Function to save the Owner/SubOwner PSK.
825  *
826  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
827  * @return  OC_STACK_OK on success
828  */
829 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
830 {
831     OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
832
833     OCStackResult res = OC_STACK_ERROR;
834
835     CAEndpoint_t endpoint;
836     CopyDevAddrToEndpoint(&selectedDeviceInfo->endpoint, &endpoint);
837     endpoint.port = getSecurePort(selectedDeviceInfo);
838
839     OicUuid_t ownerDeviceID = {.id={0}};
840     if (OC_STACK_OK != GetDoxmDeviceID(&ownerDeviceID))
841     {
842         OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
843         return res;
844     }
845
846     OicSecKey_t ownerKey;
847     memset(&ownerKey, 0, sizeof(ownerKey));
848
849     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = { 0 };
850     ownerKey.data = ownerPSK;
851     ownerKey.len = OWNER_PSK_LENGTH_128;
852     ownerKey.encoding = OIC_ENCODING_RAW;
853
854     //Generating OwnerPSK
855     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
856             (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
857             strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
858             ownerDeviceID.id, sizeof(ownerDeviceID.id),
859             selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
860             ownerPSK, OWNER_PSK_LENGTH_128);
861
862     if (CA_STATUS_OK == pskRet)
863     {
864         OIC_LOG(DEBUG, TAG,"Owner PSK dump:");
865         OIC_LOG_BUFFER(DEBUG, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
866         //Generating new credential for provisioning tool
867         OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
868                                   SYMMETRIC_PAIR_WISE_KEY, NULL,
869                                   &ownerKey, NULL);
870         OICClearMemory(ownerPSK, sizeof(ownerPSK));
871         VERIFY_NOT_NULL(TAG, cred, ERROR);
872
873         size_t outSize = 0;
874         int encodeResult = mbedtls_base64_encode(NULL, 0, &outSize, cred->privateData.data, cred->privateData.len);
875         if (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL != encodeResult)
876         {
877             OIC_LOG_V(ERROR, TAG, "%s: Error base64 encoding PSK private data", __func__);
878             res = OC_STACK_ERROR;
879             goto exit;
880         }
881         size_t b64BufSize = outSize;
882         unsigned char* b64Buf = (unsigned char *)OICCalloc(1, b64BufSize);
883         VERIFY_NOT_NULL(TAG, b64Buf, ERROR);
884        encodeResult =  mbedtls_base64_encode(b64Buf, b64BufSize, &outSize, cred->privateData.data, cred->privateData.len);
885        if (0 != encodeResult)
886        {
887            OIC_LOG_V(ERROR, TAG, "%s: Error base64 encoding PSK private data", __func__);
888            OICFree(b64Buf);
889            res = OC_STACK_ERROR;
890            goto exit;
891        }
892         OICFree( cred->privateData.data );
893         cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
894         VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
895
896         strncpy((char*)(cred->privateData.data), (char*)b64Buf, outSize);
897         cred->privateData.data[outSize] = '\0';
898         cred->privateData.encoding = OIC_ENCODING_BASE64;
899         cred->privateData.len = outSize;
900         OICFree(b64Buf);
901
902         //Finding previous ownerPSK.
903         const OicSecCred_t* credList = GetCredList();
904         const OicSecCred_t* prevCred = NULL;
905         uint16_t credId = 0;
906         LL_FOREACH(credList, prevCred)
907         {
908             //OwnerPSK's type is SYMMETRIC_PAIR_WISE_KEY
909             if (SYMMETRIC_PAIR_WISE_KEY == prevCred->credType &&
910                 0 == memcmp(prevCred->subject.id, cred->subject.id, sizeof(cred->subject.id)))
911             {
912                 credId = prevCred->credId;
913                 break;
914             }
915         }
916
917         //If duplicate owner PSK is exists, remove it.
918         if(0 < credId)
919         {
920             OIC_LOG(WARNING, TAG, "Duplicate OwnerPSK was detected.");
921             OIC_LOG(WARNING, TAG, "[Subject] : ");
922             OIC_LOG_BUFFER(WARNING, TAG, prevCred->subject.id, sizeof(prevCred->subject.id));
923             OIC_LOG_V(WARNING, TAG, "[Encoding Type] : %d", prevCred->privateData.encoding);
924             OIC_LOG(DEBUG, TAG, "[Private Data] : ");
925             OIC_LOG_BUFFER(DEBUG, TAG, prevCred->privateData.data, prevCred->privateData.len);
926             OIC_LOG(WARNING, TAG, "Previous OwnerPSK will be removed.");
927
928             res = RemoveCredentialByCredId(credId);
929             if(OC_STACK_RESOURCE_DELETED != res)
930             {
931                 OIC_LOG(ERROR, TAG, "Failed to remove the previous OwnerPSK");
932                 DeleteCredList(cred);
933                 goto exit;
934             }
935         }
936
937         res = AddCredential(cred);
938         if(res != OC_STACK_OK)
939         {
940             DeleteCredList(cred);
941             return res;
942         }
943     }
944     else
945     {
946         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
947     }
948
949     OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
950 exit:
951     return res;
952 }
953
954 /**
955  * Callback handler for OwnerShipTransferModeHandler API.
956  *
957  * @param[in] ctx             ctx value passed to callback from calling function.
958  * @param[in] UNUSED          handle to an invocation
959  * @param[in] clientResponse  Response from queries to remote servers.
960  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
961  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
962  */
963 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
964                                                          OCClientResponse *clientResponse)
965 {
966     OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
967
968     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
969
970     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
971     VERIFY_NOT_NULL(TAG, ctx, WARNING);
972
973     otmCtx->ocDoHandle = NULL;
974     (void)UNUSED;
975     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
976     {
977         OCStackResult res = OC_STACK_ERROR;
978
979         //Save the current context, that will be used by the DTLS handshake callback
980         if(OC_STACK_OK != AddOTMContext(otmCtx,
981                                         otmCtx->selectedDeviceInfo->endpoint.addr,
982                                         getSecurePort(otmCtx->selectedDeviceInfo)))
983         {
984             OIC_LOG(ERROR, TAG, "OwnerTransferModeHandler : Failed to add OTM Context into list");
985             SetResult(otmCtx, res);
986             return OC_STACK_DELETE_TRANSACTION;
987         }
988
989         //Create DTLS secure session
990         if(otmCtx->otmCallback.loadSecretCB)
991         {
992             res = otmCtx->otmCallback.loadSecretCB(otmCtx);
993             if(OC_STACK_OK != res)
994             {
995                 OIC_LOG(ERROR, TAG, "OwnerTransferModeHandler : Failed to load secret");
996                 SetResult(otmCtx, res);
997                 return  OC_STACK_DELETE_TRANSACTION;
998             }
999         }
1000         if(otmCtx->otmCallback.createSecureSessionCB)
1001         {
1002             res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
1003             if(OC_STACK_OK != res)
1004             {
1005                 OIC_LOG(ERROR, TAG, "OwnerTransferModeHandler : Failed to create DTLS session");
1006                 SetResult(otmCtx, res);
1007                 return OC_STACK_DELETE_TRANSACTION;
1008             }
1009
1010             //This is a secure session.
1011             otmCtx->selectedDeviceInfo->connType = (OCConnectivityType)(otmCtx->selectedDeviceInfo->connType | CT_FLAG_SECURE);
1012
1013             //Send request : GET /oic/sec/doxm. Then verify that the property values obtained this way
1014             //are the same as those already-stored in the otmCtx.
1015             res = GetAndVerifyDoxmResource(otmCtx);
1016             if(OC_STACK_OK != res)
1017             {
1018                 OIC_LOG(ERROR, TAG, "Failed to get doxm information after establishing secure connection");
1019                 SetResult(otmCtx, res);
1020             }
1021         }
1022     }
1023     else
1024     {
1025         OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
1026         clientResponse->result);
1027         SetResult(otmCtx, clientResponse->result);
1028     }
1029
1030     OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
1031
1032 exit:
1033     return  OC_STACK_DELETE_TRANSACTION;
1034 }
1035
1036 /**
1037  * Callback handler for ProvisioningStatusResouceHandler API.
1038  *
1039  * @param[in] ctx             ctx value passed to callback from calling function.
1040  * @param[in] UNUSED          handle to an invocation
1041  * @param[in] clientResponse  Response from queries to remote servers.
1042  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1043  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1044  */
1045 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
1046                                                     OCClientResponse *clientResponse)
1047 {
1048     OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
1049
1050     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1051
1052     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1053     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1054
1055     otmCtx->ocDoHandle = NULL;
1056     (void)UNUSED;
1057     if  (OC_STACK_OK == clientResponse->result)
1058     {
1059         if  (NULL == clientResponse->payload)
1060         {
1061             OIC_LOG(INFO, TAG, "Skipping Null payload");
1062             SetResult(otmCtx, OC_STACK_ERROR);
1063             return OC_STACK_DELETE_TRANSACTION;
1064         }
1065
1066         if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
1067         {
1068             OIC_LOG(INFO, TAG, "Unknown payload type");
1069             SetResult(otmCtx, OC_STACK_ERROR);
1070             return OC_STACK_DELETE_TRANSACTION;
1071         }
1072         OicSecPstat_t* pstat = NULL;
1073         OCStackResult result = CBORPayloadToPstat(
1074                 ((OCSecurityPayload*)clientResponse->payload)->securityData,
1075                 ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
1076                 &pstat);
1077         if(NULL == pstat || result != OC_STACK_OK)
1078         {
1079             OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
1080             SetResult(otmCtx, OC_STACK_ERROR);
1081             return OC_STACK_DELETE_TRANSACTION;
1082         }
1083         if(false == (TAKE_OWNER & pstat->cm))
1084         {
1085             OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
1086             SetResult(otmCtx, OC_STACK_ERROR);
1087             return OC_STACK_DELETE_TRANSACTION;
1088         }
1089         otmCtx->selectedDeviceInfo->pstat = pstat;
1090
1091         //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
1092         SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
1093
1094         //Send request : POST /oic/sec/pstat [{"om":"bx11", .. }]
1095         OCStackResult res = PostUpdateOperationMode(otmCtx);
1096         if (OC_STACK_OK != res)
1097         {
1098             OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
1099             SetResult(otmCtx, res);
1100         }
1101     }
1102     else
1103     {
1104         OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
1105             clientResponse->result);
1106         SetResult(otmCtx, clientResponse->result);
1107     }
1108
1109     OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
1110 exit:
1111     return  OC_STACK_DELETE_TRANSACTION;
1112 }
1113
1114 /**
1115  * Response handler for update device uuid request.
1116  *
1117  * @param[in] ctx             ctx value passed to callback from calling function.
1118  * @param[in] UNUSED          handle to an invocation
1119  * @param[in] clientResponse  Response from queries to remote servers.
1120  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1121  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1122  */
1123 static OCStackApplicationResult DeviceUuidUpdateHandler(void *ctx, OCDoHandle handle,
1124                                 OCClientResponse *clientResponse)
1125 {
1126     OIC_LOG(DEBUG, TAG, "IN DeviceUuidUpdateHandler");
1127
1128     VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1129     VERIFY_NOT_NULL_RETURN(TAG, clientResponse, WARNING, OC_STACK_DELETE_TRANSACTION);
1130
1131     OC_UNUSED(handle);
1132     OCStackResult res = OC_STACK_OK;
1133     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1134     otmCtx->ocDoHandle = NULL;
1135
1136     if(OC_STACK_OK != clientResponse->result)
1137     {
1138         OIC_LOG_V(WARNING, TAG, "DeviceUuidUpdateHandler : Client response is incorrect : %d",
1139                 clientResponse->result);
1140         return OC_STACK_DELETE_TRANSACTION;
1141     }
1142
1143     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1144     if (NULL == deviceInfo)
1145     {
1146         OIC_LOG(INFO, TAG, "Selected device info is NULL");
1147         SetResult(otmCtx, OC_STACK_ERROR);
1148         return OC_STACK_DELETE_TRANSACTION;
1149     }
1150
1151     OCSecurityPayload *payload = (OCSecurityPayload*)clientResponse->payload;
1152     if (NULL == payload)
1153     {
1154         OIC_LOG(INFO, TAG, "Skipping Null payload");
1155         SetResult(otmCtx, OC_STACK_ERROR);
1156         return OC_STACK_DELETE_TRANSACTION;
1157     }
1158
1159     OicSecDoxm_t *doxm = NULL;
1160     uint8_t *securityData = payload->securityData;
1161     size_t size = payload->payloadSize;
1162
1163     res = CBORPayloadToDoxm(securityData, size, &doxm);
1164     if ((NULL == doxm) || (OC_STACK_OK != res))
1165     {
1166         OIC_LOG(INFO, TAG, "Received malformed CBOR");
1167         SetResult(otmCtx, OC_STACK_ERROR);
1168         return OC_STACK_DELETE_TRANSACTION;
1169     }
1170
1171     //Update existing device uuid in ctxResultArray
1172     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
1173     {
1174         if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
1175                     otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
1176         {
1177             memcpy(otmCtx->ctxResultArray[i].deviceId.id, doxm->deviceID.id, UUID_LENGTH);
1178         }
1179     }
1180
1181     otmCtx->selectedDeviceInfo->doxm->deviceID = doxm->deviceID;
1182
1183     //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
1184     res = SetupPDM(otmCtx->selectedDeviceInfo);
1185     if(OC_STACK_OK != res)
1186     {
1187         OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
1188         SetResult(otmCtx, res);
1189         return (OCStackApplicationResult)res;
1190     }
1191
1192     res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
1193     if(OC_STACK_OK != res)
1194     {
1195         OIC_LOG(ERROR, TAG, "DeviceUuidUpdateHandler:Failed to owner PSK generation");
1196         SetResult(otmCtx, res);
1197         return OC_STACK_DELETE_TRANSACTION;
1198     }
1199
1200     //POST owner credential to new device according to security spec B.
1201     res = PostOwnerCredential(otmCtx);
1202     if(OC_STACK_OK != res)
1203     {
1204         OIC_LOG(ERROR, TAG,
1205                 "DeviceUuidUpdateHandler:Failed to send PosT request for onwer credential");
1206         SetResult(otmCtx, res);
1207         return OC_STACK_DELETE_TRANSACTION;
1208     }
1209
1210     OIC_LOG(DEBUG, TAG, "OUT DeviceUuidUpdateHandler");
1211     return OC_STACK_KEEP_TRANSACTION;
1212 }
1213
1214 /**
1215  * Response handler for update owner uuid request.
1216  *
1217  * @param[in] ctx             ctx value passed to callback from calling function.
1218  * @param[in] UNUSED          handle to an invocation
1219  * @param[in] clientResponse  Response from queries to remote servers.
1220  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1221  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1222  */
1223 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
1224                                 OCClientResponse *clientResponse)
1225 {
1226     OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
1227
1228     VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1229     VERIFY_NOT_NULL_RETURN(TAG, clientResponse, WARNING, OC_STACK_DELETE_TRANSACTION);
1230
1231     (void)UNUSED;
1232     OCStackResult res = OC_STACK_OK;
1233     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1234     otmCtx->ocDoHandle = NULL;
1235
1236     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1237     {
1238         if(otmCtx && otmCtx->selectedDeviceInfo)
1239         {
1240             //In case of Mutual Verified Just-Works, wait for user confirmation
1241             if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1242             {
1243                 res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
1244                 if (OC_STACK_OK != res)
1245                 {
1246                     if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, otmCtx->ctxResultCallback))
1247                     {
1248                         OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error");
1249                     }
1250                     OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to verify user confirm");
1251                     SetResult(otmCtx, res);
1252                     return OC_STACK_DELETE_TRANSACTION;
1253                 }
1254             }
1255
1256            res = GetRealUuid(otmCtx);
1257            if(OC_STACK_OK != res)
1258            {
1259                OIC_LOG(ERROR, TAG, "Failed to get doxm information");
1260                SetResult(otmCtx, res);
1261                return OC_STACK_DELETE_TRANSACTION;
1262            }
1263         }
1264     }
1265     else
1266     {
1267         if (OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel &&
1268                     OC_STACK_NOT_ACCEPTABLE == clientResponse->result)
1269         {
1270             res = OC_STACK_USER_DENIED_REQ;
1271         }
1272         else
1273         {
1274             res = clientResponse->result;
1275         }
1276         OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
1277         SetResult(otmCtx, res);
1278         return OC_STACK_DELETE_TRANSACTION;
1279     }
1280
1281     OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
1282
1283     return  OC_STACK_DELETE_TRANSACTION;
1284 }
1285
1286 /**
1287  * Response handler for update operation mode.
1288  *
1289  * @param[in] ctx             ctx value passed to callback from calling function.
1290  * @param[in] UNUSED          handle to an invocation
1291  * @param[in] clientResponse  Response from queries to remote servers.
1292  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1293  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1294  */
1295 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
1296                                 OCClientResponse *clientResponse)
1297 {
1298     OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
1299
1300     VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1301     VERIFY_NOT_NULL_RETURN(TAG, clientResponse, WARNING, OC_STACK_DELETE_TRANSACTION);
1302
1303     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1304     otmCtx->ocDoHandle = NULL;
1305     (void) UNUSED;
1306     if  (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1307     {
1308         //Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
1309         OCStackResult res = PostOwnerUuid(otmCtx);
1310         if(OC_STACK_OK != res)
1311         {
1312             OIC_LOG(ERROR, TAG, "OperationModeUpdateHandler: Failed to send devowner");
1313             SetResult(otmCtx, res);
1314         }
1315     }
1316     else
1317     {
1318         OIC_LOG(ERROR, TAG, "Error while updating operation mode");
1319         SetResult(otmCtx, clientResponse->result);
1320     }
1321
1322     OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
1323
1324     return  OC_STACK_DELETE_TRANSACTION;
1325 }
1326
1327 /**
1328  * Response handler for update owner crendetial request.
1329  *
1330  * @param[in] ctx             ctx value passed to callback from calling function.
1331  * @param[in] UNUSED          handle to an invocation
1332  * @param[in] clientResponse  Response from queries to remote servers.
1333  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1334  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1335  */
1336 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
1337                                 OCClientResponse *clientResponse)
1338 {
1339     OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
1340
1341     VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1342     VERIFY_NOT_NULL_RETURN(TAG, clientResponse, WARNING, OC_STACK_DELETE_TRANSACTION);
1343
1344     (void)UNUSED;
1345     OCStackResult res = OC_STACK_OK;
1346     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1347     otmCtx->ocDoHandle = NULL;
1348
1349     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1350     {
1351         if(otmCtx->selectedDeviceInfo)
1352         {
1353             //For Servers based on OCF 1.0, PostOwnerAcl can be executed using
1354             //the already-existing session. However, get ready here to use the
1355             //Owner Credential for establishing future secure sessions.
1356             //
1357             //For Servers based on OIC 1.1, PostOwnerAcl might fail with status
1358             //OC_STACK_UNAUTHORIZED_REQ. After such a failure, OwnerAclHandler
1359             //will close the current session and re-establish a new session,
1360             //using the Owner Credential.
1361             CAEndpoint_t *endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
1362
1363             if (IS_OIC(otmCtx->selectedDeviceInfo->specVer))
1364             {
1365                 endpoint->port = getSecurePort(otmCtx->selectedDeviceInfo);
1366                 if(CA_STATUS_OK != CAcloseSslConnection(endpoint))
1367                 {
1368                     OIC_LOG_V(WARNING, TAG, "%s: failed to close DTLS session", __func__);
1369                 }
1370             }
1371
1372             /**
1373               * If we select NULL cipher,
1374               * client will select appropriate cipher suite according to server's cipher-suite list.
1375               */
1376             // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
1377                 CAResult_t caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
1378                 if(CA_STATUS_OK != caResult)
1379                 {
1380                     OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
1381                     SetResult(otmCtx, CAResultToOCResult(caResult));
1382                     return OC_STACK_DELETE_TRANSACTION;
1383                 }
1384
1385                 /**
1386                   * in case of random PIN based OxM,
1387                   * revert get_psk_info callback of tinyDTLS to use owner credential.
1388                   */
1389                 if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1390                 {
1391                     OicUuid_t emptyUuid = { .id={0}};
1392                     SetUuidForPinBasedOxm(&emptyUuid);
1393
1394                     caResult = CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
1395                     if(CA_STATUS_OK != caResult)
1396                     {
1397                         OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1398                         SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
1399                         return OC_STACK_DELETE_TRANSACTION;
1400                     }
1401                 }
1402     #ifdef __WITH_TLS__
1403                 otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
1404     #endif
1405                 res = PostOwnerAcl(otmCtx, GET_ACL_VER(otmCtx->selectedDeviceInfo->specVer));
1406                 if(OC_STACK_OK != res)
1407                 {
1408                     OIC_LOG(ERROR, TAG, "Failed to update owner ACL to new device");
1409                     SetResult(otmCtx, res);
1410                     return OC_STACK_DELETE_TRANSACTION;
1411                 }
1412             }
1413         }
1414         else
1415         {
1416             res = clientResponse->result;
1417             OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
1418             SetResult(otmCtx, res);
1419         }
1420
1421         OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
1422
1423         return  OC_STACK_DELETE_TRANSACTION;
1424     }
1425
1426     static void SetAclVer2(char specVer[]){specVer[0]='o'; specVer[1]='c'; specVer[2]='f';}
1427
1428     /**
1429      * Response handler for update owner ACL request.
1430      *
1431      * @param[in] ctx             ctx value passed to callback from calling function.
1432      * @param[in] UNUSED          handle to an invocation
1433      * @param[in] clientResponse  Response from queries to remote servers.
1434      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1435      *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1436      */
1437     static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle handle,
1438                                     OCClientResponse *clientResponse)
1439     {
1440         OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler");
1441
1442         OC_UNUSED(handle);
1443
1444         VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1445         VERIFY_NOT_NULL_RETURN(TAG, clientResponse, WARNING, OC_STACK_DELETE_TRANSACTION);
1446
1447         OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1448         OCProvisionDev_t* selectedDeviceInfo = otmCtx->selectedDeviceInfo;
1449         VERIFY_NOT_NULL_RETURN(TAG, selectedDeviceInfo, WARNING, OC_STACK_DELETE_TRANSACTION);
1450
1451         otmCtx->ocDoHandle = NULL;
1452
1453         OCStackResult res = clientResponse->result;
1454         if(OC_STACK_RESOURCE_CHANGED == res)
1455         {
1456             if(NULL != selectedDeviceInfo)
1457             {
1458                 //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }]
1459                 OIC_LOG_V(DEBUG, TAG, "%s posting /doxm.owned = true.", __func__);
1460                 res = PostOwnershipInformation(otmCtx);
1461                 if(OC_STACK_OK != res)
1462                 {
1463                     OIC_LOG_V(ERROR, TAG, "%s: Failed to update the ownership information"
1464                         "of the new device, res = %d",
1465                         __func__, res);
1466                     SetResult(otmCtx, res);
1467                 }
1468             }
1469         }
1470         else if(OC_STACK_NO_RESOURCE == res)
1471         {
1472             OIC_LOG_V(WARNING, TAG, "%s: not found uri", __func__);
1473             if(OIC_SEC_ACL_V1 == GET_ACL_VER(otmCtx->selectedDeviceInfo->specVer))
1474             {
1475                 SetAclVer2(otmCtx->selectedDeviceInfo->specVer);
1476                 OIC_LOG_V(WARNING, TAG, "%s: set acl v2", __func__);
1477                 PostOwnerAcl(otmCtx, OIC_SEC_ACL_V2);
1478             }
1479         }
1480         else
1481         {
1482             OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res);
1483             SetResult(otmCtx, res);
1484         }
1485
1486         OIC_LOG(DEBUG, TAG, "OUT OwnerAclHandler");
1487         return  OC_STACK_DELETE_TRANSACTION;
1488     }
1489
1490     /**
1491      * Response handler for update owner information request.
1492      *
1493      * @param[in] ctx             ctx value passed to callback from calling function.
1494      * @param[in] UNUSED          handle to an invocation
1495      * @param[in] clientResponse  Response from queries to remote servers.
1496      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1497      *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1498      */
1499     static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
1500                                     OCClientResponse *clientResponse)
1501     {
1502         OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
1503
1504         VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1505
1506         (void)UNUSED;
1507         OCStackResult res = OC_STACK_OK;
1508         OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1509         VERIFY_NOT_NULL_RETURN(TAG, otmCtx->selectedDeviceInfo, WARNING, OC_STACK_DELETE_TRANSACTION);
1510         otmCtx->ocDoHandle = NULL;
1511
1512         if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1513         {
1514             if(otmCtx && otmCtx->selectedDeviceInfo)
1515             {
1516                 OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
1517                 OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
1518
1519                 res = PostRownerUuid(otmCtx);
1520                 if(OC_STACK_OK != res)
1521                 {
1522                     OIC_LOG(ERROR, TAG, "Failed to set rowneruuid pstat");
1523                     SetResult(otmCtx, res);
1524                 }
1525             }
1526         }
1527         else
1528         {
1529             res = clientResponse->result;
1530             OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
1531             SetResult(otmCtx, res);
1532         }
1533
1534         OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
1535         return OC_STACK_DELETE_TRANSACTION;
1536     }
1537
1538     /**
1539      * Response handler of update provisioning status.
1540      *
1541      * @param[in] ctx             ctx value passed to callback from calling function.
1542      * @param[in] UNUSED          handle to an invocation
1543      * @param[in] clientResponse  Response from queries to remote servers.
1544      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1545      *          and OC_STACK_KEEP_TRANSACTION to keep it.
1546      */
1547     static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
1548                                                            OCClientResponse *clientResponse)
1549     {
1550         OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
1551
1552         VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1553
1554         OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1555         VERIFY_NOT_NULL_RETURN(TAG, otmCtx->selectedDeviceInfo, WARNING, OC_STACK_DELETE_TRANSACTION);
1556         otmCtx->ocDoHandle = NULL;
1557         (void)UNUSED;
1558         OCStackResult res = OC_STACK_OK;
1559
1560         if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1561         {
1562             if(otmCtx && otmCtx->selectedDeviceInfo)
1563             {
1564                 OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
1565
1566                 res = PostNormalOperationStatus(otmCtx);
1567                 if(OC_STACK_OK != res)
1568                 {
1569                     OIC_LOG(ERROR, TAG, "Failed to update pstat");
1570                     SetResult(otmCtx, res);
1571                 }
1572             }
1573         }
1574         else
1575         {
1576             OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1577                                 clientResponse->result);
1578             SetResult(otmCtx, clientResponse->result);
1579         }
1580
1581         OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
1582         return OC_STACK_DELETE_TRANSACTION;
1583     }
1584
1585     /**
1586      * Response handler of update provisioning status to Ready for Normal..
1587      *
1588      * @param[in] ctx             ctx value passed to callback from calling function.
1589      * @param[in] UNUSED          handle to an invocation
1590      * @param[in] clientResponse  Response from queries to remote servers.
1591      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1592      *          and OC_STACK_KEEP_TRANSACTION to keep it.
1593      */
1594     static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
1595                                                            OCClientResponse *clientResponse)
1596     {
1597         OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
1598
1599         VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1600
1601         OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1602         VERIFY_NOT_NULL_RETURN(TAG, otmCtx->selectedDeviceInfo, WARNING, OC_STACK_DELETE_TRANSACTION);
1603         otmCtx->ocDoHandle = NULL;
1604         (void)UNUSED;
1605
1606         if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1607         {
1608             OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
1609             OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
1610                                                   PDM_DEVICE_ACTIVE);
1611             if (OC_STACK_OK == res)
1612             {
1613                 CloseSslConnection(otmCtx->selectedDeviceInfo);
1614                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1615                 SetResult(otmCtx, OC_STACK_OK);
1616                 return OC_STACK_DELETE_TRANSACTION;
1617             }
1618             else
1619             {
1620                 OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1621             }
1622         }
1623         else
1624         {
1625             OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1626                                 clientResponse->result);
1627             SetResult(otmCtx, clientResponse->result);
1628         }
1629
1630         OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
1631         return OC_STACK_DELETE_TRANSACTION;
1632     }
1633
1634     /**
1635      * Callback handler for GetAndVerifyDoxmResource.
1636      *
1637      * @param[in] ctx             ctx value passed to callback from calling function.
1638      * @param[in] UNUSED          handle to an invocation
1639      * @param[in] clientResponse  Response from queries to remote servers.
1640      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1641      *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1642      */
1643     static OCStackApplicationResult GetAndVerifyDoxmHandler(void *ctx, OCDoHandle UNUSED,
1644                                                         OCClientResponse *clientResponse)
1645     {
1646         OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1647
1648         VERIFY_NOT_NULL_RETURN(TAG, ctx, WARNING, OC_STACK_DELETE_TRANSACTION);
1649
1650         OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1651         VERIFY_NOT_NULL_RETURN(TAG, otmCtx->selectedDeviceInfo, WARNING, OC_STACK_DELETE_TRANSACTION);
1652         otmCtx->ocDoHandle = NULL;
1653         (void)UNUSED;
1654
1655         if (OC_STACK_CONTINUE_OPERATION == clientResponse->result)
1656         {
1657             OIC_LOG(INFO, TAG, "Skipping error handling until pass all random pin tries");
1658         }
1659         else if (OC_STACK_OK != clientResponse->result)
1660         {
1661             OIC_LOG_V(WARNING, TAG, "%s : Client response is incorrect : %d",
1662                 __func__, clientResponse->result);
1663             SetResult(otmCtx, clientResponse->result);
1664         }
1665         else
1666         {
1667             //Sanity checks.
1668             OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1669             if (NULL == deviceInfo)
1670             {
1671                 OIC_LOG(INFO, TAG, "Selected device info is NULL");
1672                 SetResult(otmCtx, OC_STACK_ERROR);
1673                 return OC_STACK_DELETE_TRANSACTION;
1674             }
1675
1676             OCSecurityPayload *payload = (OCSecurityPayload*)clientResponse->payload;
1677             if (NULL == payload)
1678             {
1679                 OIC_LOG(INFO, TAG, "Skipping Null payload");
1680                 SetResult(otmCtx, OC_STACK_ERROR);
1681                 return OC_STACK_DELETE_TRANSACTION;
1682             }
1683
1684             if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
1685             {
1686                 OIC_LOG(INFO, TAG, "Unknown payload type");
1687                 SetResult(otmCtx, OC_STACK_ERROR);
1688                 return OC_STACK_DELETE_TRANSACTION;
1689             }
1690
1691             //Compare the doxm property values obtained over this secured session with those
1692             //values obtained before the DTLS handshake.
1693             OicSecDoxm_t *doxm = NULL;
1694             uint8_t *securityData = payload->securityData;
1695             size_t size = payload->payloadSize;
1696
1697             OCStackResult res = CBORPayloadToDoxm(securityData, size, &doxm);
1698             if ((NULL == doxm) || (OC_STACK_OK != res))
1699             {
1700                 OIC_LOG(INFO, TAG, "Received malformed CBOR");
1701                 SetResult(otmCtx, OC_STACK_ERROR);
1702                 return OC_STACK_DELETE_TRANSACTION;
1703             }
1704
1705             bool equal = AreDoxmBinPropertyValuesEqual(doxm, deviceInfo->doxm);
1706             DeleteDoxmBinData(doxm);
1707             if (!equal)
1708             {
1709                 SetResult(otmCtx, OC_STACK_ERROR);
1710                 return OC_STACK_DELETE_TRANSACTION;
1711             }
1712
1713             //Send request : GET /oic/sec/pstat
1714             res = GetProvisioningStatusResource(otmCtx);
1715             if(OC_STACK_OK != res)
1716             {
1717                 OIC_LOG(ERROR, TAG, "Failed to get pstat information");
1718                 SetResult(otmCtx, res);
1719             }
1720         }
1721
1722         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1723         return OC_STACK_DELETE_TRANSACTION;
1724     }
1725
1726 static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx)
1727 {
1728     OIC_LOG(DEBUG, TAG, "IN PostOwnerCredential");
1729     OCStackResult res = OC_STACK_ERROR;
1730     OCHeaderOption *options = NULL;
1731     uint8_t numOptions = 0;
1732
1733     VERIFY_NOT_NULL_RETURN(TAG, otmCtx, ERROR, OC_STACK_INVALID_PARAM);
1734     VERIFY_NOT_NULL_RETURN(TAG, otmCtx->selectedDeviceInfo, ERROR, OC_STACK_INVALID_PARAM);
1735
1736     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1737     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1738     assert(deviceInfo->connType & CT_FLAG_SECURE);
1739
1740     if (!PMGenerateQuery(true,
1741                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
1742                         deviceInfo->connType,
1743                         query, sizeof(query), OIC_RSRC_CRED_URI))
1744     {
1745         OIC_LOG(ERROR, TAG, "PostOwnerCredential : Failed to generate query");
1746         return OC_STACK_ERROR;
1747     }
1748     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1749     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1750     if (NULL == secPayload)
1751     {
1752         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1753         return OC_STACK_NO_MEMORY;
1754     }
1755
1756     //Generate owner credential for new device
1757     OicUuid_t credSubjectId = {.id={0}};
1758     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1759     const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
1760     if (NULL == ownerCredential)
1761     {
1762         OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
1763         res = OC_STACK_NO_RESOURCE;
1764         goto exit;
1765     }
1766
1767     if (OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
1768     {
1769         OicSecCred_t newCredential;
1770         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
1771         newCredential.next = NULL;
1772
1773         //Set subject ID as PT's ID
1774         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
1775
1776         if (IS_OIC(deviceInfo->specVer))
1777         {
1778             options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
1779             if (NULL == options)
1780             {
1781                 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1782                 res = OC_STACK_NO_MEMORY;
1783                 goto exit;
1784             }
1785
1786             SetCBORFormat(options, &numOptions);
1787             OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
1788         }
1789
1790         //Fill private data as empty string
1791         newCredential.privateData.data = (uint8_t*)"";
1792         newCredential.privateData.len = 0;
1793         newCredential.privateData.encoding = ownerCredential->privateData.encoding;
1794
1795         newCredential.publicData.data = NULL;
1796         newCredential.publicData.len = 0;
1797         newCredential.publicData.encoding = ownerCredential->publicData.encoding;
1798
1799         int secureFlag = 0;
1800         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
1801         if (OC_STACK_OK != CredToCBORPayloadWithRowner(&newCredential, &credSubjectId, &secPayload->securityData,
1802                                         &secPayload->payloadSize, secureFlag))
1803         {
1804             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1805             res = OC_STACK_ERROR;
1806             goto exit;
1807         }
1808         OIC_LOG(DEBUG, TAG, "Cred Payload:");
1809         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1810
1811         OCCallbackData cbData;
1812         cbData.cb = &OwnerCredentialHandler;
1813         cbData.context = (void *)otmCtx;
1814         cbData.cd = NULL;
1815         res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1816                                          &deviceInfo->endpoint, (OCPayload*)secPayload,
1817                                          deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
1818         secPayload = NULL;
1819         if (res != OC_STACK_OK)
1820         {
1821             OIC_LOG(ERROR, TAG, "OCStack resource error");
1822         }
1823     }
1824     else
1825     {
1826         OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
1827         res = OC_STACK_NO_RESOURCE;
1828     }
1829
1830 exit:
1831     OICFree(options);
1832     OCPayloadDestroy((OCPayload *)secPayload);
1833     OIC_LOG(DEBUG, TAG, "OUT PostOwnerCredential");
1834
1835     return res;
1836 }
1837
1838 static OicSecAcl_t* GenerateOwnerAcl(const OicUuid_t* owner)
1839 {
1840     OicSecAcl_t* ownerAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
1841     OicSecAce_t* ownerAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1842     OicSecRsrc_t* wildcardRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t)); // TODO IOT-2192
1843     if (NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1844     {
1845         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1846         goto error;
1847     }
1848     LL_APPEND(ownerAcl->aces, ownerAce);
1849     LL_APPEND(ownerAce->resources, wildcardRsrc);
1850
1851     //Set resource owner as PT
1852     memcpy(ownerAcl->rownerID.id, owner->id, sizeof(owner->id));
1853
1854     //PT has full permission.
1855     ownerAce->permission = PERMISSION_FULL_CONTROL;
1856
1857     //Set subject as PT's UUID
1858     ownerAce->subjectType = OicSecAceUuidSubject;
1859     memcpy(ownerAce->subjectuuid.id, owner->id, sizeof(owner->id));
1860
1861     wildcardRsrc->href = OICStrdup(WILDCARD_RESOURCE_URI);
1862     if (NULL == wildcardRsrc->href)
1863     {
1864         goto error;
1865     }
1866
1867     wildcardRsrc->interfaceLen = 1;
1868     wildcardRsrc->interfaces = (char**)OICMalloc(wildcardRsrc->interfaceLen * sizeof(char*));
1869     if (NULL == wildcardRsrc->interfaces)
1870     {
1871         goto error;
1872     }
1873     wildcardRsrc->interfaces[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1874     if (NULL == wildcardRsrc->interfaces[0])
1875     {
1876         goto error;
1877     }
1878
1879     wildcardRsrc->typeLen = 1;
1880     wildcardRsrc->types = (char**)OICMalloc(wildcardRsrc->typeLen * sizeof(char*));
1881     if (NULL == wildcardRsrc->types)
1882     {
1883         goto error;
1884     }
1885     wildcardRsrc->types[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1886     if (NULL == wildcardRsrc->types[0])
1887     {
1888         goto error;
1889     }
1890
1891     return ownerAcl;
1892
1893 error:
1894     //in case of memory allocation failed, each resource should be removed individually.
1895     if (NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1896     {
1897         OICFree(ownerAcl);
1898         OICFree(ownerAce);
1899         OICFree(wildcardRsrc);
1900     }
1901     else
1902     {
1903         DeleteACLList(ownerAcl);
1904     }
1905     return NULL;
1906 }
1907
1908 /**
1909  * Function to update the owner ACL to new device.
1910  *
1911  * @param[in]  otmCtx  Context value of ownership transfer.
1912  * @param[in]  aclVer  ACL version.
1913  * @return  OC_STACK_OK on success
1914  */
1915 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx, OicSecAclVersion_t aclVer)
1916 {
1917     OCStackResult res = OC_STACK_ERROR;
1918     OCHeaderOption *options = NULL;
1919     uint8_t numOptions = 0;
1920
1921     OIC_LOG(DEBUG, TAG, "IN PostOwnerAcl");
1922
1923     if (!otmCtx || !otmCtx->selectedDeviceInfo)
1924     {
1925         OIC_LOG(ERROR, TAG, "Invalid parameters");
1926         return OC_STACK_INVALID_PARAM;
1927     }
1928     const char * aclUri = (OIC_SEC_ACL_V2 == aclVer ? OIC_RSRC_ACL2_URI : OIC_RSRC_ACL_URI);
1929     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1930     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1931     OicSecAcl_t* ownerAcl = NULL;
1932     assert(deviceInfo->connType & CT_FLAG_SECURE);
1933
1934     if (!PMGenerateQuery(true,
1935                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
1936                         deviceInfo->connType,
1937                         query, sizeof(query), aclUri))
1938     {
1939         OIC_LOG(ERROR, TAG, "Failed to generate query");
1940         return OC_STACK_ERROR;
1941     }
1942     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1943
1944     OicUuid_t ownerID;
1945     res = GetDoxmDeviceID(&ownerID);
1946     if (OC_STACK_OK != res)
1947     {
1948         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1949         return res;
1950     }
1951
1952     //Generate owner ACL for new device
1953     ownerAcl = GenerateOwnerAcl(&ownerID);
1954     if (NULL == ownerAcl)
1955     {
1956         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1957         return OC_STACK_NO_MEMORY;
1958     }
1959
1960     //Generate ACL payload
1961     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1962     if (NULL == secPayload)
1963     {
1964         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1965         res = OC_STACK_NO_MEMORY;
1966         goto exit;
1967     }
1968
1969     res = AclToCBORPayload(ownerAcl, aclVer, &secPayload->securityData, &secPayload->payloadSize);
1970     if (OC_STACK_OK != res)
1971     {
1972         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1973         goto exit;
1974     }
1975     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1976
1977     OIC_LOG(DEBUG, TAG, "Owner ACL Payload:");
1978     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1979
1980     if (IS_OIC(deviceInfo->specVer))
1981     {
1982         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
1983         if (NULL == options)
1984         {
1985             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1986             res = OC_STACK_NO_MEMORY;
1987             goto exit;
1988         }
1989
1990         SetCBORFormat(options, &numOptions);
1991         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
1992     }
1993
1994     //Send owner ACL to new device : POST /oic/sec/cred [ owner credential ]
1995     OCCallbackData cbData;
1996     cbData.cb = &OwnerAclHandler;
1997     cbData.context = (void *)otmCtx;
1998     cbData.cd = NULL;
1999     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
2000                                      &deviceInfo->endpoint, (OCPayload*)secPayload,
2001                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2002     secPayload = NULL;
2003     if (OC_STACK_OK != res)
2004     {
2005         OIC_LOG(ERROR, TAG, "OCStack resource error");
2006     }
2007
2008     OIC_LOG(DEBUG, TAG, "OUT PostOwnerAcl");
2009
2010 exit:
2011     OICFree(options);
2012     OCPayloadDestroy((OCPayload *)secPayload);
2013     DeleteACLList(ownerAcl);
2014
2015     return res;
2016 }
2017
2018 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx)
2019 {
2020     OIC_LOG(DEBUG, TAG, "IN PostOwnerTransferModeToResource");
2021     OCStackResult res = OC_STACK_ERROR;
2022     OCHeaderOption *options = NULL;
2023     uint8_t numOptions = 0;
2024
2025     if (!otmCtx || !otmCtx->selectedDeviceInfo)
2026     {
2027         OIC_LOG(ERROR, TAG, "Invalid parameters");
2028         return OC_STACK_INVALID_PARAM;
2029     }
2030
2031     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2032     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2033
2034     if (!PMGenerateQuery(false,
2035                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
2036                         deviceInfo->connType,
2037                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2038     {
2039         OIC_LOG(ERROR, TAG, "PostOwnerTransferModeToResource : Failed to generate query");
2040         return OC_STACK_ERROR;
2041     }
2042     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2043
2044     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
2045     if (NULL == secPayload)
2046     {
2047         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2048         return OC_STACK_NO_MEMORY;
2049     }
2050
2051     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2052     res = otmCtx->otmCallback.createSelectOxmPayloadCB(otmCtx,
2053             &secPayload->securityData, &secPayload->payloadSize);
2054     if (OC_STACK_OK != res && NULL == secPayload->securityData)
2055     {
2056         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
2057         res = OC_STACK_ERROR;
2058         goto exit;
2059     }
2060
2061     if (IS_OIC(deviceInfo->specVer))
2062     {
2063         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2064         if (NULL == options)
2065         {
2066             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2067             res = OC_STACK_NO_MEMORY;
2068             goto exit;
2069         }
2070
2071         SetCBORFormat(options, &numOptions);
2072         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2073     }
2074
2075     OCCallbackData cbData;
2076     cbData.cb = &OwnerTransferModeHandler;
2077     cbData.context = (void *)otmCtx;
2078     cbData.cd = NULL;
2079     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
2080                        &deviceInfo->endpoint, (OCPayload *)secPayload,
2081                        deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2082     secPayload = NULL;
2083     if (res != OC_STACK_OK)
2084     {
2085         OIC_LOG(ERROR, TAG, "OCStack resource error");
2086     }
2087
2088 exit:
2089     OICFree(options);
2090     OCPayloadDestroy((OCPayload *)secPayload);
2091     OIC_LOG(DEBUG, TAG, "OUT PostOwnerTransferModeToResource");
2092
2093     return res;
2094 }
2095
2096 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
2097 {
2098     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
2099
2100     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2101     {
2102         OIC_LOG(ERROR, TAG, "Invailed parameters");
2103         return OC_STACK_INVALID_PARAM;
2104     }
2105
2106     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2107     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2108     assert(deviceInfo->connType & CT_FLAG_SECURE);
2109
2110     if(!PMGenerateQuery(true,
2111                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2112                         deviceInfo->connType,
2113                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2114     {
2115         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
2116         return OC_STACK_ERROR;
2117     }
2118     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2119
2120     OCHeaderOption *options = NULL;
2121     uint8_t numOptions = 0;
2122
2123     if (IS_OIC(deviceInfo->specVer))
2124     {
2125         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2126         VERIFY_NOT_NULL_RETURN(TAG, options, ERROR, OC_STACK_NO_MEMORY);
2127         SetCBORFormat(options, &numOptions);
2128         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2129     }
2130
2131
2132     OCCallbackData cbData;
2133     cbData.cb = &ListMethodsHandler;
2134     cbData.context = (void *)otmCtx;
2135     cbData.cd = NULL;
2136     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
2137                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2138     OICFree(options);
2139     if (res != OC_STACK_OK)
2140     {
2141         OIC_LOG(ERROR, TAG, "OCStack resource error");
2142     }
2143
2144     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
2145
2146     return res;
2147 }
2148
2149 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
2150 {
2151     OIC_LOG(DEBUG, TAG, "IN PostOwnerUuid");
2152     OCStackResult res = OC_STACK_ERROR;
2153     OCHeaderOption *options = NULL;
2154     uint8_t numOptions = 0;
2155
2156     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2157     {
2158         OIC_LOG(ERROR, TAG, "Invailed parameters");
2159         return OC_STACK_INVALID_PARAM;
2160     }
2161
2162     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2163     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2164     assert(deviceInfo->connType & CT_FLAG_SECURE);
2165
2166     if(!PMGenerateQuery(true,
2167                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2168                         deviceInfo->connType,
2169                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2170     {
2171         OIC_LOG(ERROR, TAG, "PostOwnerUuid : Failed to generate query");
2172         return OC_STACK_ERROR;
2173     }
2174     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2175
2176     //Post PT's uuid to new device
2177     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
2178     if (NULL == secPayload)
2179     {
2180         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2181         return OC_STACK_NO_MEMORY;
2182     }
2183     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2184     res = otmCtx->otmCallback.createOwnerTransferPayloadCB(
2185             otmCtx, &secPayload->securityData, &secPayload->payloadSize);
2186     if (OC_STACK_OK != res && NULL == secPayload->securityData)
2187     {
2188         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
2189         res = OC_STACK_INVALID_PARAM;
2190         goto exit;
2191     }
2192     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2193
2194     if (IS_OIC(deviceInfo->specVer))
2195     {
2196         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2197         if (NULL == options)
2198         {
2199             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2200             res = OC_STACK_NO_MEMORY;
2201             goto exit;
2202         }
2203
2204         SetCBORFormat(options, &numOptions);
2205         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2206     }
2207
2208     OCCallbackData cbData;
2209     cbData.cb = &OwnerUuidUpdateHandler;
2210     cbData.context = (void *)otmCtx;
2211     cbData.cd = NULL;
2212
2213     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
2214             deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2215     secPayload = NULL;
2216     if (OC_STACK_OK != res)
2217     {
2218         OIC_LOG(ERROR, TAG, "OCStack resource error");
2219     }
2220
2221 exit:
2222     OICFree(options);
2223     OCPayloadDestroy((OCPayload *)secPayload);
2224
2225     OIC_LOG(DEBUG, TAG, "OUT PostOwnerUuid");
2226
2227     return res;
2228 }
2229
2230 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
2231 {
2232     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2233     OCStackResult res = OC_STACK_ERROR;
2234
2235     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2236     {
2237         OIC_LOG(ERROR, TAG, "Invalid parameters");
2238         return OC_STACK_INVALID_PARAM;
2239     }
2240
2241     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2242     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2243     assert(deviceInfo->connType & CT_FLAG_SECURE);
2244
2245     if(!PMGenerateQuery(true,
2246                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2247                         deviceInfo->connType,
2248                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2249     {
2250         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2251         return OC_STACK_ERROR;
2252     }
2253     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2254
2255     //OwnershipInformationHandler
2256     OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
2257     if (NULL == secPayload)
2258     {
2259         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2260         return OC_STACK_NO_MEMORY;
2261     }
2262
2263     otmCtx->selectedDeviceInfo->doxm->owned = true;
2264
2265     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2266     OCHeaderOption *options = NULL;
2267     uint8_t numOptions = 0;
2268     bool propertiesToInclude[DOXM_PROPERTY_COUNT];
2269     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
2270     propertiesToInclude[DOXM_OWNED] = true;
2271     //include rowner uuid
2272     propertiesToInclude[DOXM_ROWNERUUID] = true;
2273     //doxm.rowneruuid set to the provisioningclient's /doxm.deviceuuid.
2274     if (OC_STACK_OK != GetDoxmDeviceID(&otmCtx->selectedDeviceInfo->doxm->rownerID))
2275     {
2276         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2277         res = OC_STACK_ERROR;
2278         goto exit;
2279     }
2280
2281     if (IS_OIC(deviceInfo->specVer))
2282     {
2283         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2284         if (NULL == options)
2285         {
2286             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2287             res = OC_STACK_NO_MEMORY;
2288             goto exit;
2289         }
2290
2291         SetCBORFormat(options, &numOptions);
2292
2293         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2294     }
2295
2296     res = DoxmToCBORPayloadPartial(otmCtx->selectedDeviceInfo->doxm,
2297             &secPayload->securityData, &secPayload->payloadSize,
2298             propertiesToInclude);
2299     if (OC_STACK_OK != res && NULL == secPayload->securityData)
2300     {
2301         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
2302         res = OC_STACK_INVALID_PARAM;
2303         goto exit;
2304     }
2305
2306     OCCallbackData cbData;
2307     cbData.cb = &OwnershipInformationHandler;
2308     cbData.context = (void *)otmCtx;
2309     cbData.cd = NULL;
2310
2311     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2312                        deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2313     secPayload = NULL;
2314     if (res != OC_STACK_OK)
2315     {
2316         OIC_LOG(ERROR, TAG, "OCStack resource error");
2317     }
2318
2319 exit:
2320     OICFree(options);
2321     OCPayloadDestroy((OCPayload *)secPayload);
2322     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2323
2324     return res;
2325 }
2326
2327 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
2328 {
2329     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2330     OCStackResult res = OC_STACK_ERROR;
2331
2332     if (!otmCtx || !otmCtx->selectedDeviceInfo)
2333     {
2334         return OC_STACK_INVALID_PARAM;
2335     }
2336
2337     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2338     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2339     assert(deviceInfo->connType & CT_FLAG_SECURE);
2340
2341     if (!PMGenerateQuery(true,
2342                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2343                         deviceInfo->connType,
2344                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2345     {
2346         OIC_LOG_V(ERROR, TAG, "%s Failed to generate query", __func__);
2347         return OC_STACK_ERROR;
2348     }
2349     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2350
2351     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
2352     if (NULL == secPayload)
2353     {
2354         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2355         return OC_STACK_NO_MEMORY;
2356     }
2357
2358     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2359     OCHeaderOption *options = NULL;
2360     uint8_t numOptions = 0;
2361     bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
2362     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
2363     propertiesToInclude[PSTAT_OM] = true;
2364
2365     if (IS_OIC(deviceInfo->specVer))
2366     {
2367         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2368         if (NULL == options)
2369         {
2370             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2371             res = OC_STACK_NO_MEMORY;
2372             goto exit;
2373         }
2374
2375         SetCBORFormat(options, &numOptions);
2376         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2377         propertiesToInclude[PSTAT_TM] = true;
2378     }
2379
2380     res = PstatToCBORPayloadPartial(deviceInfo->pstat, &secPayload->securityData,
2381                                            &secPayload->payloadSize, propertiesToInclude, false);
2382
2383     if (OC_STACK_OK != res)
2384     {
2385         OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
2386         res = OC_STACK_INVALID_PARAM;
2387         goto exit;
2388     }
2389
2390     OCCallbackData cbData;
2391     cbData.cb = &OperationModeUpdateHandler;
2392     cbData.context = (void *)otmCtx;
2393     cbData.cd = NULL;
2394     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
2395                        deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2396     secPayload = NULL;
2397     if (res != OC_STACK_OK)
2398     {
2399         OIC_LOG(ERROR, TAG, "OCStack resource error");
2400     }
2401
2402 exit:
2403     OICFree(options);
2404     OCPayloadDestroy((OCPayload *)secPayload);
2405     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2406
2407     return res;
2408 }
2409
2410 static OCStackResult GetAndVerifyDoxmResource(OTMContext_t* otmCtx)
2411 {
2412     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2413
2414     if(!otmCtx || !otmCtx->selectedDeviceInfo || !otmCtx->selectedDeviceInfo->doxm)
2415     {
2416         OIC_LOG(ERROR, TAG, "Invalid context");
2417         return OC_STACK_INVALID_PARAM;
2418     }
2419
2420     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2421     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2422     assert(deviceInfo->connType & CT_FLAG_SECURE);
2423
2424     if(!PMGenerateQuery(true,
2425                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2426                         deviceInfo->connType,
2427                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2428     {
2429         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2430         return OC_STACK_ERROR;
2431     }
2432     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2433
2434     OCHeaderOption *options = NULL;
2435     uint8_t numOptions = 0;
2436
2437     if (IS_OIC(deviceInfo->specVer))
2438     {
2439         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2440         VERIFY_NOT_NULL_RETURN(TAG, options, ERROR, OC_STACK_NO_MEMORY);
2441         SetCBORFormat(options, &numOptions);
2442         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2443     }
2444
2445     OCCallbackData cbData;
2446     cbData.cb = &GetAndVerifyDoxmHandler;
2447     cbData.context = (void *)otmCtx;
2448     cbData.cd = NULL;
2449     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
2450                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2451     OICFree(options);
2452     if (res != OC_STACK_OK)
2453     {
2454         OIC_LOG(ERROR, TAG, "OCStack resource error");
2455     }
2456
2457     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2458
2459     return res;
2460 }
2461
2462 static OCStackResult GetRealUuid(OTMContext_t* otmCtx)
2463 {
2464     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2465
2466     if(!otmCtx || !otmCtx->selectedDeviceInfo || !otmCtx->selectedDeviceInfo->doxm)
2467     {
2468         OIC_LOG(ERROR, TAG, "Invalid context");
2469         return OC_STACK_INVALID_PARAM;
2470     }
2471
2472     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2473     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2474     assert(deviceInfo->connType & CT_FLAG_SECURE);
2475
2476     if(!PMGenerateQuery(true,
2477                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2478                         deviceInfo->connType,
2479                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2480     {
2481         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2482         return OC_STACK_ERROR;
2483     }
2484     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2485
2486     OCHeaderOption *options = NULL;
2487     uint8_t numOptions = 0;
2488
2489     if (IS_OIC(deviceInfo->specVer))
2490     {
2491         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2492         VERIFY_NOT_NULL_RETURN(TAG, options, ERROR, OC_STACK_NO_MEMORY);
2493         SetCBORFormat(options, &numOptions);
2494         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2495     }
2496
2497     OCCallbackData cbData;
2498     cbData.cb = &DeviceUuidUpdateHandler;
2499     cbData.context = (void *)otmCtx;
2500     cbData.cd = NULL;
2501     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
2502                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2503     OICFree(options);
2504     if (res != OC_STACK_OK)
2505     {
2506         OIC_LOG(ERROR, TAG, "OCStack resource error");
2507     }
2508
2509     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2510
2511     return res;
2512 }
2513
2514 static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice)
2515 {
2516     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2517
2518     VERIFY_NOT_NULL_RETURN(TAG, selectedDevice, ERROR, OC_STACK_INVALID_PARAM);
2519     VERIFY_NOT_NULL_RETURN(TAG, selectedDevice->doxm, ERROR, OC_STACK_INVALID_PARAM);
2520
2521     char* strUuid = NULL;
2522     OCStackResult res = OC_STACK_INVALID_PARAM;
2523     bool isDuplicate = true;
2524
2525     PdmDeviceState_t pdmState = PDM_DEVICE_UNKNOWN;
2526     res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState);
2527     if (OC_STACK_OK != res)
2528     {
2529         OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res);
2530         return res;
2531     }
2532
2533     bool removeCredReq = false;
2534     res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
2535     if (OC_STACK_OK != res)
2536     {
2537         OIC_LOG(WARNING, TAG, "Failed to covert uuid to string");
2538         return res;
2539     }
2540
2541     if (PDM_DEVICE_UNKNOWN == pdmState && !selectedDevice->doxm->owned)
2542     {
2543         removeCredReq = true;
2544     }
2545     else if (PDM_DEVICE_ACTIVE == pdmState && !selectedDevice->doxm->owned)
2546     {
2547         OIC_LOG_V(WARNING, TAG, "Unowned device[%s] dectected from PDM.", strUuid);
2548         OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", strUuid);
2549         res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
2550         if(OC_STACK_OK != res)
2551         {
2552             OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", strUuid);
2553             goto exit;
2554         }
2555
2556         removeCredReq = true;
2557     }
2558
2559     if (removeCredReq)
2560     {
2561         OIC_LOG_V(WARNING, TAG, "[%s]'s credential will be removed.", strUuid);
2562         res = RemoveCredential(&selectedDevice->doxm->deviceID);
2563         if (OC_STACK_RESOURCE_DELETED != res)
2564         {
2565             OIC_LOG_V(WARNING, TAG, "Can not find [%s]'s credential.", strUuid);
2566         }
2567     }
2568
2569     //Checking duplication of Device ID.
2570     res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
2571     if (OC_STACK_OK != res)
2572     {
2573         OIC_LOG_V(ERROR, TAG, "Internal error in PDMIsDuplicateDevice : %d", res);
2574         goto exit;
2575     }
2576
2577     if (isDuplicate)
2578     {
2579         if (PDM_DEVICE_STALE == pdmState)
2580         {
2581             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
2582                                "device status will revert back to initial status.");
2583             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
2584             if (OC_STACK_OK != res)
2585             {
2586                 OIC_LOG_V(ERROR, TAG, "Internal error in PDMSetDeviceState : %d", res);
2587                 goto exit;
2588             }
2589         }
2590         else if (PDM_DEVICE_INIT == pdmState)
2591         {
2592             OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
2593             res = OC_STACK_DUPLICATE_REQUEST;
2594             goto exit;
2595         }
2596         else
2597         {
2598             OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
2599             res = OC_STACK_ERROR;
2600             goto exit;
2601         }
2602     }
2603     else
2604     {
2605         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
2606         if (OC_STACK_OK != res)
2607         {
2608             OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res);
2609             goto exit;
2610         }
2611     }
2612
2613 exit:
2614     OICFree(strUuid);
2615     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2616     return res;
2617 }
2618
2619 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
2620 {
2621     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
2622     OCStackResult res = OC_STACK_INVALID_PARAM;
2623
2624     VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_INVALID_PARAM);
2625
2626     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
2627     otmCtx->selectedDeviceInfo = selectedDevice;
2628
2629     VERIFY_NOT_NULL_RETURN(TAG, selectedDevice, ERROR, OC_STACK_INVALID_PARAM);
2630     VERIFY_NOT_NULL_RETURN(TAG, selectedDevice->doxm, ERROR, OC_STACK_INVALID_PARAM);
2631
2632     //Select the OxM to performing ownership transfer
2633     res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
2634                                           selectedDevice->doxm->oxmLen,
2635                                           &selectedDevice->doxm->oxmSel,
2636                                           SUPER_OWNER);
2637     if(OC_STACK_OK != res)
2638     {
2639         OIC_LOG_V(ERROR, TAG, "Failed to select the provisioning method : %d", res);
2640         SetResult(otmCtx, res);
2641         return res;
2642     }
2643     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
2644
2645     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
2646     if(OC_STACK_OK != res)
2647     {
2648         OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
2649         return res;
2650     }
2651
2652 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2653     //Register TLS event handler, to catch the TLS handshake event
2654     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2655     {
2656         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2657     }
2658 #endif // __WITH_DTLS__ or __WITH_TLS__
2659
2660     //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
2661     res = PostOwnerTransferModeToResource(otmCtx);
2662     if(OC_STACK_OK != res)
2663     {
2664         OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
2665         SetResult(otmCtx, res);
2666         return res;
2667     }
2668
2669     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2670
2671     return res;
2672 }
2673
2674 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
2675 {
2676     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
2677
2678     if(!data)
2679     {
2680         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
2681         return OC_STACK_INVALID_PARAM;
2682     }
2683     if(oxmType >= OIC_OXM_COUNT)
2684     {
2685         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
2686         return OC_STACK_INVALID_PARAM;
2687     }
2688
2689     // TODO: Remove this API, Please see the jira ticket IOT-1484
2690
2691     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
2692
2693     return OC_STACK_OK;
2694 }
2695
2696 /**
2697  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
2698  */
2699 OCStackResult OTMDoOwnershipTransfer(void* ctx,
2700                                      OCProvisionDev_t *selectedDevicelist,
2701                                      OCProvisionResultCB resultCallback)
2702 {
2703     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
2704
2705     if (NULL == selectedDevicelist)
2706     {
2707         return OC_STACK_INVALID_PARAM;
2708     }
2709     if (NULL == resultCallback)
2710     {
2711         return OC_STACK_INVALID_CALLBACK;
2712     }
2713
2714     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2715     if(!otmCtx)
2716     {
2717         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2718         return OC_STACK_NO_MEMORY;
2719     }
2720
2721     otmCtx->ctxResultCallback = resultCallback;
2722     otmCtx->ctxHasError = false;
2723     otmCtx->userCtx = ctx;
2724     OCProvisionDev_t* pCurDev = selectedDevicelist;
2725
2726     //Counting number of selected devices.
2727     otmCtx->ctxResultArraySize = 0;
2728     while(NULL != pCurDev)
2729     {
2730         otmCtx->ctxResultArraySize++;
2731         pCurDev = pCurDev->next;
2732     }
2733
2734     otmCtx->ctxResultArray =
2735         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2736     if(NULL == otmCtx->ctxResultArray)
2737     {
2738         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2739         OICFree(otmCtx);
2740         return OC_STACK_NO_MEMORY;
2741     }
2742     pCurDev = selectedDevicelist;
2743
2744     //Fill the device UUID for result array.
2745     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
2746     {
2747         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
2748                pCurDev->doxm->deviceID.id,
2749                UUID_LENGTH);
2750         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
2751         pCurDev = pCurDev->next;
2752     }
2753
2754     SetDosState(DOS_RFPRO);
2755     OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist);
2756
2757     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
2758
2759     return res;
2760 }
2761
2762 OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
2763 {
2764     OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
2765               __func__, oxm, (allowStatus ? "true" : "false"));
2766
2767 #ifdef MULTIPLE_OWNER
2768     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
2769 #else
2770     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
2771 #endif
2772     {
2773         return OC_STACK_INVALID_PARAM;
2774     }
2775
2776     OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
2777     if(OXM_IDX_COUNT <= oxmIdx)
2778     {
2779         OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
2780         return OC_STACK_ERROR;
2781     }
2782     g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
2783
2784     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2785
2786     return OC_STACK_OK;
2787 }
2788
2789 OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
2790 {
2791     OIC_LOG_V(INFO, TAG, "IN %s", __func__);
2792     OCStackResult res = OC_STACK_ERROR;
2793     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2794
2795     VERIFY_NOT_NULL_RETURN(TAG, otmCtx, ERROR, OC_STACK_INVALID_PARAM);
2796     VERIFY_NOT_NULL_RETURN(TAG, otmCtx->selectedDeviceInfo, ERROR, OC_STACK_INVALID_PARAM);
2797
2798     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2799     // Change the TAKE_OWNER bit of TM to 0 (optional in Client Directed)
2800     otmCtx->selectedDeviceInfo->pstat->tm &= (~TAKE_OWNER);
2801
2802     // Change the dos.s value to RFPRO
2803     otmCtx->selectedDeviceInfo->pstat->dos.state = DOS_RFPRO;
2804
2805     // TODO [IOT-2052] set the rowneruuid for /pstat directly, so the hack
2806     // in pstatresource.c which sets all rowneruuids can be removed.
2807
2808     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2809     if (NULL == secPayload)
2810     {
2811         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2812         return OC_STACK_NO_MEMORY;
2813     }
2814     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2815
2816     // Note [IOT-2052] all the POST payloads in the provisioningclient app
2817     // should be updated to use the Partial payload APIs for the SVRs, so they
2818     // do not include read-only Properties for the Server device current
2819     // state.
2820     OCHeaderOption *options = NULL;
2821     uint8_t numOptions = 0;
2822     bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
2823     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
2824     propertiesToInclude[PSTAT_DOS] = true;
2825     propertiesToInclude[PSTAT_TM] = true;
2826
2827     if (DOS_RFOTM != otmCtx->selectedDeviceInfo->pstat->dos.state)
2828     {
2829         propertiesToInclude[PSTAT_ROWNERUUID] = false;
2830     }
2831     else
2832     {
2833         propertiesToInclude[PSTAT_ROWNERUUID] = true;
2834     }
2835     //pstat.rowneruuid set to the provisioningclient's /doxm.deviceuuid.
2836     if (OC_STACK_OK != GetDoxmDeviceID(&deviceInfo->pstat->rownerID))
2837     {
2838         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2839         res = OC_STACK_ERROR;
2840         goto exit;
2841     }
2842
2843     if (IS_OIC(deviceInfo->specVer))
2844     {
2845         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2846         if (NULL == options)
2847         {
2848             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2849             res = OC_STACK_NO_MEMORY;
2850             goto exit;
2851         }
2852
2853         SetCBORFormat(options, &numOptions);
2854         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2855         propertiesToInclude[PSTAT_ISOP] = true;
2856         propertiesToInclude[PSTAT_CM] = true;
2857         propertiesToInclude[PSTAT_OM] = true;
2858     }
2859     if (OC_STACK_OK != PstatToCBORPayloadPartial(otmCtx->selectedDeviceInfo->pstat,
2860             &secPayload->securityData, &secPayload->payloadSize, propertiesToInclude, false))
2861     {
2862         res = OC_STACK_INVALID_JSON;
2863         goto exit;
2864     }
2865     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2866     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2867
2868     assert(otmCtx->selectedDeviceInfo->connType & CT_FLAG_SECURE);
2869
2870     if(!PMGenerateQuery(true,
2871                         otmCtx->selectedDeviceInfo->endpoint.addr,
2872                         getSecurePort(otmCtx->selectedDeviceInfo),
2873                         otmCtx->selectedDeviceInfo->connType,
2874                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2875     {
2876         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2877         res = OC_STACK_ERROR;
2878         goto exit;
2879     }
2880     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2881
2882     OCCallbackData cbData;
2883     memset(&cbData, 0, sizeof(cbData));
2884     cbData.cb = &ProvisioningStatusHandler;
2885     cbData.context = (void*)otmCtx;
2886     cbData.cd = NULL;
2887     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2888             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2889     secPayload = NULL;
2890     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",res);
2891     if (res != OC_STACK_OK)
2892     {
2893         OIC_LOG(ERROR, TAG, "OCStack resource error");
2894     }
2895
2896 exit:
2897     OICFree(options);
2898     OCPayloadDestroy((OCPayload *)secPayload);
2899     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2900
2901     return res;
2902 }
2903
2904 OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
2905 {
2906     OIC_LOG(INFO, TAG, "IN PostNormalOperationStatus");
2907     OCStackResult res = OC_STACK_ERROR;
2908     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2909
2910     VERIFY_NOT_NULL_RETURN(TAG, otmCtx, ERROR, OC_STACK_INVALID_PARAM);
2911     VERIFY_NOT_NULL_RETURN(TAG, otmCtx->selectedDeviceInfo, ERROR, OC_STACK_INVALID_PARAM);
2912
2913     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2914     otmCtx->selectedDeviceInfo->pstat->dos.state = DOS_RFNOP;
2915
2916     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2917     VERIFY_NOT_NULL_RETURN(TAG, secPayload, ERROR, OC_STACK_NO_MEMORY);
2918
2919     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2920     OCHeaderOption *options = NULL;
2921     uint8_t numOptions = 0;
2922
2923     bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
2924     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
2925
2926     if (IS_OIC(deviceInfo->specVer))
2927     {
2928         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2929         if (NULL == options)
2930         {
2931             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2932             res = OC_STACK_NO_MEMORY;
2933             goto exit;
2934         }
2935         SetCBORFormat(options, &numOptions);
2936         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2937         //Set isop to true.
2938         deviceInfo->pstat->isOp = true;
2939         deviceInfo->pstat->cm = NORMAL;
2940
2941         propertiesToInclude[PSTAT_ISOP] = true;
2942         propertiesToInclude[PSTAT_CM] = true;
2943         propertiesToInclude[PSTAT_TM] = true;
2944         propertiesToInclude[PSTAT_OM] = true;
2945     }
2946     else
2947     {
2948         propertiesToInclude[PSTAT_DOS] = true;
2949     }
2950     res = PstatToCBORPayloadPartial(otmCtx->selectedDeviceInfo->pstat,
2951             &secPayload->securityData, &secPayload->payloadSize, propertiesToInclude, false);
2952
2953     if (OC_STACK_OK != res)
2954     {
2955         res = OC_STACK_INVALID_JSON;
2956         goto exit;
2957     }
2958     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2959     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2960
2961     assert(otmCtx->selectedDeviceInfo->connType & CT_FLAG_SECURE);
2962
2963     if(!PMGenerateQuery(true,
2964                         otmCtx->selectedDeviceInfo->endpoint.addr,
2965                         getSecurePort(otmCtx->selectedDeviceInfo),
2966                         otmCtx->selectedDeviceInfo->connType,
2967                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2968     {
2969         OIC_LOG(ERROR, TAG, "PostNormalOperationStatus : Failed to generate query");
2970         res = OC_STACK_ERROR;
2971         goto exit;
2972     }
2973     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2974
2975     OCCallbackData cbData;
2976     memset(&cbData, 0, sizeof(cbData));
2977     cbData.cb = &ReadyForNomalStatusHandler;
2978     cbData.context = (void*)otmCtx;
2979     cbData.cd = NULL;
2980     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2981             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2982     secPayload = NULL;
2983     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",res);
2984     if (res != OC_STACK_OK)
2985     {
2986         OIC_LOG(ERROR, TAG, "OCStack resource error");
2987     }
2988
2989 exit:
2990     OICFree(options);
2991     OCPayloadDestroy((OCPayload *)secPayload);
2992     OIC_LOG(INFO, TAG, "OUT PostNormalOperationStatus");
2993
2994     return res;
2995 }
2996
2997 OCStackResult ConfigSelfOwnership(void)
2998 {
2999     OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership");
3000
3001     bool isDeviceOwned = true;
3002     if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned))
3003     {
3004         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state");
3005         return OC_STACK_ERROR;
3006     }
3007
3008     bool isop = false;
3009     if (OC_STACK_OK != GetPstatIsop(&isop))
3010     {
3011         OIC_LOG(ERROR, TAG, "Failed to get pstat.isop.");
3012         return OC_STACK_ERROR;
3013     }
3014     if (isDeviceOwned || isop)
3015     {
3016         OIC_LOG_V(ERROR, TAG, "%s: The state of device is not Ready for Ownership transfer: %s", __func__, isDeviceOwned ? "isDeviceOwned" : "isop");
3017         return OC_STACK_ERROR;
3018     }
3019
3020     OicUuid_t deviceID = {.id={0}};
3021     if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
3022     {