21dae06d9d266c8bf1935baeb19079ce2bf21683
[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 &= ~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
767     if (NULL == endpoint || NULL == info)
768     {
769         goto exit;
770     }
771
772     OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
773               endpoint->addr, endpoint->port, info->result);
774
775     OTMContext_t* otmCtx = GetOTMContext(endpoint->addr, endpoint->port);
776     if (NULL == otmCtx)
777     {
778         OIC_LOG(ERROR, TAG, "OTM context not found!");
779         goto exit;
780     }
781
782     OicSecDoxm_t* newDevDoxm = otmCtx->selectedDeviceInfo->doxm;
783     if (NULL == newDevDoxm)
784     {
785         OIC_LOG(ERROR, TAG, "New device doxm not found!");
786         goto exit;
787     }
788
789     //Make sure the address matches.
790     bool matching = (0 == strncmp(otmCtx->selectedDeviceInfo->endpoint.addr,
791                                   endpoint->addr, sizeof(endpoint->addr)));
792     matching = (matching && (getSecurePort(otmCtx->selectedDeviceInfo) == endpoint->port));
793
794     if (!matching)
795     {
796         OIC_LOG_V(ERROR, TAG, "Mismatched: expected address %s:%u",
797                   otmCtx->selectedDeviceInfo->endpoint.addr, getSecurePort(otmCtx->selectedDeviceInfo));
798         goto exit;
799     }
800
801     OicUuid_t emptyUuid = {.id={0}};
802     bool emptyOwnerUuid = (memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0);
803
804     //If temporal secure session established successfully
805     if ((CA_STATUS_OK == info->result) && !newDevDoxm->owned && emptyOwnerUuid)
806     {
807         result = OwnershipTransferSessionEstablished(endpoint, newDevDoxm, otmCtx);
808     }
809     else
810     {
811         result = OwnershipTransferSessionFailed(endpoint, info, newDevDoxm, otmCtx, emptyOwnerUuid);
812     }
813
814 exit:
815     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
816     return result;
817 }
818
819 /**
820  * Function to save the Owner/SubOwner PSK.
821  *
822  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
823  * @return  OC_STACK_OK on success
824  */
825 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
826 {
827     OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
828
829     OCStackResult res = OC_STACK_ERROR;
830
831     CAEndpoint_t endpoint;
832     CopyDevAddrToEndpoint(&selectedDeviceInfo->endpoint, &endpoint);
833     endpoint.port = getSecurePort(selectedDeviceInfo);
834
835     OicUuid_t ownerDeviceID = {.id={0}};
836     if (OC_STACK_OK != GetDoxmDeviceID(&ownerDeviceID))
837     {
838         OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
839         return res;
840     }
841
842     OicSecKey_t ownerKey;
843     memset(&ownerKey, 0, sizeof(ownerKey));
844
845     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = { 0 };
846     ownerKey.data = ownerPSK;
847     ownerKey.len = OWNER_PSK_LENGTH_128;
848     ownerKey.encoding = OIC_ENCODING_RAW;
849
850     //Generating OwnerPSK
851     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
852             (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
853             strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
854             ownerDeviceID.id, sizeof(ownerDeviceID.id),
855             selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
856             ownerPSK, OWNER_PSK_LENGTH_128);
857
858     if (CA_STATUS_OK == pskRet)
859     {
860         OIC_LOG(DEBUG, TAG,"Owner PSK dump:");
861         OIC_LOG_BUFFER(DEBUG, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
862         //Generating new credential for provisioning tool
863         OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
864                                   SYMMETRIC_PAIR_WISE_KEY, NULL,
865                                   &ownerKey, NULL);
866         OICClearMemory(ownerPSK, sizeof(ownerPSK));
867         VERIFY_NOT_NULL(TAG, cred, ERROR);
868
869         size_t outSize = 0;
870         int encodeResult = mbedtls_base64_encode(NULL, 0, &outSize, cred->privateData.data, cred->privateData.len);
871         if (MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL != encodeResult)
872         {
873             OIC_LOG_V(ERROR, TAG, "%s: Error base64 encoding PSK private data", __func__);
874             res = OC_STACK_ERROR;
875             goto exit;
876         }
877         size_t b64BufSize = outSize;
878         unsigned char* b64Buf = (unsigned char *)OICCalloc(1, b64BufSize);
879         VERIFY_NOT_NULL(TAG, b64Buf, ERROR);
880        encodeResult =  mbedtls_base64_encode(b64Buf, b64BufSize, &outSize, cred->privateData.data, cred->privateData.len);
881        if (0 != encodeResult)
882        {
883            OIC_LOG_V(ERROR, TAG, "%s: Error base64 encoding PSK private data", __func__);
884            OICFree(b64Buf);
885            res = OC_STACK_ERROR;
886            goto exit;
887        }
888         OICFree( cred->privateData.data );
889         cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
890         VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
891
892         strncpy((char*)(cred->privateData.data), (char*)b64Buf, outSize);
893         cred->privateData.data[outSize] = '\0';
894         cred->privateData.encoding = OIC_ENCODING_BASE64;
895         cred->privateData.len = outSize;
896         OICFree(b64Buf);
897
898         //Finding previous ownerPSK.
899         const OicSecCred_t* credList = GetCredList();
900         const OicSecCred_t* prevCred = NULL;
901         uint16_t credId = 0;
902         LL_FOREACH(credList, prevCred)
903         {
904             //OwnerPSK's type is SYMMETRIC_PAIR_WISE_KEY
905             if (SYMMETRIC_PAIR_WISE_KEY == prevCred->credType &&
906                 0 == memcmp(prevCred->subject.id, cred->subject.id, sizeof(cred->subject.id)))
907             {
908                 credId = prevCred->credId;
909                 break;
910             }
911         }
912
913         //If duplicate owner PSK is exists, remove it.
914         if(0 < credId)
915         {
916             OIC_LOG(WARNING, TAG, "Duplicate OwnerPSK was detected.");
917             OIC_LOG(WARNING, TAG, "[Subject] : ");
918             OIC_LOG_BUFFER(WARNING, TAG, prevCred->subject.id, sizeof(prevCred->subject.id));
919             OIC_LOG_V(WARNING, TAG, "[Encoding Type] : %d", prevCred->privateData.encoding);
920             OIC_LOG(DEBUG, TAG, "[Private Data] : ");
921             OIC_LOG_BUFFER(DEBUG, TAG, prevCred->privateData.data, prevCred->privateData.len);
922             OIC_LOG(WARNING, TAG, "Previous OwnerPSK will be removed.");
923
924             res = RemoveCredentialByCredId(credId);
925             if(OC_STACK_RESOURCE_DELETED != res)
926             {
927                 OIC_LOG(ERROR, TAG, "Failed to remove the previous OwnerPSK");
928                 DeleteCredList(cred);
929                 goto exit;
930             }
931         }
932
933         res = AddCredential(cred);
934         if(res != OC_STACK_OK)
935         {
936             DeleteCredList(cred);
937             return res;
938         }
939     }
940     else
941     {
942         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
943     }
944
945     OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
946 exit:
947     return res;
948 }
949
950 /**
951  * Callback handler for OwnerShipTransferModeHandler API.
952  *
953  * @param[in] ctx             ctx value passed to callback from calling function.
954  * @param[in] UNUSED          handle to an invocation
955  * @param[in] clientResponse  Response from queries to remote servers.
956  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
957  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
958  */
959 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
960                                                          OCClientResponse *clientResponse)
961 {
962     OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
963
964     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
965     VERIFY_NOT_NULL(TAG, ctx, WARNING);
966
967     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
968     otmCtx->ocDoHandle = NULL;
969     (void)UNUSED;
970     if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
971     {
972         OCStackResult res = OC_STACK_ERROR;
973
974         //Save the current context, that will be used by the DTLS handshake callback
975         if(OC_STACK_OK != AddOTMContext(otmCtx,
976                                         otmCtx->selectedDeviceInfo->endpoint.addr,
977                                         getSecurePort(otmCtx->selectedDeviceInfo)))
978         {
979             OIC_LOG(ERROR, TAG, "OwnerTransferModeHandler : Failed to add OTM Context into list");
980             SetResult(otmCtx, res);
981             return OC_STACK_DELETE_TRANSACTION;
982         }
983
984         //Create DTLS secure session
985         if(otmCtx->otmCallback.loadSecretCB)
986         {
987             res = otmCtx->otmCallback.loadSecretCB(otmCtx);
988             if(OC_STACK_OK != res)
989             {
990                 OIC_LOG(ERROR, TAG, "OwnerTransferModeHandler : Failed to load secret");
991                 SetResult(otmCtx, res);
992                 return  OC_STACK_DELETE_TRANSACTION;
993             }
994         }
995         if(otmCtx->otmCallback.createSecureSessionCB)
996         {
997             res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
998             if(OC_STACK_OK != res)
999             {
1000                 OIC_LOG(ERROR, TAG, "OwnerTransferModeHandler : Failed to create DTLS session");
1001                 SetResult(otmCtx, res);
1002                 return OC_STACK_DELETE_TRANSACTION;
1003             }
1004
1005             //This is a secure session.
1006             otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
1007
1008             //Send request : GET /oic/sec/doxm. Then verify that the property values obtained this way
1009             //are the same as those already-stored in the otmCtx.
1010             res = GetAndVerifyDoxmResource(otmCtx);
1011             if(OC_STACK_OK != res)
1012             {
1013                 OIC_LOG(ERROR, TAG, "Failed to get doxm information after establishing secure connection");
1014                 SetResult(otmCtx, res);
1015             }
1016         }
1017     }
1018     else
1019     {
1020         OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
1021         clientResponse->result);
1022         SetResult(otmCtx, clientResponse->result);
1023     }
1024
1025     OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
1026
1027 exit:
1028     return  OC_STACK_DELETE_TRANSACTION;
1029 }
1030
1031 /**
1032  * Callback handler for ProvisioningStatusResouceHandler API.
1033  *
1034  * @param[in] ctx             ctx value passed to callback from calling function.
1035  * @param[in] UNUSED          handle to an invocation
1036  * @param[in] clientResponse  Response from queries to remote servers.
1037  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1038  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1039  */
1040 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
1041                                                     OCClientResponse *clientResponse)
1042 {
1043     OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
1044
1045     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1046     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1047
1048     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1049     otmCtx->ocDoHandle = NULL;
1050     (void)UNUSED;
1051     if  (OC_STACK_OK == clientResponse->result)
1052     {
1053         if  (NULL == clientResponse->payload)
1054         {
1055             OIC_LOG(INFO, TAG, "Skipping Null payload");
1056             SetResult(otmCtx, OC_STACK_ERROR);
1057             return OC_STACK_DELETE_TRANSACTION;
1058         }
1059
1060         if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
1061         {
1062             OIC_LOG(INFO, TAG, "Unknown payload type");
1063             SetResult(otmCtx, OC_STACK_ERROR);
1064             return OC_STACK_DELETE_TRANSACTION;
1065         }
1066         OicSecPstat_t* pstat = NULL;
1067         OCStackResult result = CBORPayloadToPstat(
1068                 ((OCSecurityPayload*)clientResponse->payload)->securityData,
1069                 ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
1070                 &pstat);
1071         if(NULL == pstat || result != OC_STACK_OK)
1072         {
1073             OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
1074             SetResult(otmCtx, OC_STACK_ERROR);
1075             return OC_STACK_DELETE_TRANSACTION;
1076         }
1077         if(false == (TAKE_OWNER & pstat->cm))
1078         {
1079             OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
1080             SetResult(otmCtx, OC_STACK_ERROR);
1081             return OC_STACK_DELETE_TRANSACTION;
1082         }
1083         otmCtx->selectedDeviceInfo->pstat = pstat;
1084
1085         //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
1086         SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
1087
1088         //Send request : POST /oic/sec/pstat [{"om":"bx11", .. }]
1089         OCStackResult res = PostUpdateOperationMode(otmCtx);
1090         if (OC_STACK_OK != res)
1091         {
1092             OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
1093             SetResult(otmCtx, res);
1094         }
1095     }
1096     else
1097     {
1098         OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
1099             clientResponse->result);
1100         SetResult(otmCtx, clientResponse->result);
1101     }
1102
1103     OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
1104 exit:
1105     return  OC_STACK_DELETE_TRANSACTION;
1106 }
1107
1108 /**
1109  * Response handler for update device uuid request.
1110  *
1111  * @param[in] ctx             ctx value passed to callback from calling function.
1112  * @param[in] UNUSED          handle to an invocation
1113  * @param[in] clientResponse  Response from queries to remote servers.
1114  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1115  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1116  */
1117 static OCStackApplicationResult DeviceUuidUpdateHandler(void *ctx, OCDoHandle handle,
1118                                 OCClientResponse *clientResponse)
1119 {
1120     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1121     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1122
1123     OIC_LOG(DEBUG, TAG, "IN DeviceUuidUpdateHandler");
1124     OC_UNUSED(handle);
1125     OCStackResult res = OC_STACK_OK;
1126     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1127     otmCtx->ocDoHandle = NULL;
1128
1129     if(OC_STACK_OK != clientResponse->result)
1130     {
1131         OIC_LOG_V(WARNING, TAG, "DeviceUuidUpdateHandler : Client response is incorrect : %d",
1132                 clientResponse->result);
1133         goto exit;
1134     }
1135
1136     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1137     if (NULL == deviceInfo)
1138     {
1139         OIC_LOG(INFO, TAG, "Selected device info is NULL");
1140         SetResult(otmCtx, OC_STACK_ERROR);
1141         return OC_STACK_DELETE_TRANSACTION;
1142     }
1143
1144     OCSecurityPayload *payload = (OCSecurityPayload*)clientResponse->payload;
1145     if (NULL == payload)
1146     {
1147         OIC_LOG(INFO, TAG, "Skipping Null payload");
1148         SetResult(otmCtx, OC_STACK_ERROR);
1149         return OC_STACK_DELETE_TRANSACTION;
1150     }
1151
1152     OicSecDoxm_t *doxm = NULL;
1153     uint8_t *securityData = payload->securityData;
1154     size_t size = payload->payloadSize;
1155
1156     res = CBORPayloadToDoxm(securityData, size, &doxm);
1157     if ((NULL == doxm) || (OC_STACK_OK != res))
1158     {
1159         OIC_LOG(INFO, TAG, "Received malformed CBOR");
1160         SetResult(otmCtx, OC_STACK_ERROR);
1161         return OC_STACK_DELETE_TRANSACTION;
1162     }
1163
1164     //Update existing device uuid in ctxResultArray
1165     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
1166     {
1167         if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
1168                     otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
1169         {
1170             memcpy(otmCtx->ctxResultArray[i].deviceId.id, doxm->deviceID.id, UUID_LENGTH);
1171         }
1172     }
1173
1174     otmCtx->selectedDeviceInfo->doxm->deviceID = doxm->deviceID;
1175
1176     //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
1177     res = SetupPDM(otmCtx->selectedDeviceInfo);
1178     if(OC_STACK_OK != res)
1179     {
1180         OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
1181         SetResult(otmCtx, res);
1182         return res;
1183     }
1184
1185     res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
1186     if(OC_STACK_OK != res)
1187     {
1188         OIC_LOG(ERROR, TAG, "DeviceUuidUpdateHandler:Failed to owner PSK generation");
1189         SetResult(otmCtx, res);
1190         return OC_STACK_DELETE_TRANSACTION;
1191     }
1192
1193     //POST owner credential to new device according to security spec B.
1194     res = PostOwnerCredential(otmCtx);
1195     if(OC_STACK_OK != res)
1196     {
1197         OIC_LOG(ERROR, TAG,
1198                 "DeviceUuidUpdateHandler:Failed to send PosT request for onwer credential");
1199         SetResult(otmCtx, res);
1200         return OC_STACK_DELETE_TRANSACTION;
1201     }
1202
1203     OIC_LOG(DEBUG, TAG, "OUT DeviceUuidUpdateHandler");
1204     return OC_STACK_KEEP_TRANSACTION;
1205
1206 exit:
1207     return  OC_STACK_DELETE_TRANSACTION;
1208 }
1209
1210 /**
1211  * Response handler for update owner uuid request.
1212  *
1213  * @param[in] ctx             ctx value passed to callback from calling function.
1214  * @param[in] UNUSED          handle to an invocation
1215  * @param[in] clientResponse  Response from queries to remote servers.
1216  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1217  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1218  */
1219 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
1220                                 OCClientResponse *clientResponse)
1221 {
1222     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1223     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1224
1225     OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
1226     (void)UNUSED;
1227     OCStackResult res = OC_STACK_OK;
1228     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1229     otmCtx->ocDoHandle = NULL;
1230
1231     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1232     {
1233         if(otmCtx && otmCtx->selectedDeviceInfo)
1234         {
1235             //In case of Mutual Verified Just-Works, wait for user confirmation
1236             if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1237             {
1238                 res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
1239                 if (OC_STACK_OK != res)
1240                 {
1241                     if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, otmCtx->ctxResultCallback))
1242                     {
1243                         OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error");
1244                     }
1245                     OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to verify user confirm");
1246                     SetResult(otmCtx, res);
1247                     return OC_STACK_DELETE_TRANSACTION;
1248                 }
1249             }
1250
1251            res = GetRealUuid(otmCtx);
1252            if(OC_STACK_OK != res)
1253            {
1254                OIC_LOG(ERROR, TAG, "Failed to get doxm information");
1255                SetResult(otmCtx, res);
1256                return OC_STACK_DELETE_TRANSACTION;
1257            }
1258         }
1259     }
1260     else
1261     {
1262         if (OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel &&
1263                     OC_STACK_NOT_ACCEPTABLE == clientResponse->result)
1264         {
1265             res = OC_STACK_USER_DENIED_REQ;
1266         }
1267         else
1268         {
1269             res = clientResponse->result;
1270         }
1271         OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
1272         SetResult(otmCtx, res);
1273         return OC_STACK_DELETE_TRANSACTION;
1274     }
1275
1276     OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
1277
1278 exit:
1279     return  OC_STACK_DELETE_TRANSACTION;
1280 }
1281
1282 /**
1283  * Response handler for update operation mode.
1284  *
1285  * @param[in] ctx             ctx value passed to callback from calling function.
1286  * @param[in] UNUSED          handle to an invocation
1287  * @param[in] clientResponse  Response from queries to remote servers.
1288  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1289  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1290  */
1291 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
1292                                 OCClientResponse *clientResponse)
1293 {
1294     OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
1295
1296     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1297     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1298
1299     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1300     otmCtx->ocDoHandle = NULL;
1301     (void) UNUSED;
1302     if  (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1303     {
1304         //Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
1305         OCStackResult res = PostOwnerUuid(otmCtx);
1306         if(OC_STACK_OK != res)
1307         {
1308             OIC_LOG(ERROR, TAG, "OperationModeUpdateHandler: Failed to send devowner");
1309             SetResult(otmCtx, res);
1310         }
1311     }
1312     else
1313     {
1314         OIC_LOG(ERROR, TAG, "Error while updating operation mode");
1315         SetResult(otmCtx, clientResponse->result);
1316     }
1317
1318     OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
1319
1320 exit:
1321     return  OC_STACK_DELETE_TRANSACTION;
1322 }
1323
1324 /**
1325  * Response handler for update owner crendetial request.
1326  *
1327  * @param[in] ctx             ctx value passed to callback from calling function.
1328  * @param[in] UNUSED          handle to an invocation
1329  * @param[in] clientResponse  Response from queries to remote servers.
1330  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1331  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1332  */
1333 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
1334                                 OCClientResponse *clientResponse)
1335 {
1336     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1337     VERIFY_NOT_NULL(TAG, ctx, WARNING);
1338
1339     OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
1340     (void)UNUSED;
1341     OCStackResult res = OC_STACK_OK;
1342     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1343     otmCtx->ocDoHandle = NULL;
1344
1345     if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1346     {
1347         if(otmCtx->selectedDeviceInfo)
1348         {
1349             //For Servers based on OCF 1.0, PostOwnerAcl can be executed using
1350             //the already-existing session. However, get ready here to use the
1351             //Owner Credential for establishing future secure sessions.
1352             //
1353             //For Servers based on OIC 1.1, PostOwnerAcl might fail with status
1354             //OC_STACK_UNAUTHORIZED_REQ. After such a failure, OwnerAclHandler
1355             //will close the current session and re-establish a new session,
1356             //using the Owner Credential.
1357             CAEndpoint_t *endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
1358
1359             if (IS_OIC(otmCtx->selectedDeviceInfo->specVer))
1360             {
1361                 endpoint->port = getSecurePort(otmCtx->selectedDeviceInfo);
1362                 if(CA_STATUS_OK != CAcloseSslConnection(endpoint))
1363                 {
1364                     OIC_LOG_V(WARNING, TAG, "%s: failed to close DTLS session", __func__);
1365                 }
1366             }
1367
1368             /**
1369               * If we select NULL cipher,
1370               * client will select appropriate cipher suite according to server's cipher-suite list.
1371               */
1372             // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
1373                 CAResult_t caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
1374                 if(CA_STATUS_OK != caResult)
1375                 {
1376                     OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
1377                     SetResult(otmCtx, CAResultToOCResult(caResult));
1378                     return OC_STACK_DELETE_TRANSACTION;
1379                 }
1380
1381                 /**
1382                   * in case of random PIN based OxM,
1383                   * revert get_psk_info callback of tinyDTLS to use owner credential.
1384                   */
1385                 if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
1386                 {
1387                     OicUuid_t emptyUuid = { .id={0}};
1388                     SetUuidForPinBasedOxm(&emptyUuid);
1389
1390                     caResult = CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
1391                     if(CA_STATUS_OK != caResult)
1392                     {
1393                         OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1394                         SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
1395                         return OC_STACK_DELETE_TRANSACTION;
1396                     }
1397                 }
1398     #ifdef __WITH_TLS__
1399                 otmCtx->selectedDeviceInfo->connType |= CT_FLAG_SECURE;
1400     #endif
1401                 res = PostOwnerAcl(otmCtx, GET_ACL_VER(otmCtx->selectedDeviceInfo->specVer));
1402                 if(OC_STACK_OK != res)
1403                 {
1404                     OIC_LOG(ERROR, TAG, "Failed to update owner ACL to new device");
1405                     SetResult(otmCtx, res);
1406                     return OC_STACK_DELETE_TRANSACTION;
1407                 }
1408             }
1409         }
1410         else
1411         {
1412             res = clientResponse->result;
1413             OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
1414             SetResult(otmCtx, res);
1415         }
1416
1417         OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
1418
1419     exit:
1420         return  OC_STACK_DELETE_TRANSACTION;
1421     }
1422
1423     static void SetAclVer2(char specVer[]){specVer[0]='o'; specVer[1]='c'; specVer[2]='f';}
1424
1425     /**
1426      * Response handler for update owner ACL request.
1427      *
1428      * @param[in] ctx             ctx value passed to callback from calling function.
1429      * @param[in] UNUSED          handle to an invocation
1430      * @param[in] clientResponse  Response from queries to remote servers.
1431      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1432      *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1433      */
1434     static OCStackApplicationResult OwnerAclHandler(void *ctx, OCDoHandle handle,
1435                                     OCClientResponse *clientResponse)
1436     {
1437         OIC_LOG(DEBUG, TAG, "IN OwnerAclHandler");
1438
1439         OC_UNUSED(handle);
1440
1441         VERIFY_NOT_NULL(TAG, ctx, WARNING);
1442         OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1443         VERIFY_NOT_NULL(TAG, otmCtx->selectedDeviceInfo, WARNING);
1444         OCProvisionDev_t* selectedDeviceInfo = otmCtx->selectedDeviceInfo;
1445         VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1446
1447         otmCtx->ocDoHandle = NULL;
1448
1449         OCStackResult res = clientResponse->result;
1450         if(OC_STACK_RESOURCE_CHANGED == res)
1451         {
1452             if(NULL != selectedDeviceInfo)
1453             {
1454                 //POST /oic/sec/doxm [{ ..., "owned":"TRUE" }]
1455                 OIC_LOG_V(DEBUG, TAG, "%s posting /doxm.owned = true.", __func__);
1456                 res = PostOwnershipInformation(otmCtx);
1457                 if(OC_STACK_OK != res)
1458                 {
1459                     OIC_LOG_V(ERROR, TAG, "%s: Failed to update the ownership information"
1460                         "of the new device, res = %d",
1461                         __func__, res);
1462                     SetResult(otmCtx, res);
1463                 }
1464             }
1465         }
1466         else if(OC_STACK_NO_RESOURCE == res)
1467         {
1468             OIC_LOG_V(WARNING, TAG, "%s: not found uri", __func__);
1469             if(OIC_SEC_ACL_V1 == GET_ACL_VER(otmCtx->selectedDeviceInfo->specVer))
1470             {
1471                 SetAclVer2(otmCtx->selectedDeviceInfo->specVer);
1472                 OIC_LOG_V(WARNING, TAG, "%s: set acl v2", __func__);
1473                 PostOwnerAcl(otmCtx, OIC_SEC_ACL_V2);
1474             }
1475         }
1476         else
1477         {
1478             OIC_LOG_V(ERROR, TAG, "OwnerAclHandler : Unexpected result %d", res);
1479             SetResult(otmCtx, res);
1480         }
1481     exit:
1482         OIC_LOG(DEBUG, TAG, "OUT OwnerAclHandler");
1483         return  OC_STACK_DELETE_TRANSACTION;
1484     }
1485
1486     /**
1487      * Response handler for update owner information request.
1488      *
1489      * @param[in] ctx             ctx value passed to callback from calling function.
1490      * @param[in] UNUSED          handle to an invocation
1491      * @param[in] clientResponse  Response from queries to remote servers.
1492      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1493      *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1494      */
1495     static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
1496                                     OCClientResponse *clientResponse)
1497     {
1498         VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1499         VERIFY_NOT_NULL(TAG, ctx, WARNING);
1500
1501         OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
1502         (void)UNUSED;
1503         OCStackResult res = OC_STACK_OK;
1504         OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1505         otmCtx->ocDoHandle = NULL;
1506
1507         if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1508         {
1509             if(otmCtx && otmCtx->selectedDeviceInfo)
1510             {
1511                 OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
1512                 OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
1513
1514                 res = PostRownerUuid(otmCtx);
1515                 if(OC_STACK_OK != res)
1516                 {
1517                     OIC_LOG(ERROR, TAG, "Failed to set rowneruuid pstat");
1518                     SetResult(otmCtx, res);
1519                 }
1520             }
1521         }
1522         else
1523         {
1524             res = clientResponse->result;
1525             OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
1526             SetResult(otmCtx, res);
1527         }
1528
1529         OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
1530
1531     exit:
1532         return  OC_STACK_DELETE_TRANSACTION;
1533     }
1534
1535     /**
1536      * Response handler of update provisioning status.
1537      *
1538      * @param[in] ctx             ctx value passed to callback from calling function.
1539      * @param[in] UNUSED          handle to an invocation
1540      * @param[in] clientResponse  Response from queries to remote servers.
1541      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1542      *          and OC_STACK_KEEP_TRANSACTION to keep it.
1543      */
1544     static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
1545                                                            OCClientResponse *clientResponse)
1546     {
1547         OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
1548
1549         VERIFY_NOT_NULL(TAG, clientResponse, ERROR);
1550         VERIFY_NOT_NULL(TAG, ctx, ERROR);
1551
1552         OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1553         otmCtx->ocDoHandle = NULL;
1554         (void)UNUSED;
1555         OCStackResult res = OC_STACK_OK;
1556
1557         if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1558         {
1559             if(otmCtx && otmCtx->selectedDeviceInfo)
1560             {
1561                 OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
1562
1563                 res = PostNormalOperationStatus(otmCtx);
1564                 if(OC_STACK_OK != res)
1565                 {
1566                     OIC_LOG(ERROR, TAG, "Failed to update pstat");
1567                     SetResult(otmCtx, res);
1568                 }
1569             }
1570         }
1571         else
1572         {
1573             OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1574                                 clientResponse->result);
1575             SetResult(otmCtx, clientResponse->result);
1576         }
1577
1578     exit:
1579         OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
1580         return OC_STACK_DELETE_TRANSACTION;
1581     }
1582
1583     /**
1584      * Response handler of update provisioning status to Ready for Normal..
1585      *
1586      * @param[in] ctx             ctx value passed to callback from calling function.
1587      * @param[in] UNUSED          handle to an invocation
1588      * @param[in] clientResponse  Response from queries to remote servers.
1589      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1590      *          and OC_STACK_KEEP_TRANSACTION to keep it.
1591      */
1592     static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
1593                                                            OCClientResponse *clientResponse)
1594     {
1595         OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
1596
1597         VERIFY_NOT_NULL(TAG, clientResponse, ERROR);
1598         VERIFY_NOT_NULL(TAG, ctx, ERROR);
1599
1600         OTMContext_t* otmCtx = (OTMContext_t*) ctx;
1601         otmCtx->ocDoHandle = NULL;
1602         (void)UNUSED;
1603
1604         if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
1605         {
1606             OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
1607             OCStackResult res = PDMSetDeviceState(&otmCtx->selectedDeviceInfo->doxm->deviceID,
1608                                                   PDM_DEVICE_ACTIVE);
1609             if (OC_STACK_OK == res)
1610             {
1611                 CloseSslConnection(otmCtx->selectedDeviceInfo);
1612                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
1613                 SetResult(otmCtx, OC_STACK_OK);
1614                 return OC_STACK_DELETE_TRANSACTION;
1615             }
1616             else
1617             {
1618                 OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
1619             }
1620         }
1621         else
1622         {
1623             OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
1624                                 clientResponse->result);
1625             SetResult(otmCtx, clientResponse->result);
1626         }
1627
1628     exit:
1629         OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
1630         return OC_STACK_DELETE_TRANSACTION;
1631     }
1632
1633     /**
1634      * Callback handler for GetAndVerifyDoxmResource.
1635      *
1636      * @param[in] ctx             ctx value passed to callback from calling function.
1637      * @param[in] UNUSED          handle to an invocation
1638      * @param[in] clientResponse  Response from queries to remote servers.
1639      * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
1640      *          and  OC_STACK_KEEP_TRANSACTION to keep it.
1641      */
1642     static OCStackApplicationResult GetAndVerifyDoxmHandler(void *ctx, OCDoHandle UNUSED,
1643                                                         OCClientResponse *clientResponse)
1644     {
1645         OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
1646
1647         VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
1648         VERIFY_NOT_NULL(TAG, ctx, WARNING);
1649
1650         OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1651         otmCtx->ocDoHandle = NULL;
1652         (void)UNUSED;
1653
1654         if (OC_STACK_CONTINUE_OPERATION == clientResponse->result)
1655         {
1656             OIC_LOG(INFO, TAG, "Skipping error handling until pass all random pin tries");
1657         }
1658         else if (OC_STACK_OK != clientResponse->result)
1659         {
1660             OIC_LOG_V(WARNING, TAG, "%s : Client response is incorrect : %d",
1661                 __func__, clientResponse->result);
1662             SetResult(otmCtx, clientResponse->result);
1663         }
1664         else
1665         {
1666             //Sanity checks.
1667             OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1668             if (NULL == deviceInfo)
1669             {
1670                 OIC_LOG(INFO, TAG, "Selected device info is NULL");
1671                 SetResult(otmCtx, OC_STACK_ERROR);
1672                 return OC_STACK_DELETE_TRANSACTION;
1673             }
1674
1675             OCSecurityPayload *payload = (OCSecurityPayload*)clientResponse->payload;
1676             if (NULL == payload)
1677             {
1678                 OIC_LOG(INFO, TAG, "Skipping Null payload");
1679                 SetResult(otmCtx, OC_STACK_ERROR);
1680                 return OC_STACK_DELETE_TRANSACTION;
1681             }
1682
1683             if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
1684             {
1685                 OIC_LOG(INFO, TAG, "Unknown payload type");
1686                 SetResult(otmCtx, OC_STACK_ERROR);
1687                 return OC_STACK_DELETE_TRANSACTION;
1688             }
1689
1690             //Compare the doxm property values obtained over this secured session with those
1691             //values obtained before the DTLS handshake.
1692             OicSecDoxm_t *doxm = NULL;
1693             uint8_t *securityData = payload->securityData;
1694             size_t size = payload->payloadSize;
1695
1696             OCStackResult res = CBORPayloadToDoxm(securityData, size, &doxm);
1697             if ((NULL == doxm) || (OC_STACK_OK != res))
1698             {
1699                 OIC_LOG(INFO, TAG, "Received malformed CBOR");
1700                 SetResult(otmCtx, OC_STACK_ERROR);
1701                 return OC_STACK_DELETE_TRANSACTION;
1702             }
1703
1704             bool equal = AreDoxmBinPropertyValuesEqual(doxm, deviceInfo->doxm);
1705             DeleteDoxmBinData(doxm);
1706             if (!equal)
1707             {
1708                 SetResult(otmCtx, OC_STACK_ERROR);
1709                 return OC_STACK_DELETE_TRANSACTION;
1710             }
1711
1712             //Send request : GET /oic/sec/pstat
1713             res = GetProvisioningStatusResource(otmCtx);
1714             if(OC_STACK_OK != res)
1715             {
1716                 OIC_LOG(ERROR, TAG, "Failed to get pstat information");
1717                 SetResult(otmCtx, res);
1718             }
1719         }
1720
1721         OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
1722     exit:
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     if (!otmCtx || !otmCtx->selectedDeviceInfo)
1734     {
1735         OIC_LOG(ERROR, TAG, "Invalid parameters");
1736         return OC_STACK_INVALID_PARAM;
1737     }
1738
1739     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1740     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1741     assert(deviceInfo->connType & CT_FLAG_SECURE);
1742
1743     if (!PMGenerateQuery(true,
1744                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
1745                         deviceInfo->connType,
1746                         query, sizeof(query), OIC_RSRC_CRED_URI))
1747     {
1748         OIC_LOG(ERROR, TAG, "PostOwnerCredential : Failed to generate query");
1749         return OC_STACK_ERROR;
1750     }
1751     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1752     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1753     if (NULL == secPayload)
1754     {
1755         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1756         return OC_STACK_NO_MEMORY;
1757     }
1758
1759     //Generate owner credential for new device
1760     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1761     const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
1762     if (NULL == ownerCredential)
1763     {
1764         OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
1765         res = OC_STACK_NO_RESOURCE;
1766         goto exit;
1767     }
1768
1769     OicUuid_t credSubjectId = {.id={0}};
1770     if (OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
1771     {
1772         OicSecCred_t newCredential;
1773         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
1774         newCredential.next = NULL;
1775
1776         //Set subject ID as PT's ID
1777         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
1778
1779         if (IS_OIC(deviceInfo->specVer))
1780         {
1781             options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
1782             if (NULL == options)
1783             {
1784                 OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1785                 res = OC_STACK_NO_MEMORY;
1786                 goto exit;
1787             }
1788
1789             SetCBORFormat(options, &numOptions);
1790             OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
1791         }
1792
1793         //Fill private data as empty string
1794         newCredential.privateData.data = (uint8_t*)"";
1795         newCredential.privateData.len = 0;
1796         newCredential.privateData.encoding = ownerCredential->privateData.encoding;
1797
1798         newCredential.publicData.data = NULL;
1799         newCredential.publicData.len = 0;
1800         newCredential.publicData.encoding = ownerCredential->publicData.encoding;
1801
1802         int secureFlag = 0;
1803         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
1804         if (OC_STACK_OK != CredToCBORPayloadWithRowner(&newCredential, &credSubjectId, &secPayload->securityData,
1805                                         &secPayload->payloadSize, secureFlag))
1806         {
1807             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1808             res = OC_STACK_ERROR;
1809             goto exit;
1810         }
1811         OIC_LOG(DEBUG, TAG, "Cred Payload:");
1812         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1813
1814         OCCallbackData cbData;
1815         cbData.cb = &OwnerCredentialHandler;
1816         cbData.context = (void *)otmCtx;
1817         cbData.cd = NULL;
1818         res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
1819                                          &deviceInfo->endpoint, (OCPayload*)secPayload,
1820                                          deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
1821         secPayload = NULL;
1822         if (res != OC_STACK_OK)
1823         {
1824             OIC_LOG(ERROR, TAG, "OCStack resource error");
1825         }
1826     }
1827     else
1828     {
1829         OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
1830         res = OC_STACK_NO_RESOURCE;
1831     }
1832
1833 exit:
1834     OICFree(options);
1835     OCPayloadDestroy((OCPayload *)secPayload);
1836     OIC_LOG(DEBUG, TAG, "OUT PostOwnerCredential");
1837
1838     return res;
1839 }
1840
1841 static OicSecAcl_t* GenerateOwnerAcl(const OicUuid_t* owner)
1842 {
1843     OicSecAcl_t* ownerAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
1844     OicSecAce_t* ownerAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1845     OicSecRsrc_t* wildcardRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t)); // TODO IOT-2192
1846     if (NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1847     {
1848         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1849         goto error;
1850     }
1851     LL_APPEND(ownerAcl->aces, ownerAce);
1852     LL_APPEND(ownerAce->resources, wildcardRsrc);
1853
1854     //Set resource owner as PT
1855     memcpy(ownerAcl->rownerID.id, owner->id, sizeof(owner->id));
1856
1857     //PT has full permission.
1858     ownerAce->permission = PERMISSION_FULL_CONTROL;
1859
1860     //Set subject as PT's UUID
1861     ownerAce->subjectType = OicSecAceUuidSubject;
1862     memcpy(ownerAce->subjectuuid.id, owner->id, sizeof(owner->id));
1863
1864     wildcardRsrc->href = OICStrdup(WILDCARD_RESOURCE_URI);
1865     if (NULL == wildcardRsrc->href)
1866     {
1867         goto error;
1868     }
1869
1870     wildcardRsrc->interfaceLen = 1;
1871     wildcardRsrc->interfaces = (char**)OICMalloc(wildcardRsrc->interfaceLen * sizeof(char*));
1872     if (NULL == wildcardRsrc->interfaces)
1873     {
1874         goto error;
1875     }
1876     wildcardRsrc->interfaces[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1877     if (NULL == wildcardRsrc->interfaces[0])
1878     {
1879         goto error;
1880     }
1881
1882     wildcardRsrc->typeLen = 1;
1883     wildcardRsrc->types = (char**)OICMalloc(wildcardRsrc->typeLen * sizeof(char*));
1884     if (NULL == wildcardRsrc->types)
1885     {
1886         goto error;
1887     }
1888     wildcardRsrc->types[0] = OICStrdup(WILDCARD_RESOURCE_URI);
1889     if (NULL == wildcardRsrc->types[0])
1890     {
1891         goto error;
1892     }
1893
1894     return ownerAcl;
1895
1896 error:
1897     //in case of memory allocation failed, each resource should be removed individually.
1898     if (NULL == ownerAcl || NULL == ownerAce || NULL == wildcardRsrc)
1899     {
1900         OICFree(ownerAcl);
1901         OICFree(ownerAce);
1902         OICFree(wildcardRsrc);
1903     }
1904     else
1905     {
1906         DeleteACLList(ownerAcl);
1907     }
1908     return NULL;
1909 }
1910
1911 /**
1912  * Function to update the owner ACL to new device.
1913  *
1914  * @param[in]  otmCtx  Context value of ownership transfer.
1915  * @param[in]  aclVer  ACL version.
1916  * @return  OC_STACK_OK on success
1917  */
1918 static OCStackResult PostOwnerAcl(OTMContext_t* otmCtx, OicSecAclVersion_t aclVer)
1919 {
1920     OCStackResult res = OC_STACK_ERROR;
1921     OCHeaderOption *options = NULL;
1922     uint8_t numOptions = 0;
1923
1924     OIC_LOG(DEBUG, TAG, "IN PostOwnerAcl");
1925
1926     if (!otmCtx || !otmCtx->selectedDeviceInfo)
1927     {
1928         OIC_LOG(ERROR, TAG, "Invalid parameters");
1929         return OC_STACK_INVALID_PARAM;
1930     }
1931     const char * aclUri = (OIC_SEC_ACL_V2 == aclVer ? OIC_RSRC_ACL2_URI : OIC_RSRC_ACL_URI);
1932     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1933     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1934     OicSecAcl_t* ownerAcl = NULL;
1935     assert(deviceInfo->connType & CT_FLAG_SECURE);
1936
1937     if (!PMGenerateQuery(true,
1938                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
1939                         deviceInfo->connType,
1940                         query, sizeof(query), aclUri))
1941     {
1942         OIC_LOG(ERROR, TAG, "Failed to generate query");
1943         return OC_STACK_ERROR;
1944     }
1945     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1946
1947     OicUuid_t ownerID;
1948     res = GetDoxmDeviceID(&ownerID);
1949     if (OC_STACK_OK != res)
1950     {
1951         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1952         return res;
1953     }
1954
1955     //Generate owner ACL for new device
1956     ownerAcl = GenerateOwnerAcl(&ownerID);
1957     if (NULL == ownerAcl)
1958     {
1959         OIC_LOG(ERROR, TAG, "Failed to generate owner ACL");
1960         return OC_STACK_NO_MEMORY;
1961     }
1962
1963     //Generate ACL payload
1964     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1965     if (NULL == secPayload)
1966     {
1967         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1968         res = OC_STACK_NO_MEMORY;
1969         goto exit;
1970     }
1971
1972     res = AclToCBORPayload(ownerAcl, aclVer, &secPayload->securityData, &secPayload->payloadSize);
1973     if (OC_STACK_OK != res)
1974     {
1975         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
1976         goto exit;
1977     }
1978     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1979
1980     OIC_LOG(DEBUG, TAG, "Owner ACL Payload:");
1981     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1982
1983     if (IS_OIC(deviceInfo->specVer))
1984     {
1985         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
1986         if (NULL == options)
1987         {
1988             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1989             res = OC_STACK_NO_MEMORY;
1990             goto exit;
1991         }
1992
1993         SetCBORFormat(options, &numOptions);
1994         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
1995     }
1996
1997     //Send owner ACL to new device : POST /oic/sec/cred [ owner credential ]
1998     OCCallbackData cbData;
1999     cbData.cb = &OwnerAclHandler;
2000     cbData.context = (void *)otmCtx;
2001     cbData.cd = NULL;
2002     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
2003                                      &deviceInfo->endpoint, (OCPayload*)secPayload,
2004                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2005     secPayload = NULL;
2006     if (OC_STACK_OK != res)
2007     {
2008         OIC_LOG(ERROR, TAG, "OCStack resource error");
2009     }
2010
2011     OIC_LOG(DEBUG, TAG, "OUT PostOwnerAcl");
2012
2013 exit:
2014     OICFree(options);
2015     OCPayloadDestroy((OCPayload *)secPayload);
2016     DeleteACLList(ownerAcl);
2017
2018     return res;
2019 }
2020
2021 static OCStackResult PostOwnerTransferModeToResource(OTMContext_t* otmCtx)
2022 {
2023     OIC_LOG(DEBUG, TAG, "IN PostOwnerTransferModeToResource");
2024     OCStackResult res = OC_STACK_ERROR;
2025     OCHeaderOption *options = NULL;
2026     uint8_t numOptions = 0;
2027
2028     if (!otmCtx || !otmCtx->selectedDeviceInfo)
2029     {
2030         OIC_LOG(ERROR, TAG, "Invalid parameters");
2031         return OC_STACK_INVALID_PARAM;
2032     }
2033
2034     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2035     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2036
2037     if (!PMGenerateQuery(false,
2038                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
2039                         deviceInfo->connType,
2040                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2041     {
2042         OIC_LOG(ERROR, TAG, "PostOwnerTransferModeToResource : Failed to generate query");
2043         return OC_STACK_ERROR;
2044     }
2045     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2046
2047     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
2048     if (NULL == secPayload)
2049     {
2050         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2051         return OC_STACK_NO_MEMORY;
2052     }
2053
2054     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2055     res = otmCtx->otmCallback.createSelectOxmPayloadCB(otmCtx,
2056             &secPayload->securityData, &secPayload->payloadSize);
2057     if (OC_STACK_OK != res && NULL == secPayload->securityData)
2058     {
2059         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
2060         res = OC_STACK_ERROR;
2061         goto exit;
2062     }
2063
2064     if (IS_OIC(deviceInfo->specVer))
2065     {
2066         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2067         if (NULL == options)
2068         {
2069             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2070             res = OC_STACK_NO_MEMORY;
2071             goto exit;
2072         }
2073
2074         SetCBORFormat(options, &numOptions);
2075         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2076     }
2077
2078     OCCallbackData cbData;
2079     cbData.cb = &OwnerTransferModeHandler;
2080     cbData.context = (void *)otmCtx;
2081     cbData.cd = NULL;
2082     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query,
2083                        &deviceInfo->endpoint, (OCPayload *)secPayload,
2084                        deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2085     secPayload = NULL;
2086     if (res != OC_STACK_OK)
2087     {
2088         OIC_LOG(ERROR, TAG, "OCStack resource error");
2089     }
2090
2091 exit:
2092     OICFree(options);
2093     OCPayloadDestroy((OCPayload *)secPayload);
2094     OIC_LOG(DEBUG, TAG, "OUT PostOwnerTransferModeToResource");
2095
2096     return res;
2097 }
2098
2099 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
2100 {
2101     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
2102
2103     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2104     {
2105         OIC_LOG(ERROR, TAG, "Invailed parameters");
2106         return OC_STACK_INVALID_PARAM;
2107     }
2108
2109     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2110     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2111     assert(deviceInfo->connType & CT_FLAG_SECURE);
2112
2113     if(!PMGenerateQuery(true,
2114                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2115                         deviceInfo->connType,
2116                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2117     {
2118         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
2119         return OC_STACK_ERROR;
2120     }
2121     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2122
2123     OCHeaderOption *options = NULL;
2124     uint8_t numOptions = 0;
2125
2126     if (IS_OIC(deviceInfo->specVer))
2127     {
2128         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2129         VERIFY_NOT_NULL_RETURN(TAG, options, ERROR, OC_STACK_NO_MEMORY);
2130         SetCBORFormat(options, &numOptions);
2131         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2132     }
2133
2134
2135     OCCallbackData cbData;
2136     cbData.cb = &ListMethodsHandler;
2137     cbData.context = (void *)otmCtx;
2138     cbData.cd = NULL;
2139     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
2140                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2141     OICFree(options);
2142     if (res != OC_STACK_OK)
2143     {
2144         OIC_LOG(ERROR, TAG, "OCStack resource error");
2145     }
2146
2147     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
2148
2149     return res;
2150 }
2151
2152 static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
2153 {
2154     OIC_LOG(DEBUG, TAG, "IN PostOwnerUuid");
2155     OCStackResult res = OC_STACK_ERROR;
2156     OCHeaderOption *options = NULL;
2157     uint8_t numOptions = 0;
2158
2159     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2160     {
2161         OIC_LOG(ERROR, TAG, "Invailed parameters");
2162         return OC_STACK_INVALID_PARAM;
2163     }
2164
2165     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2166     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2167     assert(deviceInfo->connType & CT_FLAG_SECURE);
2168
2169     if(!PMGenerateQuery(true,
2170                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2171                         deviceInfo->connType,
2172                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2173     {
2174         OIC_LOG(ERROR, TAG, "PostOwnerUuid : Failed to generate query");
2175         return OC_STACK_ERROR;
2176     }
2177     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2178
2179     //Post PT's uuid to new device
2180     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
2181     if (NULL == secPayload)
2182     {
2183         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2184         return OC_STACK_NO_MEMORY;
2185     }
2186     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2187     res = otmCtx->otmCallback.createOwnerTransferPayloadCB(
2188             otmCtx, &secPayload->securityData, &secPayload->payloadSize);
2189     if (OC_STACK_OK != res && NULL == secPayload->securityData)
2190     {
2191         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
2192         res = OC_STACK_INVALID_PARAM;
2193         goto exit;
2194     }
2195     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2196
2197     if (IS_OIC(deviceInfo->specVer))
2198     {
2199         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2200         if (NULL == options)
2201         {
2202             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2203             res = OC_STACK_NO_MEMORY;
2204             goto exit;
2205         }
2206
2207         SetCBORFormat(options, &numOptions);
2208         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2209     }
2210
2211     OCCallbackData cbData;
2212     cbData.cb = &OwnerUuidUpdateHandler;
2213     cbData.context = (void *)otmCtx;
2214     cbData.cd = NULL;
2215
2216     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
2217             deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2218     secPayload = NULL;
2219     if (OC_STACK_OK != res)
2220     {
2221         OIC_LOG(ERROR, TAG, "OCStack resource error");
2222     }
2223
2224 exit:
2225     OICFree(options);
2226     OCPayloadDestroy((OCPayload *)secPayload);
2227
2228     OIC_LOG(DEBUG, TAG, "OUT PostOwnerUuid");
2229
2230     return res;
2231 }
2232
2233 static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
2234 {
2235     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2236     OCStackResult res = OC_STACK_ERROR;
2237
2238     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2239     {
2240         OIC_LOG(ERROR, TAG, "Invalid parameters");
2241         return OC_STACK_INVALID_PARAM;
2242     }
2243
2244     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2245     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2246     assert(deviceInfo->connType & CT_FLAG_SECURE);
2247
2248     if(!PMGenerateQuery(true,
2249                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2250                         deviceInfo->connType,
2251                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2252     {
2253         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2254         return OC_STACK_ERROR;
2255     }
2256     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2257
2258     //OwnershipInformationHandler
2259     OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
2260     if (NULL == secPayload)
2261     {
2262         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2263         return OC_STACK_NO_MEMORY;
2264     }
2265
2266     otmCtx->selectedDeviceInfo->doxm->owned = true;
2267
2268     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2269     OCHeaderOption *options = NULL;
2270     uint8_t numOptions = 0;
2271     bool propertiesToInclude[DOXM_PROPERTY_COUNT];
2272     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
2273     propertiesToInclude[DOXM_OWNED] = true;
2274     //include rowner uuid
2275     propertiesToInclude[DOXM_ROWNERUUID] = true;
2276     //doxm.rowneruuid set to the provisioningclient's /doxm.deviceuuid.
2277     if (OC_STACK_OK != GetDoxmDeviceID(&otmCtx->selectedDeviceInfo->doxm->rownerID))
2278     {
2279         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2280         res = OC_STACK_ERROR;
2281         goto exit;
2282     }
2283
2284     if (IS_OIC(deviceInfo->specVer))
2285     {
2286         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2287         if (NULL == options)
2288         {
2289             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2290             res = OC_STACK_NO_MEMORY;
2291             goto exit;
2292         }
2293
2294         SetCBORFormat(options, &numOptions);
2295
2296         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2297     }
2298
2299     res = DoxmToCBORPayloadPartial(otmCtx->selectedDeviceInfo->doxm,
2300             &secPayload->securityData, &secPayload->payloadSize,
2301             propertiesToInclude);
2302     if (OC_STACK_OK != res && NULL == secPayload->securityData)
2303     {
2304         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
2305         res = OC_STACK_INVALID_PARAM;
2306         goto exit;
2307     }
2308
2309     OCCallbackData cbData;
2310     cbData.cb = &OwnershipInformationHandler;
2311     cbData.context = (void *)otmCtx;
2312     cbData.cd = NULL;
2313
2314     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2315                        deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2316     secPayload = NULL;
2317     if (res != OC_STACK_OK)
2318     {
2319         OIC_LOG(ERROR, TAG, "OCStack resource error");
2320     }
2321
2322 exit:
2323     OICFree(options);
2324     OCPayloadDestroy((OCPayload *)secPayload);
2325     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2326
2327     return res;
2328 }
2329
2330 static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
2331 {
2332     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2333     OCStackResult res = OC_STACK_ERROR;
2334
2335     if (!otmCtx || !otmCtx->selectedDeviceInfo)
2336     {
2337         return OC_STACK_INVALID_PARAM;
2338     }
2339
2340     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2341     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2342     assert(deviceInfo->connType & CT_FLAG_SECURE);
2343
2344     if (!PMGenerateQuery(true,
2345                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2346                         deviceInfo->connType,
2347                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2348     {
2349         OIC_LOG_V(ERROR, TAG, "%s Failed to generate query", __func__);
2350         return OC_STACK_ERROR;
2351     }
2352     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2353
2354     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
2355     if (NULL == secPayload)
2356     {
2357         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2358         return OC_STACK_NO_MEMORY;
2359     }
2360
2361     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2362     OCHeaderOption *options = NULL;
2363     uint8_t numOptions = 0;
2364     bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
2365     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
2366     propertiesToInclude[PSTAT_OM] = true;
2367
2368     if (IS_OIC(deviceInfo->specVer))
2369     {
2370         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2371         if (NULL == options)
2372         {
2373             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2374             res = OC_STACK_NO_MEMORY;
2375             goto exit;
2376         }
2377
2378         SetCBORFormat(options, &numOptions);
2379         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2380         propertiesToInclude[PSTAT_TM] = true;
2381     }
2382
2383     res = PstatToCBORPayloadPartial(deviceInfo->pstat, &secPayload->securityData,
2384                                            &secPayload->payloadSize, propertiesToInclude, false);
2385
2386     if (OC_STACK_OK != res)
2387     {
2388         OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
2389         res = OC_STACK_INVALID_PARAM;
2390         goto exit;
2391     }
2392
2393     OCCallbackData cbData;
2394     cbData.cb = &OperationModeUpdateHandler;
2395     cbData.context = (void *)otmCtx;
2396     cbData.cd = NULL;
2397     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload *)secPayload,
2398                        deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2399     secPayload = NULL;
2400     if (res != OC_STACK_OK)
2401     {
2402         OIC_LOG(ERROR, TAG, "OCStack resource error");
2403     }
2404
2405 exit:
2406     OICFree(options);
2407     OCPayloadDestroy((OCPayload *)secPayload);
2408     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2409
2410     return res;
2411 }
2412
2413 static OCStackResult GetAndVerifyDoxmResource(OTMContext_t* otmCtx)
2414 {
2415     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2416
2417     if(!otmCtx || !otmCtx->selectedDeviceInfo || !otmCtx->selectedDeviceInfo->doxm)
2418     {
2419         OIC_LOG(ERROR, TAG, "Invalid context");
2420         return OC_STACK_INVALID_PARAM;
2421     }
2422
2423     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2424     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2425     assert(deviceInfo->connType & CT_FLAG_SECURE);
2426
2427     if(!PMGenerateQuery(true,
2428                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2429                         deviceInfo->connType,
2430                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2431     {
2432         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2433         return OC_STACK_ERROR;
2434     }
2435     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2436
2437     OCHeaderOption *options = NULL;
2438     uint8_t numOptions = 0;
2439
2440     if (IS_OIC(deviceInfo->specVer))
2441     {
2442         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2443         VERIFY_NOT_NULL_RETURN(TAG, options, ERROR, OC_STACK_NO_MEMORY);
2444         SetCBORFormat(options, &numOptions);
2445         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2446     }
2447
2448     OCCallbackData cbData;
2449     cbData.cb = &GetAndVerifyDoxmHandler;
2450     cbData.context = (void *)otmCtx;
2451     cbData.cd = NULL;
2452     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
2453                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2454     OICFree(options);
2455     if (res != OC_STACK_OK)
2456     {
2457         OIC_LOG(ERROR, TAG, "OCStack resource error");
2458     }
2459
2460     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2461
2462     return res;
2463 }
2464
2465 static OCStackResult GetRealUuid(OTMContext_t* otmCtx)
2466 {
2467     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2468
2469     if(!otmCtx || !otmCtx->selectedDeviceInfo || !otmCtx->selectedDeviceInfo->doxm)
2470     {
2471         OIC_LOG(ERROR, TAG, "Invalid context");
2472         return OC_STACK_INVALID_PARAM;
2473     }
2474
2475     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2476     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2477     assert(deviceInfo->connType & CT_FLAG_SECURE);
2478
2479     if(!PMGenerateQuery(true,
2480                         deviceInfo->endpoint.addr, getSecurePort(deviceInfo),
2481                         deviceInfo->connType,
2482                         query, sizeof(query), OIC_RSRC_DOXM_URI))
2483     {
2484         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2485         return OC_STACK_ERROR;
2486     }
2487     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2488
2489     OCHeaderOption *options = NULL;
2490     uint8_t numOptions = 0;
2491
2492     if (IS_OIC(deviceInfo->specVer))
2493     {
2494         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2495         VERIFY_NOT_NULL_RETURN(TAG, options, ERROR, OC_STACK_NO_MEMORY);
2496         SetCBORFormat(options, &numOptions);
2497         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2498     }
2499
2500     OCCallbackData cbData;
2501     cbData.cb = &DeviceUuidUpdateHandler;
2502     cbData.context = (void *)otmCtx;
2503     cbData.cd = NULL;
2504     OCStackResult res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_GET, query, NULL, NULL,
2505                                      deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2506     OICFree(options);
2507     if (res != OC_STACK_OK)
2508     {
2509         OIC_LOG(ERROR, TAG, "OCStack resource error");
2510     }
2511
2512     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2513
2514     return res;
2515 }
2516
2517 static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice)
2518 {
2519     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2520
2521     char* strUuid = NULL;
2522     OCStackResult res = OC_STACK_INVALID_PARAM;
2523
2524     VERIFY_NOT_NULL(TAG, selectedDevice, ERROR);
2525     VERIFY_NOT_NULL(TAG, selectedDevice->doxm, ERROR);
2526
2527     PdmDeviceState_t pdmState = PDM_DEVICE_UNKNOWN;
2528     res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState);
2529     if (OC_STACK_OK != res)
2530     {
2531         OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res);
2532         return res;
2533     }
2534
2535     bool removeCredReq = false;
2536     res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
2537     if (OC_STACK_OK != res)
2538     {
2539         OIC_LOG(WARNING, TAG, "Failed to covert uuid to string");
2540         return res;
2541     }
2542
2543     if (PDM_DEVICE_UNKNOWN == pdmState && !selectedDevice->doxm->owned)
2544     {
2545         removeCredReq = true;
2546     }
2547     else if (PDM_DEVICE_ACTIVE == pdmState && !selectedDevice->doxm->owned)
2548     {
2549         OIC_LOG_V(WARNING, TAG, "Unowned device[%s] dectected from PDM.", strUuid);
2550         OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", strUuid);
2551         res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
2552         if(OC_STACK_OK != res)
2553         {
2554             OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", strUuid);
2555             goto exit;
2556         }
2557
2558         removeCredReq = true;
2559     }
2560
2561     if (removeCredReq)
2562     {
2563         OIC_LOG_V(WARNING, TAG, "[%s]'s credential will be removed.", strUuid);
2564         res = RemoveCredential(&selectedDevice->doxm->deviceID);
2565         if (OC_STACK_RESOURCE_DELETED != res)
2566         {
2567             OIC_LOG_V(WARNING, TAG, "Can not find [%s]'s credential.", strUuid);
2568         }
2569     }
2570
2571     //Checking duplication of Device ID.
2572     bool isDuplicate = true;
2573     res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
2574     if (OC_STACK_OK != res)
2575     {
2576         OIC_LOG_V(ERROR, TAG, "Internal error in PDMIsDuplicateDevice : %d", res);
2577         goto exit;
2578     }
2579
2580     if (isDuplicate)
2581     {
2582         if (PDM_DEVICE_STALE == pdmState)
2583         {
2584             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
2585                                "device status will revert back to initial status.");
2586             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
2587             if (OC_STACK_OK != res)
2588             {
2589                 OIC_LOG_V(ERROR, TAG, "Internal error in PDMSetDeviceState : %d", res);
2590                 goto exit;
2591             }
2592         }
2593         else if (PDM_DEVICE_INIT == pdmState)
2594         {
2595             OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
2596             res = OC_STACK_DUPLICATE_REQUEST;
2597             goto exit;
2598         }
2599         else
2600         {
2601             OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
2602             res = OC_STACK_ERROR;
2603             goto exit;
2604         }
2605     }
2606     else
2607     {
2608         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
2609         if (OC_STACK_OK != res)
2610         {
2611             OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res);
2612             goto exit;
2613         }
2614     }
2615
2616 exit:
2617     OICFree(strUuid);
2618     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2619     return res;
2620 }
2621
2622 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
2623 {
2624     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
2625     OCStackResult res = OC_STACK_INVALID_PARAM;
2626
2627     VERIFY_NOT_NULL(TAG, selectedDevice, ERROR);
2628     VERIFY_NOT_NULL(TAG, selectedDevice->doxm, ERROR);
2629
2630     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
2631     otmCtx->selectedDeviceInfo = selectedDevice;
2632
2633     //Select the OxM to performing ownership transfer
2634     res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
2635                                           selectedDevice->doxm->oxmLen,
2636                                           &selectedDevice->doxm->oxmSel,
2637                                           SUPER_OWNER);
2638     if(OC_STACK_OK != res)
2639     {
2640         OIC_LOG_V(ERROR, TAG, "Failed to select the provisioning method : %d", res);
2641         SetResult(otmCtx, res);
2642         return res;
2643     }
2644     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
2645
2646     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
2647     if(OC_STACK_OK != res)
2648     {
2649         OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
2650         return res;
2651     }
2652
2653 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2654     //Register TLS event handler, to catch the TLS handshake event
2655     if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeCB))
2656     {
2657         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register TLS handshake callback.");
2658     }
2659 #endif // __WITH_DTLS__ or __WITH_TLS__
2660
2661     //Send Req: POST /oic/sec/doxm [{..."OxmSel" :g_OTMCbDatas[Index of Selected OxM].OXMString,...}]
2662     res = PostOwnerTransferModeToResource(otmCtx);
2663     if(OC_STACK_OK != res)
2664     {
2665         OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
2666         SetResult(otmCtx, res);
2667         return res;
2668     }
2669
2670     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
2671
2672 exit:
2673     return res;
2674 }
2675
2676 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
2677 {
2678     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
2679
2680     if(!data)
2681     {
2682         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
2683         return OC_STACK_INVALID_PARAM;
2684     }
2685     if(oxmType >= OIC_OXM_COUNT)
2686     {
2687         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
2688         return OC_STACK_INVALID_PARAM;
2689     }
2690
2691     // TODO: Remove this API, Please see the jira ticket IOT-1484
2692
2693     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
2694
2695     return OC_STACK_OK;
2696 }
2697
2698 /**
2699  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
2700  */
2701 OCStackResult OTMDoOwnershipTransfer(void* ctx,
2702                                      OCProvisionDev_t *selectedDevicelist,
2703                                      OCProvisionResultCB resultCallback)
2704 {
2705     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
2706
2707     if (NULL == selectedDevicelist)
2708     {
2709         return OC_STACK_INVALID_PARAM;
2710     }
2711     if (NULL == resultCallback)
2712     {
2713         return OC_STACK_INVALID_CALLBACK;
2714     }
2715
2716     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
2717     if(!otmCtx)
2718     {
2719         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
2720         return OC_STACK_NO_MEMORY;
2721     }
2722
2723     otmCtx->ctxResultCallback = resultCallback;
2724     otmCtx->ctxHasError = false;
2725     otmCtx->userCtx = ctx;
2726     OCProvisionDev_t* pCurDev = selectedDevicelist;
2727
2728     //Counting number of selected devices.
2729     otmCtx->ctxResultArraySize = 0;
2730     while(NULL != pCurDev)
2731     {
2732         otmCtx->ctxResultArraySize++;
2733         pCurDev = pCurDev->next;
2734     }
2735
2736     otmCtx->ctxResultArray =
2737         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
2738     if(NULL == otmCtx->ctxResultArray)
2739     {
2740         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
2741         OICFree(otmCtx);
2742         return OC_STACK_NO_MEMORY;
2743     }
2744     pCurDev = selectedDevicelist;
2745
2746     //Fill the device UUID for result array.
2747     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
2748     {
2749         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
2750                pCurDev->doxm->deviceID.id,
2751                UUID_LENGTH);
2752         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
2753         pCurDev = pCurDev->next;
2754     }
2755
2756     SetDosState(DOS_RFPRO);
2757     OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist);
2758
2759     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
2760
2761     return res;
2762 }
2763
2764 OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
2765 {
2766     OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
2767               __func__, oxm, (allowStatus ? "true" : "false"));
2768
2769 #ifdef MULTIPLE_OWNER
2770     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
2771 #else
2772     if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
2773 #endif
2774     {
2775         return OC_STACK_INVALID_PARAM;
2776     }
2777
2778     OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
2779     if(OXM_IDX_COUNT <= oxmIdx)
2780     {
2781         OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
2782         return OC_STACK_ERROR;
2783     }
2784     g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
2785
2786     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2787
2788     return OC_STACK_OK;
2789 }
2790
2791 OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
2792 {
2793     OIC_LOG_V(INFO, TAG, "IN %s", __func__);
2794     OCStackResult res = OC_STACK_ERROR;
2795
2796     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2797     {
2798         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2799         return OC_STACK_INVALID_PARAM;
2800     }
2801
2802     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2803     // Change the TAKE_OWNER bit of TM to 0 (optional in Client Directed)
2804     otmCtx->selectedDeviceInfo->pstat->tm &= (~TAKE_OWNER);
2805
2806     // Change the dos.s value to RFPRO
2807     otmCtx->selectedDeviceInfo->pstat->dos.state = DOS_RFPRO;
2808
2809     // TODO [IOT-2052] set the rowneruuid for /pstat directly, so the hack
2810     // in pstatresource.c which sets all rowneruuids can be removed.
2811
2812     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2813     if (NULL == secPayload)
2814     {
2815         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2816         return OC_STACK_NO_MEMORY;
2817     }
2818     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2819
2820     // Note [IOT-2052] all the POST payloads in the provisioningclient app
2821     // should be updated to use the Partial payload APIs for the SVRs, so they
2822     // do not include read-only Properties for the Server device current
2823     // state.
2824     OCHeaderOption *options = NULL;
2825     uint8_t numOptions = 0;
2826     bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
2827     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
2828     propertiesToInclude[PSTAT_DOS] = true;
2829     propertiesToInclude[PSTAT_TM] = true;
2830
2831     if (DOS_RFOTM != otmCtx->selectedDeviceInfo->pstat->dos.state)
2832     {
2833         propertiesToInclude[PSTAT_ROWNERUUID] = false;
2834     }
2835     else
2836     {
2837         propertiesToInclude[PSTAT_ROWNERUUID] = true;
2838     }
2839     //pstat.rowneruuid set to the provisioningclient's /doxm.deviceuuid.
2840     if (OC_STACK_OK != GetDoxmDeviceID(&deviceInfo->pstat->rownerID))
2841     {
2842         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2843         res = OC_STACK_ERROR;
2844         goto exit;
2845     }
2846
2847     if (IS_OIC(deviceInfo->specVer))
2848     {
2849         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2850         if (NULL == options)
2851         {
2852             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2853             res = OC_STACK_NO_MEMORY;
2854             goto exit;
2855         }
2856
2857         SetCBORFormat(options, &numOptions);
2858         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2859         propertiesToInclude[PSTAT_ISOP] = true;
2860         propertiesToInclude[PSTAT_CM] = true;
2861         propertiesToInclude[PSTAT_OM] = true;
2862     }
2863     if (OC_STACK_OK != PstatToCBORPayloadPartial(otmCtx->selectedDeviceInfo->pstat,
2864             &secPayload->securityData, &secPayload->payloadSize, propertiesToInclude, false))
2865     {
2866         res = OC_STACK_INVALID_JSON;
2867         goto exit;
2868     }
2869     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2870     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2871
2872     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2873     assert(otmCtx->selectedDeviceInfo->connType & CT_FLAG_SECURE);
2874
2875     if(!PMGenerateQuery(true,
2876                         otmCtx->selectedDeviceInfo->endpoint.addr,
2877                         getSecurePort(otmCtx->selectedDeviceInfo),
2878                         otmCtx->selectedDeviceInfo->connType,
2879                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2880     {
2881         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
2882         res = OC_STACK_ERROR;
2883         goto exit;
2884     }
2885     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2886
2887     OCCallbackData cbData;
2888     memset(&cbData, 0, sizeof(cbData));
2889     cbData.cb = &ProvisioningStatusHandler;
2890     cbData.context = (void*)otmCtx;
2891     cbData.cd = NULL;
2892     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2893             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2894     secPayload = NULL;
2895     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",res);
2896     if (res != OC_STACK_OK)
2897     {
2898         OIC_LOG(ERROR, TAG, "OCStack resource error");
2899     }
2900
2901 exit:
2902     OICFree(options);
2903     OCPayloadDestroy((OCPayload *)secPayload);
2904     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
2905
2906     return res;
2907 }
2908
2909 OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
2910 {
2911     OIC_LOG(INFO, TAG, "IN PostNormalOperationStatus");
2912     OCStackResult res = OC_STACK_ERROR;
2913
2914     if(!otmCtx || !otmCtx->selectedDeviceInfo)
2915     {
2916         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
2917         return OC_STACK_INVALID_PARAM;
2918     }
2919
2920     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
2921     otmCtx->selectedDeviceInfo->pstat->dos.state = DOS_RFNOP;
2922
2923     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
2924     if (NULL == secPayload)
2925     {
2926         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2927         return OC_STACK_NO_MEMORY;
2928     }
2929     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
2930     OCHeaderOption *options = NULL;
2931     uint8_t numOptions = 0;
2932
2933     bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
2934     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
2935
2936     if (IS_OIC(deviceInfo->specVer))
2937     {
2938         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
2939         if (NULL == options)
2940         {
2941             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
2942             res = OC_STACK_NO_MEMORY;
2943             goto exit;
2944         }
2945         SetCBORFormat(options, &numOptions);
2946         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
2947         //Set isop to true.
2948         deviceInfo->pstat->isOp = true;
2949         deviceInfo->pstat->cm = NORMAL;
2950
2951         propertiesToInclude[PSTAT_ISOP] = true;
2952         propertiesToInclude[PSTAT_CM] = true;
2953         propertiesToInclude[PSTAT_TM] = true;
2954         propertiesToInclude[PSTAT_OM] = true;
2955     }
2956     else
2957     {
2958         propertiesToInclude[PSTAT_DOS] = true;
2959     }
2960     res = PstatToCBORPayloadPartial(otmCtx->selectedDeviceInfo->pstat,
2961             &secPayload->securityData, &secPayload->payloadSize, propertiesToInclude, false);
2962
2963     if (OC_STACK_OK != res)
2964     {
2965         res = OC_STACK_INVALID_JSON;
2966         goto exit;
2967     }
2968     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
2969     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
2970
2971     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
2972     assert(otmCtx->selectedDeviceInfo->connType & CT_FLAG_SECURE);
2973
2974     if(!PMGenerateQuery(true,
2975                         otmCtx->selectedDeviceInfo->endpoint.addr,
2976                         getSecurePort(otmCtx->selectedDeviceInfo),
2977                         otmCtx->selectedDeviceInfo->connType,
2978                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
2979     {
2980         OIC_LOG(ERROR, TAG, "PostNormalOperationStatus : Failed to generate query");
2981         res = OC_STACK_ERROR;
2982         goto exit;
2983     }
2984     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
2985
2986     OCCallbackData cbData;
2987     memset(&cbData, 0, sizeof(cbData));
2988     cbData.cb = &ReadyForNomalStatusHandler;
2989     cbData.context = (void*)otmCtx;
2990     cbData.cd = NULL;
2991     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
2992             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
2993     secPayload = NULL;
2994     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",res);
2995     if (res != OC_STACK_OK)
2996     {
2997         OIC_LOG(ERROR, TAG, "OCStack resource error");
2998     }
2999
3000 exit:
3001     OICFree(options);
3002     OCPayloadDestroy((OCPayload *)secPayload);
3003     OIC_LOG(INFO, TAG, "OUT PostNormalOperationStatus");
3004
3005     return res;
3006 }
3007
3008 OCStackResult ConfigSelfOwnership(void)
3009 {
3010     OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership");
3011
3012     bool isDeviceOwned = true;
3013     if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned))
3014     {
3015         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state");
3016         return OC_STACK_ERROR;
3017     }
3018
3019     bool isop = false;
3020     if (OC_STACK_OK != GetPstatIsop(&isop))
3021     {
3022         OIC_LOG(ERROR, TAG, "Failed to get pstat.isop.");
3023         return OC_STACK_ERROR;
3024     }
3025     if (isDeviceOwned || isop)
3026     {
3027         OIC_LOG_V(ERROR, TAG, "%s: The state of device is not Ready for Ownership transfer: %s", __func__, isDeviceOwned ? "isDeviceOwned" : "isop");
3028         return OC_STACK_ERROR;
3029     }
3030
3031     OicUuid_t deviceID = {.id={0}};
3032     if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
3033     {
3034         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
3035         return OC_STACK_ERROR;
3036     }
3037
3038     OCStackResult ret = OC_STACK_OK;
3039     //Update the pstat resource as Normal Operation.
3040     ret = SetPstatSelfOwnership(&deviceID);
3041     if(OC_STACK_OK != ret)
3042     {
3043         OIC_LOG (ERROR, TAG, "Unable to update pstat resource as Normal Operation");
3044         goto exit;
3045     }
3046     //Update the doxm resource as Normal Operation.
3047     ret = SetDoxmSelfOwnership(&deviceID);
3048     if(OC_STACK_OK != ret)
3049     {
3050         OIC_LOG (ERROR, TAG, "Unable to update doxm resource as Normal Operation");
3051         goto exit;
3052     }
3053     //Update default ACE of security resource to prevent anonymous user access.
3054     ret = UpdateDefaultSecProvACE();
3055     if(OC_STACK_OK != ret)
3056     {
3057         OIC_LOG (ERROR, TAG, "Unable to update default ace in ConfigSelfOwnership");
3058         goto exit;
3059     }
3060     //Update the acl resource owner as owner device.
3061     ret = SetAclRownerId(&deviceID);
3062     if(OC_STACK_OK != ret)
3063     {
3064         OIC_LOG (ERROR, TAG, "Unable to update acl resource in ConfigSelfOwnership");
3065         goto exit;
3066     }
3067     //Update the cred resource owner as owner device.
3068     ret = SetCredRownerId(&deviceID);
3069     if(OC_STACK_OK != ret)
3070     {
3071         // Cred resouce may be empty in Ready for Ownership transfer state.
3072         if (OC_STACK_NO_RESOURCE == ret)
3073         {
3074             OIC_LOG (INFO, TAG, "Cred resource is empty");
3075             ret = OC_STACK_OK;
3076             goto exit;
3077         }
3078         OIC_LOG (ERROR, TAG, "Unable to update cred resource in ConfigSelfOwnership");
3079     }
3080
3081 exit:
3082     if(OC_STACK_OK != ret)
3083     {
3084         /*
3085          * If some error is occured while configure self-ownership,
3086          * ownership related resource should be revert back to initial status.
3087         */
3088         ResetSecureResourceInPS();
3089     }
3090
3091     return ret;
3092 }
3093
3094 /**
3095  * Response handler of set rowner uuid.
3096  *
3097  * @param[in] ctx             ctx value passed to callback from calling function.
3098  * @param[in] UNUSED          handle to an invocation
3099  * @param[in] clientResponse  Response from queries to remote servers.
3100  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
3101  *          and OC_STACK_KEEP_TRANSACTION to keep it.
3102  */
3103 static OCStackApplicationResult RownerUuidHandler(void *ctx, OCDoHandle handle,
3104                                                        OCClientResponse *clientResponse)
3105 {
3106     OIC_LOG_V(INFO, TAG, "%s IN", __func__);
3107
3108     VERIFY_NOT_NULL(TAG, clientResponse, ERROR);
3109     VERIFY_NOT_NULL(TAG, ctx, ERROR);
3110
3111     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
3112     OC_UNUSED(handle);
3113
3114     OIC_LOG_V(INFO, TAG, "%s response got: %d", __func__, clientResponse->result);
3115
3116     if(OC_STACK_RESOURCE_CHANGED < clientResponse->result)
3117     {
3118         //Remove the current OTM Context from OTM queue
3119         RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
3120                          getSecurePort(otmCtx->selectedDeviceInfo));
3121
3122         //If there is a request being performed, cancel it to prevent retransmission.
3123         if(otmCtx->ocDoHandle)
3124         {
3125             OIC_LOG_V(DEBUG, TAG, "OCCancel - %s : %d",
3126                     otmCtx->selectedDeviceInfo->endpoint.addr,
3127                     getSecurePort(otmCtx->selectedDeviceInfo));
3128             if(OC_STACK_OK != OCCancel(otmCtx->ocDoHandle, OC_HIGH_QOS, NULL, 0))
3129             {
3130                 OIC_LOG(WARNING, TAG, "Failed to remove registered callback");
3131             }
3132             else
3133             {
3134                 otmCtx->ocDoHandle = NULL;
3135             }
3136         }
3137     }
3138     else
3139     {
3140         if(OC_STACK_OK != PostProvisioningStatus(otmCtx))
3141         {
3142             OIC_LOG(ERROR, TAG, "Failed to update pstat");
3143             SetResult(otmCtx, OC_STACK_ERROR);
3144         }
3145     }
3146 exit:
3147     OIC_LOG_V(INFO, TAG, "%s OUT", __func__);
3148     return OC_STACK_DELETE_TRANSACTION;
3149 }
3150
3151 OCStackResult PostRownerUuid(OTMContext_t* otmCtx)
3152 {
3153     OIC_LOG_V(INFO, TAG, "%s IN", __func__);
3154     OCStackResult res = OC_STACK_ERROR;
3155     OCHeaderOption *options = NULL;
3156     uint8_t numOptions = 0;
3157
3158     if (!otmCtx || !otmCtx->selectedDeviceInfo)
3159     {
3160         OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !otmCtx ? "OTMContext" : "selectedDeviceInfo" );
3161         return OC_STACK_INVALID_PARAM;
3162     }
3163
3164     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
3165     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
3166     if (NULL == secPayload)
3167     {
3168         OIC_LOG_V(ERROR, TAG, "%s: Failed to memory allocation", __func__);
3169         return OC_STACK_NO_MEMORY;
3170     }
3171     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
3172
3173     bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
3174     memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
3175
3176     if (DOS_RFOTM != otmCtx->selectedDeviceInfo->pstat->dos.state)
3177     {
3178         propertiesToInclude[PSTAT_ROWNERUUID] = false;
3179     }
3180     else
3181     {
3182         propertiesToInclude[PSTAT_ROWNERUUID] = true;
3183     }
3184     //pstat.rowneruuid set to the provisioningclient's /doxm.deviceuuid.
3185     if (OC_STACK_OK != GetDoxmDeviceID(&deviceInfo->pstat->rownerID))
3186     {
3187         OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
3188         res = OC_STACK_ERROR;
3189         goto exit;
3190     }
3191
3192     if (OC_STACK_OK != PstatToCBORPayloadPartial(deviceInfo->pstat,
3193             &secPayload->securityData, &secPayload->payloadSize, propertiesToInclude, false))
3194     {
3195         res = OC_STACK_INVALID_JSON;
3196         goto exit;
3197     }
3198     OIC_LOG(DEBUG, TAG, "Created payload for set rowner uuid");
3199     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
3200
3201     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
3202     assert(deviceInfo->connType & CT_FLAG_SECURE);
3203
3204     if (!PMGenerateQuery(true,
3205                         deviceInfo->endpoint.addr,
3206                         getSecurePort(deviceInfo),
3207                         deviceInfo->connType,
3208                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
3209     {
3210         OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
3211         res = OC_STACK_ERROR;
3212         goto exit;
3213     }
3214     OIC_LOG_V(DEBUG, TAG, "%s: Query=%s", __func__, query);
3215
3216     if (IS_OIC(deviceInfo->specVer))
3217     {
3218         options = (OCHeaderOption*) OICCalloc(1, sizeof(OCHeaderOption));
3219         if (NULL == options)
3220         {
3221             OIC_LOG(ERROR, TAG, "Failed to memory allocation");
3222             res = OC_STACK_NO_MEMORY;
3223             goto exit;
3224         }
3225
3226         SetCBORFormat(options, &numOptions);
3227         OIC_LOG_V(WARNING, TAG, "%s: oic version detected", __func__);
3228     }
3229
3230     OCCallbackData cbData;
3231     memset(&cbData, 0, sizeof(cbData));
3232     cbData.cb = &RownerUuidHandler;
3233     cbData.context = (void*)otmCtx;
3234     cbData.cd = NULL;
3235     res = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
3236             deviceInfo->connType, OC_HIGH_QOS, &cbData, options, numOptions);
3237     secPayload = NULL;
3238     OIC_LOG_V(INFO, TAG, "%s: OCDoResource returned: %d", __func__, res);
3239     if (res != OC_STACK_OK)
3240     {
3241         OIC_LOG(ERROR, TAG, "OCStack resource error");
3242     }
3243
3244 exit:
3245     OICFree(options);
3246     OCPayloadDestroy((OCPayload *)secPayload);
3247     OIC_LOG_V(INFO, TAG, "%s OUT", __func__);
3248
3249     return res;
3250 }