Imported Upstream version 1.1.0
[platform/upstream/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 <time.h>
34 #include <unistd.h>
35 #include <sys/time.h>
36 #include <stdbool.h>
37 #include <string.h>
38
39 #include "logger.h"
40 #include "oic_malloc.h"
41 #include "oic_string.h"
42 #include "cacommon.h"
43 #include "cainterface.h"
44 #include "base64.h"
45 #include "cJSON.h"
46 #include "global.h"
47
48 #include "srmresourcestrings.h"
49 #include "doxmresource.h"
50 #include "pstatresource.h"
51 #include "credresource.h"
52 #include "aclresource.h"
53 #include "ownershiptransfermanager.h"
54 #include "securevirtualresourcetypes.h"
55 #include "oxmjustworks.h"
56 #include "pmtypes.h"
57 #include "pmutility.h"
58 #include "srmutility.h"
59 #include "provisioningdatabasemanager.h"
60 #include "oxmrandompin.h"
61 #include "ocpayload.h"
62 #include "payload_logging.h"
63
64 #define TAG "OTM"
65
66 /**
67  * Array to store the callbacks for each owner transfer method.
68  */
69 static OTMCallbackData_t g_OTMDatas[OIC_OXM_COUNT];
70
71 /**
72  * Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
73  */
74 static OTMContext_t* g_otmCtx = NULL;
75
76 /**
77  * Function to select appropriate  provisioning method.
78  *
79  * @param[in] supportedMethods   Array of supported methods
80  * @param[in] numberOfMethods   number of supported methods
81  * @param[out]  selectedMethod         Selected methods
82  * @return  OC_STACK_OK on success
83  */
84 static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
85         size_t numberOfMethods, OicSecOxm_t *selectedMethod)
86 {
87     OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
88
89     if(numberOfMethods == 0 || !supportedMethods)
90     {
91         OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
92         return OC_STACK_ERROR;
93     }
94
95     *selectedMethod  = supportedMethods[0];
96     for(size_t i = 0; i < numberOfMethods; i++)
97     {
98         if(*selectedMethod < supportedMethods[i])
99         {
100             *selectedMethod =  supportedMethods[i];
101         }
102     }
103
104     return OC_STACK_OK;
105 }
106
107 /**
108  * Function to select operation mode.This function will return most secure common operation mode.
109  *
110  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
111  * @param[out]   selectedMode   selected operation mode
112  * @return  OC_STACK_OK on success
113  */
114 static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
115                                 OicSecDpom_t *selectedMode)
116 {
117     OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
118     *selectedMode = selectedDeviceInfo->pstat->sm[0];
119     OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
120 }
121
122 /**
123  * Function to start ownership transfer.
124  * This function will send the first request for provisioning,
125  * The next request message is sent from the response handler for this request.
126  *
127  * @param[in] ctx   context value passed to callback from calling function.
128  * @param[in] selectedDevice   selected device information to performing provisioning.
129  * @return  OC_STACK_OK on success
130  */
131 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
132
133 /**
134  * Function to update owner transfer mode
135  *
136  * @param[in]  otmCtx  Context value of ownership transfer.
137  * @return  OC_STACK_OK on success
138  */
139 static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx);
140
141 /**
142  * Function to send request to resource to get its pstat resource information.
143  *
144  * @param[in]  otmCtx  Context value of ownership transfer.
145  * @return  OC_STACK_OK on success
146  */
147 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx);
148
149
150 /**
151  * Function to send  uuid of owner device to new device.
152  * This function would update 'owner of doxm' as UUID for provisioning tool.
153  *
154  * @param[in]  otmCtx  Context value of ownership transfer.
155  * @return  OC_STACK_OK on success
156  */
157 static OCStackResult PutOwnerUuid(OTMContext_t* otmCtx);
158
159 /**
160  * Function to update the operation mode. As per the spec. Operation mode in client driven
161  * single service provisioning it will be updated to 0x3
162  *
163  * @param[in]  otmCtx  Context value of ownership transfer.
164  * @return  OC_STACK_OK on success
165  */
166 static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx);
167
168 /**
169  * Function to update the owner credential to new device
170  *
171  * @param[in]  otmCtx  Context value of ownership transfer.
172  * @param[in] selectedOperationMode selected operation mode
173  * @return  OC_STACK_OK on success
174  */
175 static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx);
176
177 /**
178  * Function to send ownerShip info.
179  * This function would update 'owned of doxm' as true.
180  *
181  * @param[in]  otmCtx  Context value of ownership transfer.
182  * @return  OC_STACK_OK on success
183  */
184 static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx);
185
186 /**
187  * Function to update pstat as Ready for provisioning.
188  * This function would update 'cm' from bx0000,0010 to bx0000,0000.
189  *
190  * @param[in] ctx   context value passed to callback from calling function.
191  * @param[in] selectedDevice   selected device information to performing provisioning.
192  * @return  OC_STACK_OK on success
193  */
194 static OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx);
195
196 /**
197  * Function to update pstat as Ready for Normal Operation.
198  * This function would update 'isop' from false to true.
199  *
200  * @param[in] ctx   context value passed to callback from calling function.
201  * @param[in] selectedDevice   selected device information to performing provisioning.
202  * @return  OC_STACK_OK on success
203  */
204 static OCStackResult PutNormalOperationStatus(OTMContext_t* otmCtx);
205
206 static bool IsComplete(OTMContext_t* otmCtx)
207 {
208     for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
209     {
210         if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
211         {
212             return false;
213         }
214     }
215
216     return true;
217 }
218
219 /**
220  * Function to save the result of provisioning.
221  *
222  * @param[in,out] otmCtx   Context value of ownership transfer.
223  * @param[in] res   result of provisioning
224  */
225 static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
226 {
227     OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
228
229     if(!otmCtx)
230     {
231         OIC_LOG(WARNING, TAG, "OTMContext is NULL");
232         return;
233     }
234
235     if(otmCtx->selectedDeviceInfo)
236     {
237         //Revert psk_info callback and new deivce uuid in case of random PIN OxM
238         if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
239         {
240             if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
241             {
242                 OIC_LOG(WARNING, TAG, "Failed to revert  is DTLS credential handler.");
243             }
244             OicUuid_t emptyUuid = { .id={0}};
245             SetUuidForRandomPinOxm(&emptyUuid);
246         }
247
248         for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
249         {
250             if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id,
251                       otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
252             {
253                 otmCtx->ctxResultArray[i].res = res;
254                 if(OC_STACK_OK != res)
255                 {
256                     otmCtx->ctxHasError = true;
257                 }
258             }
259         }
260
261         g_otmCtx = NULL;
262
263         //If all request is completed, invoke the user callback.
264         if(IsComplete(otmCtx))
265         {
266             otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
267                                        otmCtx->ctxResultArray, otmCtx->ctxHasError);
268             OICFree(otmCtx->ctxResultArray);
269             OICFree(otmCtx);
270         }
271         else
272         {
273             if(OC_STACK_OK != StartOwnershipTransfer(otmCtx,
274                                                      otmCtx->selectedDeviceInfo->next))
275             {
276                 OIC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer");
277             }
278         }
279     }
280
281     OIC_LOG(DEBUG, TAG, "OUT SetResult");
282 }
283
284 /**
285  * Function to handle the handshake result in OTM.
286  * This function will be invoked after DTLS handshake
287  * @param   endPoint  [IN] The remote endpoint.
288  * @param   errorInfo [IN] Error information from the endpoint.
289  * @return  NONE
290  */
291 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
292 {
293     if(NULL != g_otmCtx && NULL != g_otmCtx->selectedDeviceInfo &&
294        NULL != endpoint && NULL != info)
295     {
296         OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
297                  endpoint->addr, endpoint->port, info->result);
298
299         OicSecDoxm_t* newDevDoxm = g_otmCtx->selectedDeviceInfo->doxm;
300
301         if(NULL != newDevDoxm)
302         {
303             OicUuid_t emptyUuid = {.id={0}};
304
305             //Make sure the address matches.
306             if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr,
307                endpoint->addr,
308                sizeof(endpoint->addr)) == 0 &&
309                g_otmCtx->selectedDeviceInfo->securePort == endpoint->port)
310             {
311                 OCStackResult res = OC_STACK_ERROR;
312
313                 //If temporal secure sesstion established successfully
314                 if(CA_STATUS_OK == info->result &&
315                    false == newDevDoxm->owned &&
316                    memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0)
317                 {
318                     //Send request : PUT /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
319                     res = PutOwnerUuid(g_otmCtx);
320                     if(OC_STACK_OK != res)
321                     {
322                         OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
323                         SetResult(g_otmCtx, res);
324                     }
325                 }
326                 //In case of authentication failure
327                 else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
328                 {
329                     //in case of error from owner credential
330                     if(memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0 &&
331                         true == newDevDoxm->owned)
332                     {
333                         OIC_LOG(ERROR, TAG, "The owner credential may incorrect.");
334
335                         if(OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID)))
336                         {
337                             OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
338                         }
339                         SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
340                     }
341                     //in case of error from wrong PIN, re-start the ownership transfer
342                     else if(OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel)
343                     {
344                         OIC_LOG(ERROR, TAG, "The PIN number may incorrect.");
345
346                         memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
347                         newDevDoxm->owned = false;
348                         g_otmCtx->attemptCnt++;
349
350                         if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt)
351                         {
352                             res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo);
353                             if(OC_STACK_OK != res)
354                             {
355                                 SetResult(g_otmCtx, res);
356                                 OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
357                             }
358                         }
359                         else
360                         {
361                             OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
362                             SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
363                         }
364                     }
365                     else
366                     {
367                         OIC_LOG(ERROR, TAG, "Failed to establish secure session.");
368                         SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
369                     }
370                 }
371             }
372         }
373     }
374 }
375
376 /**
377  * Function to save ownerPSK at provisioning tool end.
378  *
379  * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
380  * @return  OC_STACK_OK on success
381  */
382 static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
383 {
384     OIC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");
385
386     OCStackResult res = OC_STACK_ERROR;
387
388     CAEndpoint_t endpoint;
389     memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
390     OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
391     endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
392     endpoint.port = selectedDeviceInfo->securePort;
393
394     OicUuid_t ptDeviceID = {.id={0}};
395     if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
396     {
397         OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
398         return res;
399     }
400
401     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
402     OicSecKey_t ownerKey = {ownerPSK, OWNER_PSK_LENGTH_128};
403
404     //Generating OwnerPSK
405     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
406             (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
407             strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
408             ptDeviceID.id, sizeof(ptDeviceID.id),
409             selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
410             ownerPSK, OWNER_PSK_LENGTH_128);
411
412     if (CA_STATUS_OK == pskRet)
413     {
414         OIC_LOG(INFO, TAG,"ownerPSK dump:\n");
415         OIC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
416         //Generating new credential for provisioning tool
417         OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
418                 SYMMETRIC_PAIR_WISE_KEY, NULL,
419                 &ownerKey, &ptDeviceID);
420         VERIFY_NON_NULL(TAG, cred, ERROR);
421
422         res = AddCredential(cred);
423         if(res != OC_STACK_OK)
424         {
425             DeleteCredList(cred);
426             return res;
427         }
428     }
429     else
430     {
431         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
432     }
433
434     OIC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
435 exit:
436     return res;
437 }
438
439 /**
440  * Callback handler for OwnerShipTransferModeHandler API.
441  *
442  * @param[in] ctx             ctx value passed to callback from calling function.
443  * @param[in] UNUSED          handle to an invocation
444  * @param[in] clientResponse  Response from queries to remote servers.
445  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
446  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
447  */
448 static OCStackApplicationResult OwnerTransferModeHandler(void *ctx, OCDoHandle UNUSED,
449                                                          OCClientResponse *clientResponse)
450 {
451     OIC_LOG(DEBUG, TAG, "IN OwnerTransferModeHandler");
452
453     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
454     VERIFY_NON_NULL(TAG, ctx, WARNING);
455
456     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
457     (void)UNUSED;
458     if(clientResponse->result == OC_STACK_OK)
459     {
460         OIC_LOG(INFO, TAG, "OwnerTransferModeHandler : response result = OC_STACK_OK");
461         //Send request : GET /oic/sec/pstat
462         OCStackResult res = GetProvisioningStatusResource(otmCtx);
463         if(OC_STACK_OK != res)
464         {
465             OIC_LOG(WARNING, TAG, "Failed to get pstat information");
466             SetResult(otmCtx, res);
467         }
468     }
469     else
470     {
471         OIC_LOG_V(WARNING, TAG, "OwnerTransferModeHandler : Client response is incorrect : %d",
472         clientResponse->result);
473         SetResult(otmCtx, clientResponse->result);
474     }
475
476     OIC_LOG(DEBUG, TAG, "OUT OwnerTransferModeHandler");
477
478 exit:
479     return  OC_STACK_DELETE_TRANSACTION;
480 }
481
482 /**
483  * Callback handler for ProvisioningStatusResouceHandler API.
484  *
485  * @param[in] ctx             ctx value passed to callback from calling function.
486  * @param[in] UNUSED          handle to an invocation
487  * @param[in] clientResponse  Response from queries to remote servers.
488  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
489  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
490  */
491 static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
492                                                     OCClientResponse *clientResponse)
493 {
494     OIC_LOG(DEBUG, TAG, "IN ListMethodsHandler");
495
496     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
497     VERIFY_NON_NULL(TAG, ctx, WARNING);
498
499     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
500     (void)UNUSED;
501     if  (OC_STACK_OK == clientResponse->result)
502     {
503         if  (NULL == clientResponse->payload)
504         {
505             OIC_LOG(INFO, TAG, "Skiping Null payload");
506             SetResult(otmCtx, OC_STACK_ERROR);
507             return OC_STACK_DELETE_TRANSACTION;
508         }
509
510         if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
511         {
512             OIC_LOG(INFO, TAG, "Unknown payload type");
513             SetResult(otmCtx, OC_STACK_ERROR);
514             return OC_STACK_DELETE_TRANSACTION;
515         }
516         OicSecPstat_t* pstat = NULL;
517         OCStackResult result = CBORPayloadToPstat(
518                 ((OCSecurityPayload*)clientResponse->payload)->securityData,
519                 ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
520                 &pstat);
521         if(NULL == pstat || result != OC_STACK_OK)
522         {
523             OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
524             SetResult(otmCtx, OC_STACK_ERROR);
525             return OC_STACK_DELETE_TRANSACTION;
526         }
527         if(false == (TAKE_OWNER & pstat->cm))
528         {
529             OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
530             SetResult(otmCtx, OC_STACK_ERROR);
531             return OC_STACK_DELETE_TRANSACTION;
532         }
533         otmCtx->selectedDeviceInfo->pstat = pstat;
534
535         //Select operation mode (Currently supported SINGLE_SERVICE_CLIENT_DRIVEN only)
536         SelectOperationMode(otmCtx->selectedDeviceInfo, &(otmCtx->selectedDeviceInfo->pstat->om));
537
538         //Send request : PUT /oic/sec/pstat [{"om":"bx11", .. }]
539         OCStackResult res = PutUpdateOperationMode(otmCtx);
540         if (OC_STACK_OK != res)
541         {
542             OIC_LOG(ERROR, TAG, "Error while updating operation mode.");
543             SetResult(otmCtx, res);
544         }
545     }
546     else
547     {
548         OIC_LOG_V(WARNING, TAG, "ListMethodsHandler : Client response is incorrect : %d",
549             clientResponse->result);
550         SetResult(otmCtx, clientResponse->result);
551     }
552
553     OIC_LOG(DEBUG, TAG, "OUT ListMethodsHandler");
554 exit:
555     return  OC_STACK_DELETE_TRANSACTION;
556 }
557
558 /**
559  * Response handler for update owner uuid request.
560  *
561  * @param[in] ctx             ctx value passed to callback from calling function.
562  * @param[in] UNUSED          handle to an invocation
563  * @param[in] clientResponse  Response from queries to remote servers.
564  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
565  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
566  */
567 static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNUSED,
568                                 OCClientResponse *clientResponse)
569 {
570     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
571     VERIFY_NON_NULL(TAG, ctx, WARNING);
572
573     OIC_LOG(DEBUG, TAG, "IN OwnerUuidUpdateHandler");
574     (void)UNUSED;
575     OCStackResult res = OC_STACK_OK;
576     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
577
578     if(OC_STACK_OK == clientResponse->result)
579     {
580         if(otmCtx && otmCtx->selectedDeviceInfo)
581         {
582             res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
583             if(OC_STACK_OK != res)
584             {
585                 OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to owner PSK generation");
586                 SetResult(otmCtx, res);
587                 return OC_STACK_DELETE_TRANSACTION;
588             }
589
590             //PUT owner credential to new device according to security spec B.
591             res = PutOwnerCredential(otmCtx);
592             if(OC_STACK_OK != res)
593             {
594                 OIC_LOG(ERROR, TAG,
595                         "OwnerUuidUpdateHandler:Failed to send PUT request for onwer credential");
596                 SetResult(otmCtx, res);
597                 return OC_STACK_DELETE_TRANSACTION;
598             }
599         }
600     }
601     else
602     {
603         res = clientResponse->result;
604         OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
605         SetResult(otmCtx, res);
606     }
607
608     OIC_LOG(DEBUG, TAG, "OUT OwnerUuidUpdateHandler");
609
610 exit:
611     return  OC_STACK_DELETE_TRANSACTION;
612 }
613
614 /**
615  * Response handler for update operation mode.
616  *
617  * @param[in] ctx             ctx value passed to callback from calling function.
618  * @param[in] UNUSED          handle to an invocation
619  * @param[in] clientResponse  Response from queries to remote servers.
620  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
621  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
622  */
623 static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle UNUSED,
624                                 OCClientResponse *clientResponse)
625 {
626     OIC_LOG(DEBUG, TAG, "IN OperationModeUpdateHandler");
627
628     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
629     VERIFY_NON_NULL(TAG, ctx, WARNING);
630
631     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
632     (void) UNUSED;
633     if  (OC_STACK_OK == clientResponse->result)
634     {
635         OCStackResult res = OC_STACK_ERROR;
636         OicSecOxm_t selOxm = otmCtx->selectedDeviceInfo->doxm->oxmSel;
637         //DTLS Handshake
638         //Load secret for temporal secure session.
639         if(g_OTMDatas[selOxm].loadSecretCB)
640         {
641             res = g_OTMDatas[selOxm].loadSecretCB(otmCtx);
642             if(OC_STACK_OK != res)
643             {
644                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
645                 SetResult(otmCtx, res);
646                 return  OC_STACK_DELETE_TRANSACTION;
647             }
648         }
649
650         //It will be used in handshake event handler
651         g_otmCtx = otmCtx;
652
653         //Try DTLS handshake to generate secure session
654         if(g_OTMDatas[selOxm].createSecureSessionCB)
655         {
656             res = g_OTMDatas[selOxm].createSecureSessionCB(otmCtx);
657             if(OC_STACK_OK != res)
658             {
659                 OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
660                 SetResult(otmCtx, res);
661                 return OC_STACK_DELETE_TRANSACTION;
662             }
663         }
664     }
665     else
666     {
667         OIC_LOG(ERROR, TAG, "Error while update operation mode");
668         SetResult(otmCtx, clientResponse->result);
669     }
670
671     OIC_LOG(DEBUG, TAG, "OUT OperationModeUpdateHandler");
672
673 exit:
674     return  OC_STACK_DELETE_TRANSACTION;
675 }
676
677 /**
678  * Response handler for update owner crendetial request.
679  *
680  * @param[in] ctx             ctx value passed to callback from calling function.
681  * @param[in] UNUSED          handle to an invocation
682  * @param[in] clientResponse  Response from queries to remote servers.
683  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
684  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
685  */
686 static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
687                                 OCClientResponse *clientResponse)
688 {
689     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
690     VERIFY_NON_NULL(TAG, ctx, WARNING);
691
692     OIC_LOG(DEBUG, TAG, "IN OwnerCredentialHandler");
693     (void)UNUSED;
694     OCStackResult res = OC_STACK_OK;
695     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
696
697     if(OC_STACK_RESOURCE_CREATED == clientResponse->result)
698     {
699         if(otmCtx && otmCtx->selectedDeviceInfo)
700         {
701             //Close the temporal secure session to verify the owner credential
702             CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
703             endpoint->port = otmCtx->selectedDeviceInfo->securePort;
704             CAResult_t caResult = CACloseDtlsSession(endpoint);
705             if(CA_STATUS_OK != caResult)
706             {
707                 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
708                 SetResult(otmCtx, caResult);
709                 return OC_STACK_DELETE_TRANSACTION;
710             }
711
712             /**
713              * If we select NULL cipher,
714              * client will select appropriate cipher suite according to server's cipher-suite list.
715              */
716             caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL);
717             if(CA_STATUS_OK != caResult)
718             {
719                 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
720                 SetResult(otmCtx, caResult);
721                 return OC_STACK_DELETE_TRANSACTION;
722             }
723
724             /**
725              * in case of random PIN based OxM,
726              * revert get_psk_info callback of tinyDTLS to use owner credential.
727              */
728             if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
729             {
730                 OicUuid_t emptyUuid = { .id={0}};
731                 SetUuidForRandomPinOxm(&emptyUuid);
732
733                 if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
734                 {
735                     OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
736                     SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
737                     return OC_STACK_DELETE_TRANSACTION;
738                 }
739             }
740
741             //PUT /oic/sec/doxm [{ ..., "owned":"TRUE" }]
742             res = PutOwnershipInformation(otmCtx);
743             if(OC_STACK_OK != res)
744             {
745                 OIC_LOG(ERROR, TAG, "Failed to put ownership information to new device");
746                 SetResult(otmCtx, res);
747                 return OC_STACK_DELETE_TRANSACTION;
748             }
749         }
750     }
751     else
752     {
753         res = clientResponse->result;
754         OIC_LOG_V(ERROR, TAG, "OwnerCredentialHandler : Unexpected result %d", res);
755         SetResult(otmCtx, res);
756     }
757
758     OIC_LOG(DEBUG, TAG, "OUT OwnerCredentialHandler");
759
760 exit:
761     return  OC_STACK_DELETE_TRANSACTION;
762 }
763
764
765 /**
766  * Response handler for update owner information request.
767  *
768  * @param[in] ctx             ctx value passed to callback from calling function.
769  * @param[in] UNUSED          handle to an invocation
770  * @param[in] clientResponse  Response from queries to remote servers.
771  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
772  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
773  */
774 static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandle UNUSED,
775                                 OCClientResponse *clientResponse)
776 {
777     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
778     VERIFY_NON_NULL(TAG, ctx, WARNING);
779
780     OIC_LOG(DEBUG, TAG, "IN OwnershipInformationHandler");
781     (void)UNUSED;
782     OCStackResult res = OC_STACK_OK;
783     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
784
785     if(OC_STACK_OK == clientResponse->result)
786     {
787         if(otmCtx && otmCtx->selectedDeviceInfo)
788         {
789             OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
790             OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
791
792             res = PutProvisioningStatus(otmCtx);
793             if(OC_STACK_OK != res)
794             {
795                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
796                 SetResult(otmCtx, res);
797             }
798         }
799     }
800     else
801     {
802         res = clientResponse->result;
803         OIC_LOG_V(ERROR, TAG, "OwnershipInformationHandler : Unexpected result %d", res);
804         SetResult(otmCtx, res);
805     }
806
807     OIC_LOG(DEBUG, TAG, "OUT OwnershipInformationHandler");
808
809 exit:
810     return  OC_STACK_DELETE_TRANSACTION;
811 }
812
813 /**
814  * Response handler of update provisioning status.
815  *
816  * @param[in] ctx             ctx value passed to callback from calling function.
817  * @param[in] UNUSED          handle to an invocation
818  * @param[in] clientResponse  Response from queries to remote servers.
819  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
820  *          and OC_STACK_KEEP_TRANSACTION to keep it.
821  */
822 static OCStackApplicationResult ProvisioningStatusHandler(void *ctx, OCDoHandle UNUSED,
823                                                        OCClientResponse *clientResponse)
824 {
825     OIC_LOG_V(INFO, TAG, "IN ProvisioningStatusHandler.");
826
827     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
828     VERIFY_NON_NULL(TAG, ctx, ERROR);
829
830     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
831     (void)UNUSED;
832     OCStackResult res = OC_STACK_OK;
833
834     if(OC_STACK_OK == clientResponse->result)
835     {
836         if(otmCtx && otmCtx->selectedDeviceInfo)
837         {
838             OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
839
840             res = PutNormalOperationStatus(otmCtx);
841             if(OC_STACK_OK != res)
842             {
843                 OIC_LOG(ERROR, TAG, "Failed to update pstat");
844                 SetResult(otmCtx, res);
845             }
846         }
847     }
848     else
849     {
850         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
851                             clientResponse->result);
852         SetResult(otmCtx, clientResponse->result);
853     }
854
855 exit:
856     OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
857     return OC_STACK_DELETE_TRANSACTION;
858 }
859
860 /**
861  * Response handler of update provisioning status to Ready for Normal..
862  *
863  * @param[in] ctx             ctx value passed to callback from calling function.
864  * @param[in] UNUSED          handle to an invocation
865  * @param[in] clientResponse  Response from queries to remote servers.
866  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
867  *          and OC_STACK_KEEP_TRANSACTION to keep it.
868  */
869 static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
870                                                        OCClientResponse *clientResponse)
871 {
872     OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
873
874     VERIFY_NON_NULL(TAG, clientResponse, ERROR);
875     VERIFY_NON_NULL(TAG, ctx, ERROR);
876
877     OTMContext_t* otmCtx = (OTMContext_t*) ctx;
878     (void)UNUSED;
879
880     if (OC_STACK_OK == clientResponse->result)
881     {
882         OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
883         OCStackResult res = PDMAddDevice(&otmCtx->selectedDeviceInfo->doxm->deviceID);
884          if (OC_STACK_OK == res)
885          {
886                 OIC_LOG_V(INFO, TAG, "Add device's UUID in PDM_DB");
887                 SetResult(otmCtx, OC_STACK_OK);
888                 return OC_STACK_DELETE_TRANSACTION;
889          }
890           else
891          {
892               OIC_LOG(ERROR, TAG, "Ownership transfer is complete but adding information to DB is failed.");
893          }
894     }
895     else
896     {
897         OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
898                             clientResponse->result);
899         SetResult(otmCtx, clientResponse->result);
900     }
901
902 exit:
903     OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
904     return OC_STACK_DELETE_TRANSACTION;
905 }
906
907 static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx)
908 {
909     OIC_LOG(DEBUG, TAG, "IN PutOwnerCredential");
910
911     if(!otmCtx || !otmCtx->selectedDeviceInfo)
912     {
913         OIC_LOG(ERROR, TAG, "Invalid parameters");
914         return OC_STACK_INVALID_PARAM;
915     }
916
917     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
918     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
919
920     if(!PMGenerateQuery(true,
921                         deviceInfo->endpoint.addr, deviceInfo->securePort,
922                         deviceInfo->connType,
923                         query, sizeof(query), OIC_RSRC_CRED_URI))
924     {
925         OIC_LOG(ERROR, TAG, "PutOwnerCredential : Failed to generate query");
926         return OC_STACK_ERROR;
927     }
928     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
929     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
930     if(!secPayload)
931     {
932         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
933         return OC_STACK_NO_MEMORY;
934     }
935
936     //Generate owner credential for new device
937     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
938     const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
939     if(!ownerCredential)
940     {
941         OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
942         return OC_STACK_NO_RESOURCE;
943     }
944
945     OicUuid_t credSubjectId = {.id={0}};
946     if(OC_STACK_OK == GetDoxmDeviceID(&credSubjectId))
947     {
948         OicSecCred_t newCredential;
949         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
950         newCredential.next = NULL;
951
952         //Set subject ID as PT's ID
953         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
954
955         //Fill private data as empty string
956         newCredential.privateData.data = NULL;
957         newCredential.privateData.len = 0;
958 #ifdef __WITH_X509__
959         newCredential.publicData.data = NULL;
960         newCredential.publicData.len = 0;
961 #endif
962
963         //Send owner credential to new device : PUT /oic/sec/cred [ owner credential ]
964         if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData, &secPayload->payloadSize))
965         {
966             OICFree(secPayload);
967             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
968             return OC_STACK_ERROR;
969         }
970         OIC_LOG(DEBUG, TAG, "Cred Payload:");
971         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
972
973         OCCallbackData cbData;
974         cbData.cb = &OwnerCredentialHandler;
975         cbData.context = (void *)otmCtx;
976         cbData.cd = NULL;
977         OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query,
978                                          &deviceInfo->endpoint, (OCPayload*)secPayload,
979                                          deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
980         if (res != OC_STACK_OK)
981         {
982             OIC_LOG(ERROR, TAG, "OCStack resource error");
983         }
984     }
985     else
986     {
987         OIC_LOG(ERROR, TAG, "Failed to read DOXM device ID.");
988         return OC_STACK_NO_RESOURCE;
989     }
990
991     OIC_LOG(DEBUG, TAG, "OUT PutOwnerCredential");
992
993     return OC_STACK_OK;
994 }
995
996 static OCStackResult PutOwnerTransferModeToResource(OTMContext_t* otmCtx)
997 {
998     OIC_LOG(DEBUG, TAG, "IN PutOwnerTransferModeToResource");
999
1000     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1001     {
1002         OIC_LOG(ERROR, TAG, "Invalid parameters");
1003         return OC_STACK_INVALID_PARAM;
1004     }
1005
1006     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1007     OicSecOxm_t selectedOxm = deviceInfo->doxm->oxmSel;
1008     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1009
1010     if(!PMGenerateQuery(false,
1011                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1012                         deviceInfo->connType,
1013                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1014     {
1015         OIC_LOG(ERROR, TAG, "PutOwnerTransferModeToResource : Failed to generate query");
1016         return OC_STACK_ERROR;
1017     }
1018     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1019     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1020     if(!secPayload)
1021     {
1022         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1023         return OC_STACK_NO_MEMORY;
1024     }
1025     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1026     OCStackResult res = g_OTMDatas[selectedOxm].createSelectOxmPayloadCB(otmCtx,
1027             &secPayload->securityData, &secPayload->payloadSize);
1028     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1029     {
1030         OCPayloadDestroy((OCPayload *)secPayload);
1031         OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
1032         return OC_STACK_ERROR;
1033     }
1034
1035     OCCallbackData cbData;
1036     cbData.cb = &OwnerTransferModeHandler;
1037     cbData.context = (void *)otmCtx;
1038     cbData.cd = NULL;
1039     res = OCDoResource(NULL, OC_REST_PUT, query,
1040                        &deviceInfo->endpoint, (OCPayload *)secPayload,
1041                        deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1042     if (res != OC_STACK_OK)
1043     {
1044         OIC_LOG(ERROR, TAG, "OCStack resource error");
1045     }
1046
1047     OIC_LOG(DEBUG, TAG, "OUT PutOwnerTransferModeToResource");
1048
1049     return res;
1050 }
1051
1052 static OCStackResult GetProvisioningStatusResource(OTMContext_t* otmCtx)
1053 {
1054     OIC_LOG(DEBUG, TAG, "IN GetProvisioningStatusResource");
1055
1056     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1057     {
1058         OIC_LOG(ERROR, TAG, "Invailed parameters");
1059         return OC_STACK_INVALID_PARAM;
1060     }
1061
1062     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1063     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1064     if(!PMGenerateQuery(false,
1065                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1066                         deviceInfo->connType,
1067                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1068     {
1069         OIC_LOG(ERROR, TAG, "GetProvisioningStatusResource : Failed to generate query");
1070         return OC_STACK_ERROR;
1071     }
1072     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1073
1074     OCCallbackData cbData;
1075     cbData.cb = &ListMethodsHandler;
1076     cbData.context = (void *)otmCtx;
1077     cbData.cd = NULL;
1078     OCStackResult res = OCDoResource(NULL, OC_REST_GET, query, NULL, NULL,
1079                                      deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1080     if (res != OC_STACK_OK)
1081     {
1082         OIC_LOG(ERROR, TAG, "OCStack resource error");
1083     }
1084
1085     OIC_LOG(DEBUG, TAG, "OUT GetProvisioningStatusResource");
1086
1087     return res;
1088 }
1089
1090 static OCStackResult PutOwnerUuid(OTMContext_t* otmCtx)
1091 {
1092     OIC_LOG(DEBUG, TAG, "IN PutOwnerUuid");
1093
1094     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1095     {
1096         OIC_LOG(ERROR, TAG, "Invailed parameters");
1097         return OC_STACK_INVALID_PARAM;
1098     }
1099
1100     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1101     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1102     if(!PMGenerateQuery(true,
1103                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1104                         deviceInfo->connType,
1105                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1106     {
1107         OIC_LOG(ERROR, TAG, "PutOwnershipInformation : Failed to generate query");
1108         return OC_STACK_ERROR;
1109     }
1110     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1111
1112     //PUT PT's uuid to new device
1113     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1114     if(!secPayload)
1115     {
1116         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1117         return OC_STACK_NO_MEMORY;
1118     }
1119     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1120     OCStackResult res =  g_OTMDatas[deviceInfo->doxm->oxmSel].createOwnerTransferPayloadCB(
1121             otmCtx, &secPayload->securityData, &secPayload->payloadSize);
1122     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1123     {
1124         OCPayloadDestroy((OCPayload *)secPayload);
1125         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
1126         return OC_STACK_INVALID_PARAM;
1127     }
1128     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1129
1130     OCCallbackData cbData;
1131     cbData.cb = &OwnerUuidUpdateHandler;
1132     cbData.context = (void *)otmCtx;
1133     cbData.cd = NULL;
1134
1135     res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload *)secPayload,
1136             deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1137     if (res != OC_STACK_OK)
1138     {
1139         OIC_LOG(ERROR, TAG, "OCStack resource error");
1140     }
1141
1142     OIC_LOG(DEBUG, TAG, "OUT PutOwnerUuid");
1143
1144     return res;
1145 }
1146
1147 static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx)
1148 {
1149     OIC_LOG(DEBUG, TAG, "IN PutOwnershipInformation");
1150
1151     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1152     {
1153         OIC_LOG(ERROR, TAG, "Invailed parameters");
1154         return OC_STACK_INVALID_PARAM;
1155     }
1156
1157     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1158     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1159     if(!PMGenerateQuery(true,
1160                         deviceInfo->endpoint.addr, deviceInfo->securePort,
1161                         deviceInfo->connType,
1162                         query, sizeof(query), OIC_RSRC_DOXM_URI))
1163     {
1164         OIC_LOG(ERROR, TAG, "PutOwnershipInformation : Failed to generate query");
1165         return OC_STACK_ERROR;
1166     }
1167     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1168
1169     //OwnershipInformationHandler
1170     OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1171     if (!secPayload)
1172     {
1173         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1174         return OC_STACK_NO_MEMORY;
1175     }
1176
1177     otmCtx->selectedDeviceInfo->doxm->owned = true;
1178
1179     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1180     OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
1181             &secPayload->securityData, &secPayload->payloadSize);
1182     if (OC_STACK_OK != res && NULL == secPayload->securityData)
1183     {
1184         OCPayloadDestroy((OCPayload *)secPayload);
1185         OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
1186         return OC_STACK_INVALID_PARAM;
1187     }
1188
1189     OCCallbackData cbData;
1190     cbData.cb = &OwnershipInformationHandler;
1191     cbData.context = (void *)otmCtx;
1192     cbData.cd = NULL;
1193
1194     res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1195                        deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1196     if (res != OC_STACK_OK)
1197     {
1198         OIC_LOG(ERROR, TAG, "OCStack resource error");
1199     }
1200
1201     OIC_LOG(DEBUG, TAG, "OUT PutOwnershipInformation");
1202
1203     return res;
1204 }
1205
1206 static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx)
1207 {
1208     OIC_LOG(DEBUG, TAG, "IN PutUpdateOperationMode");
1209
1210     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1211     {
1212         return OC_STACK_INVALID_PARAM;
1213     }
1214
1215     OCProvisionDev_t* deviceInfo = otmCtx->selectedDeviceInfo;
1216     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1217     if(!PMGenerateQuery(false,
1218                         deviceInfo->endpoint.addr, deviceInfo->endpoint.port,
1219                         deviceInfo->connType,
1220                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1221     {
1222         OIC_LOG(ERROR, TAG, "PutUpdateOperationMode : Failed to generate query");
1223         return OC_STACK_ERROR;
1224     }
1225     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1226
1227     OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1228     if(!secPayload)
1229     {
1230         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1231         return OC_STACK_NO_MEMORY;
1232     }
1233     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1234     OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
1235                                            &secPayload->payloadSize);
1236    if (OC_STACK_OK != res)
1237     {
1238         OCPayloadDestroy((OCPayload *)secPayload);
1239         OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
1240         return OC_STACK_INVALID_PARAM;
1241     }
1242
1243     OCCallbackData cbData;
1244     cbData.cb = &OperationModeUpdateHandler;
1245     cbData.context = (void *)otmCtx;
1246     cbData.cd = NULL;
1247     res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload *)secPayload,
1248                        deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
1249     if (res != OC_STACK_OK)
1250     {
1251         OIC_LOG(ERROR, TAG, "OCStack resource error");
1252     }
1253
1254     OIC_LOG(DEBUG, TAG, "OUT PutUpdateOperationMode");
1255
1256     return res;
1257 }
1258
1259 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
1260 {
1261     OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
1262     OTMContext_t* otmCtx = (OTMContext_t*)ctx;
1263     otmCtx->selectedDeviceInfo = selectedDevice;
1264
1265     //Set to the lowest level OxM, and then find more higher level OxM.
1266     OCStackResult res = SelectProvisioningMethod(selectedDevice->doxm->oxm,
1267                                                  selectedDevice->doxm->oxmLen,
1268                                                  &selectedDevice->doxm->oxmSel);
1269     if(OC_STACK_OK != res)
1270     {
1271         OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
1272         SetResult(otmCtx, res);
1273         return res;
1274     }
1275     OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
1276
1277     //Send Req: PUT /oic/sec/doxm [{..."OxmSel" :g_OTMDatas[Index of Selected OxM].OXMString,...}]
1278     res = PutOwnerTransferModeToResource(otmCtx);
1279     if(OC_STACK_OK != res)
1280     {
1281         OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
1282         SetResult(otmCtx, res);
1283         return res;
1284     }
1285
1286     //Register DTLS event handler to catch the dtls event while handshake
1287     if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DTLSHandshakeCB))
1288     {
1289         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register DTLS handshake callback.");
1290     }
1291
1292     OIC_LOG(INFO, TAG, "OUT StartOwnershipTransfer");
1293
1294     return res;
1295
1296 }
1297
1298 OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxmType, OTMCallbackData_t* data)
1299 {
1300     OIC_LOG(DEBUG, TAG, "IN OTMSetOwnerTransferCallbackData");
1301
1302     if(!data)
1303     {
1304         OIC_LOG(ERROR, TAG, "OTMSetOwnershipTransferCallbackData : Invalid parameters");
1305         return OC_STACK_INVALID_PARAM;
1306     }
1307     if(oxmType >= OIC_OXM_COUNT)
1308     {
1309         OIC_LOG(INFO, TAG, "Unknow ownership transfer method");
1310         return OC_STACK_INVALID_PARAM;
1311     }
1312
1313     g_OTMDatas[oxmType].loadSecretCB= data->loadSecretCB;
1314     g_OTMDatas[oxmType].createSecureSessionCB = data->createSecureSessionCB;
1315     g_OTMDatas[oxmType].createSelectOxmPayloadCB = data->createSelectOxmPayloadCB;
1316     g_OTMDatas[oxmType].createOwnerTransferPayloadCB = data->createOwnerTransferPayloadCB;
1317
1318     OIC_LOG(DEBUG, TAG, "OUT OTMSetOwnerTransferCallbackData");
1319
1320     return OC_STACK_OK;
1321 }
1322
1323 /**
1324  * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer
1325  */
1326 OCStackResult OTMDoOwnershipTransfer(void* ctx,
1327                                      OCProvisionDev_t *selectedDevicelist,
1328                                      OCProvisionResultCB resultCallback)
1329 {
1330     OIC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer");
1331
1332     if (NULL == selectedDevicelist)
1333     {
1334         return OC_STACK_INVALID_PARAM;
1335     }
1336     if (NULL == resultCallback)
1337     {
1338         return OC_STACK_INVALID_CALLBACK;
1339     }
1340
1341     OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
1342     if(!otmCtx)
1343     {
1344         OIC_LOG(ERROR, TAG, "Failed to create OTM Context");
1345         return OC_STACK_NO_MEMORY;
1346     }
1347     otmCtx->ctxResultCallback = resultCallback;
1348     otmCtx->ctxHasError = false;
1349     otmCtx->userCtx = ctx;
1350     OCProvisionDev_t* pCurDev = selectedDevicelist;
1351
1352     //Counting number of selected devices.
1353     otmCtx->ctxResultArraySize = 0;
1354     while(NULL != pCurDev)
1355     {
1356         otmCtx->ctxResultArraySize++;
1357         pCurDev = pCurDev->next;
1358     }
1359
1360     otmCtx->ctxResultArray =
1361         (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
1362     if(NULL == otmCtx->ctxResultArray)
1363     {
1364         OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation");
1365         OICFree(otmCtx);
1366         return OC_STACK_NO_MEMORY;
1367     }
1368     pCurDev = selectedDevicelist;
1369
1370     OCStackResult res = OC_STACK_OK;
1371     //Fill the device UUID for result array.
1372     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
1373     {
1374         //Checking duplication of Device ID.
1375         bool isDuplicate = true;
1376         res = PDMIsDuplicateDevice(&pCurDev->doxm->deviceID, &isDuplicate);
1377         if (OC_STACK_OK != res)
1378         {
1379             goto error;
1380         }
1381         if (isDuplicate)
1382         {
1383             OIC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Device ID is duplicated");
1384             res = OC_STACK_INVALID_PARAM;
1385             goto error;
1386         }
1387         memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id,
1388                pCurDev->doxm->deviceID.id,
1389                UUID_LENGTH);
1390         otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE;
1391         pCurDev = pCurDev->next;
1392     }
1393
1394     StartOwnershipTransfer(otmCtx, selectedDevicelist);
1395
1396     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
1397     return OC_STACK_OK;
1398
1399 error:
1400     OICFree(otmCtx->ctxResultArray);
1401     OICFree(otmCtx);
1402     return res;
1403 }
1404
1405 OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx)
1406 {
1407     OIC_LOG(INFO, TAG, "IN PutProvisioningStatus");
1408
1409     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1410     {
1411         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
1412         return OC_STACK_INVALID_PARAM;
1413     }
1414
1415     //Change the TAKE_OWNER bit of CM to 0.
1416     otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
1417
1418     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
1419     if (!secPayload)
1420     {
1421         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1422         return OC_STACK_NO_MEMORY;
1423     }
1424     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1425     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
1426             &secPayload->securityData, &secPayload->payloadSize))
1427     {
1428         OCPayloadDestroy((OCPayload *)secPayload);
1429         return OC_STACK_INVALID_JSON;
1430     }
1431     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
1432     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1433
1434     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1435     if(!PMGenerateQuery(true,
1436                         otmCtx->selectedDeviceInfo->endpoint.addr,
1437                         otmCtx->selectedDeviceInfo->securePort,
1438                         otmCtx->selectedDeviceInfo->connType,
1439                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1440     {
1441         OIC_LOG(ERROR, TAG, "PutProvisioningStatus : Failed to generate query");
1442         return OC_STACK_ERROR;
1443     }
1444     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1445
1446     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1447     cbData.cb = &ProvisioningStatusHandler;
1448     cbData.context = (void*)otmCtx;
1449     cbData.cd = NULL;
1450     OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1451             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1452     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
1453     if (ret != OC_STACK_OK)
1454     {
1455         OIC_LOG(ERROR, TAG, "OCStack resource error");
1456     }
1457
1458     OIC_LOG(INFO, TAG, "OUT PutProvisioningStatus");
1459
1460     return ret;
1461 }
1462
1463 OCStackResult PutNormalOperationStatus(OTMContext_t* otmCtx)
1464 {
1465     OIC_LOG(INFO, TAG, "IN PutNormalOperationStatus");
1466
1467     if(!otmCtx || !otmCtx->selectedDeviceInfo)
1468     {
1469         OIC_LOG(ERROR, TAG, "OTMContext is NULL");
1470         return OC_STACK_INVALID_PARAM;
1471     }
1472
1473     //Set isop to true.
1474     otmCtx->selectedDeviceInfo->pstat->isOp = true;
1475
1476     OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
1477     if (!secPayload)
1478     {
1479         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
1480         return OC_STACK_NO_MEMORY;
1481     }
1482     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
1483     if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
1484             &secPayload->securityData, &secPayload->payloadSize))
1485     {
1486         OCPayloadDestroy((OCPayload *)secPayload);
1487         return OC_STACK_INVALID_JSON;
1488     }
1489     OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
1490     OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
1491
1492     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
1493     if(!PMGenerateQuery(true,
1494                         otmCtx->selectedDeviceInfo->endpoint.addr,
1495                         otmCtx->selectedDeviceInfo->securePort,
1496                         otmCtx->selectedDeviceInfo->connType,
1497                         query, sizeof(query), OIC_RSRC_PSTAT_URI))
1498     {
1499         OIC_LOG(ERROR, TAG, "PutNormalOperationStatus : Failed to generate query");
1500         return OC_STACK_ERROR;
1501     }
1502     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
1503
1504     OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
1505     cbData.cb = &ReadyForNomalStatusHandler;
1506     cbData.context = (void*)otmCtx;
1507     cbData.cd = NULL;
1508     OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
1509             otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
1510     OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
1511     if (ret != OC_STACK_OK)
1512     {
1513         OIC_LOG(ERROR, TAG, "OCStack resource error");
1514     }
1515
1516     OIC_LOG(INFO, TAG, "OUT PutNormalOperationStatus");
1517
1518     return ret;
1519 }