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