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