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