[IOT-2447] Support Multiple Ownership
authorOleksii Beketov <ol.beketov@samsung.com>
Tue, 22 Aug 2017 00:40:53 +0000 (03:40 +0300)
committerRandeep Singh <randeep.s@samsung.com>
Wed, 23 Aug 2017 09:02:41 +0000 (09:02 +0000)
Enable MOT

Change-Id: I4cfd4e456d5ae53596cffb6648f1a1d265ed6868
Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
Signed-off-by: Oleksandr Dmytrenko <o.dmytrenko@samsung.com>
Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/21577
Reviewed-by: Nathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Alex Kelley <alexke@microsoft.com>
Reviewed-by: Aleksey Volkov <a.volkov@samsung.com>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
resource/csdk/security/provisioning/include/internal/multipleownershiptransfermanager.h
resource/csdk/security/provisioning/include/internal/ownershiptransfermanager.h
resource/csdk/security/provisioning/include/internal/secureresourceprovider.h
resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c
resource/csdk/security/provisioning/src/pmutility.c
resource/csdk/security/provisioning/src/secureresourceprovider.c
resource/csdk/security/src/doxmresource.c

index bbc60bd..6472790 100644 (file)
@@ -115,6 +115,15 @@ OCStackResult MOTDoOwnershipTransfer(void* ctx,
 OCStackResult MOTAddPreconfigPIN(const OCProvisionDev_t *targetDeviceInfo,
                                  const char* preconfPIN, size_t preconfPINLen);
 
+/**
+ * The function checks is the device type MOT support.
+ *
+ * @param[in]  ptrDoxm     Doxm
+ *
+ * @return 0 in case of success and 1 otherwise.
+ */
+int MOTIsSupportedOnboardingType(OicSecDoxm_t *ptrDoxm);
+
 #ifdef __cplusplus
 }
 #endif
index 08e2270..9a9dcba 100644 (file)
@@ -99,8 +99,12 @@ struct OTMContext{
     OCProvisionResult_t* ctxResultArray;      /**< Result array having result of all device. */\r
     size_t ctxResultArraySize;                /**< No of elements in result array. */\r
     bool ctxHasError;                         /**< Does OT process have any error. */\r
-    OCDoHandle ocDoHandle;                    /** <A handle for latest request message*/\r
-    OTMCallbackData_t otmCallback; /**< OTM callbacks to perform the OT/MOT. **/\r
+    OCDoHandle ocDoHandle;                    /**< A handle for latest request message. */\r
+    OTMCallbackData_t otmCallback;            /**< OTM callbacks to perform the OT/MOT. */\r
+#ifdef MULTIPLE_OWNER\r
+    OicSecDoxm_t* doxm;                       /**< Device Owner Transfer Method. */\r
+    OicSecCred_t* cred;                       /**< Credential data. */\r
+#endif // MULTIPLE_OWNER\r
     int attemptCnt;\r
 };\r
 \r
index 03b657a..ce20483 100644 (file)
 #include "pmtypes.h"
 #include "octypes.h"
 
+// Enum type index for data types.
+typedef enum
+{
+    CHAIN_TYPE = 0,                       /**< Certificate trust chain.**/
+    ACL_TYPE,                             /**< Access control list.**/
+    PSK_TYPE,                             /**< Pre-Shared Key.**/
+    CERT_TYPE,                            /**< X.509 certificate.**/
+    MOT_TYPE                              /**< Multiple Ownership Transfer.**/
+} DataType_t;
+
+/**
+ * Structure to carry general data to callback.
+ */
+typedef struct Data
+{
+    void *ctx;                                   /**< Pointer to user context.**/
+    DataType_t type;                             /**< Data type of the context.**/
+} Data_t;
+
 
 #ifdef __cplusplus
 extern "C"
@@ -348,6 +367,7 @@ OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
  */
 OCStackResult SRPReadTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
                                      size_t *chainSize);
+
 /**
  * Function for certificate provisioning.
  * @param[in] ctx Application context to be returned in result callback.
@@ -360,6 +380,20 @@ OCStackResult SRPReadTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
 OCStackResult SRPProvisionCertificate(void *ctx, const OCProvisionDev_t *pDev,
         const char* pemCert, OCProvisionResultCB resultCallback);
 
+/**
+ * Updates pstat resource of server.
+ *
+ * @param[in] data Structure for the application context
+ * @param[in] dos DOS mode
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            provisioning request recieves a response from first resource server.
+ * @return  OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t dos,
+                            OCClientResponseHandler resultCallback);
+
+void FreeData(Data_t *data);
+
 #ifdef __cplusplus
 }
 #endif
index 825e3ec..0f9c24f 100644 (file)
@@ -59,6 +59,7 @@
 #include "ocstackinternal.h"
 #include "mbedtls/ssl_ciphersuites.h"
 #include "ocrandom.h"
+#include "secureresourceprovider.h"
 
 #define TAG "OIC_MULTIPLE_OTM"
 
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult MOTUpdateSecurityResourceCB(void *ctx, OCDoHandle UNUSED,
-                                                OCClientResponse *clientResponse)
+static OCStackApplicationResult MOTUpdateSecurityResourceCB(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
 {
-    OIC_LOG_V(INFO, TAG, "Inside MOTUpdateMomCB.");
-    (void)UNUSED;
-    OTMContext_t *motCtx = (OTMContext_t*)ctx;
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    OC_UNUSED(handle);
+
+    OTMContext_t *motCtx = NULL;
+
+    VERIFY_NOT_NULL(TAG, ctx, ERROR);
+    VERIFY_NOT_NULL(TAG, ((Data_t *)ctx)->ctx, ERROR);
+
+    motCtx = (OTMContext_t *)(((Data_t *)ctx)->ctx);
+
     VERIFY_NOT_NULL(TAG, motCtx, ERROR);
     VERIFY_NOT_NULL(TAG, motCtx->ctxResultCallback, ERROR);
     VERIFY_NOT_NULL(TAG, motCtx->ctxResultArray, ERROR);
 
-    if(clientResponse)
+    if (clientResponse)
     {
         memcpy(motCtx->ctxResultArray[0].deviceId.id,
                motCtx->selectedDeviceInfo->doxm->deviceID.id,
                sizeof(OicUuid_t));
         motCtx->ctxResultArray[0].res = clientResponse->result;
-
-        if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
         {
             motCtx->ctxHasError = false;
         }
@@ -103,7 +111,7 @@ static OCStackApplicationResult MOTUpdateSecurityResourceCB(void *ctx, OCDoHandl
     }
     else
     {
-        OIC_LOG_V(ERROR, TAG, "SRPGetACLResourceCB received Null clientResponse");
+        OIC_LOG_V(ERROR, TAG, "%s: received Null clientResponse", __func__);
         motCtx->ctxResultArray[0].res = OC_STACK_ERROR;
         motCtx->ctxHasError = true;
     }
@@ -111,34 +119,67 @@ static OCStackApplicationResult MOTUpdateSecurityResourceCB(void *ctx, OCDoHandl
     motCtx->ctxResultCallback(motCtx->userCtx, motCtx->ctxResultArraySize,
                               motCtx->ctxResultArray, motCtx->ctxHasError);
 
+    OIC_LOG_V(DEBUG, TAG, "%s: update ok", __func__);
 exit:
-    if(motCtx)
+    if (motCtx)
     {
         PMDeleteDeviceList(motCtx->selectedDeviceInfo);
         OICFree(motCtx->ctxResultArray);
         OICFree(motCtx);
     }
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_DELETE_TRANSACTION;
 }
 
 /**
- * Internal API to send POST doxm request
+ * Restores pstat after PIN provisioning
  */
-static OCStackResult MOTSendPostDoxm(void *ctx,
-                                     const OCProvisionDev_t *targetDeviceInfo,
-                                     OCProvisionResultCB resultCallback,
-                                     const OicSecDoxm_t* doxm)
+static OCStackApplicationResult RestoreProvCB(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
 {
-    OCStackResult postMomRes = OC_STACK_ERROR;
-    OCSecurityPayload* secPayload = NULL;
-    OTMContext_t *motCtx = NULL;
-    OCProvisionDev_t *localTargetDeviceInfo = NULL;
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    OC_UNUSED(handle);
+    OC_UNUSED(clientResponse);
+
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+
+    if (OC_STACK_OK != SetDOS(ctx, DOS_RFNOP, MOTUpdateSecurityResourceCB))
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: SetDOS", __func__);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackApplicationResult MOTSendPostDoxmCB(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    OC_UNUSED(handle);
+    OC_UNUSED(clientResponse);
+
     bool freeFlag = true;
+    OTMContext_t *motCtx = NULL;
+    OCStackResult postMomRes = OC_STACK_INVALID_PARAM;
+    VERIFY_NOT_NULL(TAG, ctx, ERROR);
 
-    OIC_LOG(DEBUG, TAG, "IN MOTSendPostDoxm");
+    OCSecurityPayload *secPayload = NULL;
+
+    Data_t *data = (Data_t *) ctx;
+    if (MOT_TYPE != data->type)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid type");
+        goto exit;
+    }
+
+    VERIFY_NOT_NULL(TAG, data->ctx, ERROR);
+    motCtx = (OTMContext_t *) (data->ctx);
 
     //Generate the security payload using updated doxm
-    secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+    secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
     VERIFY_NOT_NULL(TAG, secPayload, ERROR);
     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
 
@@ -151,8 +192,8 @@ static OCStackResult MOTSendPostDoxm(void *ctx,
     propertiesToInclude[DOXM_SUBOWNER] = true;
     propertiesToInclude[DOXM_MOM] = true;
 
-    postMomRes = DoxmToCBORPayloadPartial(doxm, &secPayload->securityData,
-        &secPayload->payloadSize, propertiesToInclude);
+    postMomRes = DoxmToCBORPayloadPartial(motCtx->doxm, &secPayload->securityData,
+                                          &secPayload->payloadSize, propertiesToInclude);
     VERIFY_SUCCESS(TAG, (OC_STACK_OK == postMomRes), ERROR);
 
     OIC_LOG(DEBUG, TAG, "Created doxm payload to update doxm:");
@@ -160,15 +201,60 @@ static OCStackResult MOTSendPostDoxm(void *ctx,
 
     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
     bool queryGenRes = PMGenerateQuery(true,
-                                       targetDeviceInfo->endpoint.addr,
-                                       targetDeviceInfo->securePort,
-                                       targetDeviceInfo->connType,
+                                       motCtx->selectedDeviceInfo->endpoint.addr,
+                                       motCtx->selectedDeviceInfo->securePort,
+                                       motCtx->selectedDeviceInfo->connType,
                                        query, sizeof(query), OIC_RSRC_DOXM_URI);
     VERIFY_SUCCESS(TAG, (true == queryGenRes), ERROR);
     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
 
+    //Send POST request
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(cbData));
+
+    cbData.cb = &RestoreProvCB;
+    cbData.context = ctx;
+    cbData.cd = NULL;
+
+    postMomRes = OCDoResource(NULL, OC_REST_POST, query,
+                              &(motCtx->selectedDeviceInfo->endpoint), (OCPayload *)secPayload,
+                              motCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    VERIFY_SUCCESS(TAG, (OC_STACK_OK == postMomRes), ERROR);
+
+    freeFlag = false;
+
+    OIC_LOG_V(DEBUG, TAG, "%s: Send POST 'doxm' request to resource server", __func__);
+
+exit:
+    //If POST request successfully sent, motCtx will be cleaned from response handler.
+    if (freeFlag && motCtx)
+    {
+        PMDeleteDeviceList(motCtx->selectedDeviceInfo);
+        OICFree(motCtx->ctxResultArray);
+        OICFree(motCtx);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return postMomRes;
+}
+
+/**
+ * Internal API to send POST doxm request
+ */
+static OCStackResult MOTSendPostDoxm(void *ctx,
+                                     const OCProvisionDev_t *targetDeviceInfo,
+                                     OCProvisionResultCB resultCallback,
+                                     OicSecDoxm_t *doxm)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    OTMContext_t *motCtx = NULL;
+    OCProvisionDev_t *localTargetDeviceInfo = NULL;
+    OCStackResult ret =  OC_STACK_ERROR;
+
     //Create the MOT Context to handle the response message
-    motCtx = (OTMContext_t*)OICCalloc(1, sizeof(OTMContext_t));
+    motCtx = (OTMContext_t *)OICCalloc(1, sizeof(OTMContext_t));
     VERIFY_NOT_NULL(TAG, motCtx, ERROR);
 
     localTargetDeviceInfo = PMCloneOCProvisionDevList(targetDeviceInfo);
@@ -178,35 +264,31 @@ static OCStackResult MOTSendPostDoxm(void *ctx,
     motCtx->ctxResultCallback = resultCallback;
     motCtx->ctxResultArraySize = 1;
     motCtx->ctxHasError = false;
+    motCtx->doxm = doxm;
     motCtx->userCtx = ctx;
-    motCtx->ctxResultArray= (OCProvisionResult_t*)OICCalloc(1, sizeof(OCProvisionResult_t));
+    motCtx->ctxResultArray = (OCProvisionResult_t *)OICCalloc(1, sizeof(OCProvisionResult_t));
     VERIFY_NOT_NULL(TAG, motCtx->ctxResultArray, ERROR);
 
-    //Send POST request
-    OCCallbackData cbData;
-    memset(&cbData, 0, sizeof(cbData));
-    cbData.cb = &MOTUpdateSecurityResourceCB;
-    cbData.context = (void *)motCtx;
-    OIC_LOG(DEBUG, TAG, "Sending POST 'doxm' request to resource server");
-    postMomRes = OCDoResource(NULL, OC_REST_POST, query,
-                              &targetDeviceInfo->endpoint, (OCPayload*)secPayload,
-                              targetDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == postMomRes), ERROR);
-
-    freeFlag = false;
-
-    OIC_LOG(DEBUG, TAG, "OUT MOTSendPostDoxm");
+    Data_t *data = (Data_t *) OICCalloc(1, sizeof(Data_t));
+    VERIFY_NOT_NULL(TAG, data, ERROR);
+    data->type = MOT_TYPE;
+    data->ctx = motCtx;
 
+    ret =  SetDOS(data, DOS_RFPRO, MOTSendPostDoxmCB);
+    if (OC_STACK_OK != ret)
+    {
+        FreeData(data);
+    }
 exit:
-    //If POST request successfully sent, motCtx will be cleaned from response handler.
-    if(freeFlag && motCtx)
+    if (OC_STACK_OK != ret)
     {
-        PMDeleteDeviceList(motCtx->selectedDeviceInfo);
         OICFree(motCtx->ctxResultArray);
         OICFree(motCtx);
     }
 
-    return postMomRes;
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return ret;
 }
 
 /**
@@ -222,8 +304,8 @@ OCStackResult MOTChangeMode(void *ctx, const OCProvisionDev_t *targetDeviceInfo,
                             const OicSecMomType_t momType, OCProvisionResultCB resultCallback)
 {
     OCStackResult postMomRes = OC_STACK_INVALID_PARAM;
-    OicSecDoxm_tdoxm = NULL;
-    uint8_tdoxmPayload = NULL;
+    OicSecDoxm_t *doxm = NULL;
+    uint8_t *doxmPayload = NULL;
     size_t doxmPayloadLen = 0;
 
     OIC_LOG(DEBUG, TAG, "IN MOTChangeMode");
@@ -241,10 +323,10 @@ OCStackResult MOTChangeMode(void *ctx, const OCProvisionDev_t *targetDeviceInfo,
     VERIFY_SUCCESS(TAG, (OC_STACK_OK == postMomRes), ERROR);
     VERIFY_NOT_NULL(TAG, doxm, ERROR);
 
-    if(NULL == doxm->mom)
+    if (NULL == doxm->mom)
     {
         postMomRes = OC_STACK_NO_MEMORY;
-        doxm->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t));
+        doxm->mom = (OicSecMom_t *)OICCalloc(1, sizeof(OicSecMom_t));
         VERIFY_NOT_NULL(TAG, (doxm->mom), ERROR);
     }
     doxm->mom->mode = momType;
@@ -271,11 +353,11 @@ exit:
  * @return OC_STACK_OK in case of success and other value otherwise.
  */
 OCStackResult MOTAddMOTMethod(void *ctx, OCProvisionDev_t *targetDeviceInfo,
-                                 const OicSecOxm_t newOxm, OCProvisionResultCB resultCallback)
+                              const OicSecOxm_t newOxm, OCProvisionResultCB resultCallback)
 {
     OCStackResult postOxmRes = OC_STACK_INVALID_PARAM;
-    OicSecOxm_tnewOxms = NULL;
-    uint8_tdoxmPayload = NULL;
+    OicSecOxm_t *newOxms = NULL;
+    uint8_t *doxmPayload = NULL;
 
     OIC_LOG(DEBUG, TAG, "IN MOTAddMOTMethod");
 
@@ -285,12 +367,12 @@ OCStackResult MOTAddMOTMethod(void *ctx, OCProvisionDev_t *targetDeviceInfo,
     VERIFY_NOT_NULL(TAG, resultCallback, ERROR);
     postOxmRes = OC_STACK_NO_MEMORY;
 
-    for(size_t i = 0; i < targetDeviceInfo->doxm->oxmLen; i++)
+    for (size_t i = 0; i < targetDeviceInfo->doxm->oxmLen; i++)
     {
-        if(targetDeviceInfo->doxm->oxm[i] == newOxm)
+        if (targetDeviceInfo->doxm->oxm[i] == newOxm)
         {
             OIC_LOG_V(INFO, TAG, "[%d] OxM already supported", (int)newOxm);
-            OCProvisionResult_t* resArr = (OCProvisionResult_t*)OICCalloc(1, sizeof(OCProvisionResult_t));
+            OCProvisionResult_t *resArr = (OCProvisionResult_t *)OICCalloc(1, sizeof(OCProvisionResult_t));
             VERIFY_NOT_NULL(TAG, resArr, ERROR);
             resArr->res = OC_STACK_OK;
             memcpy(resArr->deviceId.id, targetDeviceInfo->doxm->deviceID.id, sizeof(resArr->deviceId.id));
@@ -299,10 +381,10 @@ OCStackResult MOTAddMOTMethod(void *ctx, OCProvisionDev_t *targetDeviceInfo,
         }
     }
 
-    newOxms = (OicSecOxm_t*)OICMalloc(sizeof(OicSecOxm_t) * (targetDeviceInfo->doxm->oxmLen + 1));
-    VERIFY_NOT_NULL(TAG, newOxms , ERROR);
+    newOxms = (OicSecOxm_t *)OICMalloc(sizeof(OicSecOxm_t) * (targetDeviceInfo->doxm->oxmLen + 1));
+    VERIFY_NOT_NULL(TAG, newOxms, ERROR);
 
-    for(size_t i = 0; i < targetDeviceInfo->doxm->oxmLen; i++)
+    for (size_t i = 0; i < targetDeviceInfo->doxm->oxmLen; i++)
     {
         newOxms[i] = targetDeviceInfo->doxm->oxm[i];
     }
@@ -311,7 +393,7 @@ OCStackResult MOTAddMOTMethod(void *ctx, OCProvisionDev_t *targetDeviceInfo,
     OICFree(targetDeviceInfo->doxm->oxm);
     targetDeviceInfo->doxm->oxm = newOxms;
 
-    //Send POST reuqest for update doxm
+    //Send POST request for doxm update
     postOxmRes = MOTSendPostDoxm(ctx, targetDeviceInfo, resultCallback, targetDeviceInfo->doxm);
     VERIFY_SUCCESS(TAG, (OC_STACK_OK == postOxmRes), ERROR);
 
@@ -326,7 +408,7 @@ exit:
  * API to update 'doxm.oxmsel' to resource server.
  *
  * @param[in] targetDeviceInfo Selected target device.
 * @param[in] oxmSelValue Method of multiple ownership transfer (ref. oic.sec.doxmtype)
+ * @param[in] oxmSelValue Method of multiple ownership transfer (ref. oic.sec.doxmtype)
  * @param[in] resultCallback callback provided by API user, callback will be called when
  *            POST 'oxmsel' request recieves a response from resource server.
  * @return OC_STACK_OK in case of success and other value otherwise.
@@ -335,8 +417,8 @@ OCStackResult MOTSelectMOTMethod(void *ctx, const OCProvisionDev_t *targetDevice
                                  const OicSecOxm_t oxmSelValue, OCProvisionResultCB resultCallback)
 {
     OCStackResult postMomRes = OC_STACK_INVALID_CALLBACK;
-    OicSecDoxm_tdoxm = NULL;
-    uint8_tdoxmPayload = NULL;
+    OicSecDoxm_t *doxm = NULL;
+    uint8_t *doxmPayload = NULL;
     size_t doxmPayloadLen = 0;
 
     OIC_LOG(DEBUG, TAG, "IN MOTSelectOTMethod");
@@ -346,9 +428,9 @@ OCStackResult MOTSelectMOTMethod(void *ctx, const OCProvisionDev_t *targetDevice
     VERIFY_NOT_NULL(TAG, targetDeviceInfo, ERROR);
 
     bool isValidOxmsel = false;
-    for(size_t i = 0; i < targetDeviceInfo->doxm->oxmLen; i++)
+    for (size_t i = 0; i < targetDeviceInfo->doxm->oxmLen; i++)
     {
-        if(targetDeviceInfo->doxm->oxm[i] == oxmSelValue)
+        if (targetDeviceInfo->doxm->oxm[i] == oxmSelValue)
         {
             isValidOxmsel = true;
             break;
@@ -378,6 +460,90 @@ exit:
     return postMomRes;
 }
 
+static OCStackApplicationResult MOTProvisionPreconfigPINCB(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    OC_UNUSED(handle);
+    OC_UNUSED(clientResponse);
+
+    bool freeFlag = true;
+    OTMContext_t *motCtx = NULL;
+    OCStackResult postCredRes = OC_STACK_INVALID_PARAM;
+    OCSecurityPayload *secPayload = NULL;
+
+    VERIFY_NOT_NULL(TAG, ctx, ERROR);
+
+    Data_t *data = (Data_t *) ctx;
+    if (MOT_TYPE != data->type)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid type");
+        goto exit;
+    }
+
+    VERIFY_NOT_NULL(TAG, data->ctx, ERROR);
+    motCtx = (OTMContext_t *) (data->ctx);
+
+    //Generate the security payload using updated doxm
+    secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
+    VERIFY_NOT_NULL(TAG, secPayload, ERROR);
+    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+
+    postCredRes = CredToCBORPayload(motCtx->cred, &secPayload->securityData, &secPayload->payloadSize,
+                                    false);
+    VERIFY_SUCCESS(TAG, (OC_STACK_OK == postCredRes), ERROR);
+
+    OIC_LOG(DEBUG, TAG, "Created Credential payload to register PIN credential:");
+    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    bool queryGenRes = PMGenerateQuery(true,
+                                       motCtx->selectedDeviceInfo->endpoint.addr,
+                                       motCtx->selectedDeviceInfo->securePort,
+                                       motCtx->selectedDeviceInfo->connType,
+                                       query, sizeof(query), OIC_RSRC_CRED_URI);
+    VERIFY_SUCCESS(TAG, (true == queryGenRes), ERROR);
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    //Send POST request
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(cbData));
+
+    cbData.cb = &RestoreProvCB;
+    cbData.context = ctx;
+    cbData.cd = NULL;
+
+    OIC_LOG(DEBUG, TAG, "Sending POST Preconfiged PIN credenatial request to resource server");
+    postCredRes = OCDoResource(NULL, OC_REST_POST, query,
+                               &(motCtx->selectedDeviceInfo->endpoint), (OCPayload *)secPayload,
+                               motCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    VERIFY_SUCCESS(TAG, (OC_STACK_OK == postCredRes), ERROR);
+
+    freeFlag = false;
+
+exit:
+    //If POST request successfully sent, motCtx will be cleaned from response handler.
+    if (freeFlag && motCtx)
+    {
+        PMDeleteDeviceList(motCtx->selectedDeviceInfo);
+
+        if (motCtx->cred)
+        {
+            OICFree(motCtx->cred->credUsage);
+            OICFree(motCtx->cred->privateData.data);
+            OICFree(motCtx->cred);
+        }
+
+        OICFree(motCtx->ctxResultArray);
+        OICFree(motCtx);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return postCredRes;
+}
+
 /**
  * API to provision preconfigured PIN to resource server.
  *
@@ -389,16 +555,17 @@ exit:
  * @return OC_STACK_OK in case of success and other value otherwise.
  */
 OCStackResult MOTProvisionPreconfigPIN(void *ctx, const OCProvisionDev_t *targetDeviceInfo,
-                                 const char* preconfPIN, size_t preconfPINLen, OCProvisionResultCB resultCallback)
+                                       const char *preconfPIN, size_t preconfPINLen, OCProvisionResultCB resultCallback)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     OCStackResult postCredRes = OC_STACK_INVALID_CALLBACK;
     bool freeFlag = true;
-    OCSecurityPayload* secPayload = NULL;
     OTMContext_t *motCtx = NULL;
-    OicSecCred_t* pinCred = NULL;
-    OCProvisionDev_t* localTargetDeviceInfo = NULL;
+    OicSecCred_t *pinCred = NULL;
+    Data_t *data = NULL;
+    OCProvisionDev_t *localTargetDeviceInfo = NULL;
 
-    OIC_LOG(DEBUG, TAG, "IN MOTProvisionPreconfigPIN");
 
     VERIFY_NOT_NULL(TAG, resultCallback, ERROR);
     postCredRes = OC_STACK_INVALID_PARAM;
@@ -409,10 +576,10 @@ OCStackResult MOTProvisionPreconfigPIN(void *ctx, const OCProvisionDev_t *target
 
     postCredRes = OC_STACK_NO_MEMORY;
     //Generate PIN based credential
-    pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    pinCred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
     VERIFY_NOT_NULL(TAG, pinCred, ERROR);
 
-    pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPINLen + 1);
+    pinCred->privateData.data = (uint8_t *)OICMalloc(preconfPINLen + 1);
     VERIFY_NOT_NULL(TAG, pinCred->privateData.data, ERROR);
 
     memcpy(pinCred->privateData.data, preconfPIN, preconfPINLen);
@@ -422,77 +589,59 @@ OCStackResult MOTProvisionPreconfigPIN(void *ctx, const OCProvisionDev_t *target
     pinCred->credType = PIN_PASSWORD;
     memcpy(&pinCred->subject, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t));
 
-    pinCred->credUsage = (char*)OICCalloc(1, (strlen(PRECONFIG_PIN_CRED) + 1));
+    pinCred->credUsage = (char *)OICCalloc(1, (strlen(PRECONFIG_PIN_CRED) + 1));
     VERIFY_NOT_NULL(TAG, pinCred->credUsage, ERROR);
     OICStrcpy(pinCred->credUsage, (strlen(PRECONFIG_PIN_CRED) + 1), PRECONFIG_PIN_CRED);
 
-    //Generate the security payload using updated doxm
-    secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
-    VERIFY_NOT_NULL(TAG, secPayload, ERROR);
-    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-
-    postCredRes = CredToCBORPayload(pinCred, &secPayload->securityData, &secPayload->payloadSize, false);
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == postCredRes), ERROR);
-
-    OIC_LOG(DEBUG, TAG, "Created Credential payload to register PIN credential:");
-    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
-
-    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
-    bool queryGenRes = PMGenerateQuery(true,
-                                       targetDeviceInfo->endpoint.addr,
-                                       targetDeviceInfo->securePort,
-                                       targetDeviceInfo->connType,
-                                       query, sizeof(query), OIC_RSRC_CRED_URI);
-    VERIFY_SUCCESS(TAG, (true == queryGenRes), ERROR);
-    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
-
     //Create the MOT Context to handle the response message
-    motCtx = (OTMContext_t*)OICCalloc(1, sizeof(OTMContext_t));
+    motCtx = (OTMContext_t *)OICCalloc(1, sizeof(OTMContext_t));
     VERIFY_NOT_NULL(TAG, motCtx, ERROR);
 
     localTargetDeviceInfo = PMCloneOCProvisionDevList(targetDeviceInfo);
     VERIFY_NOT_NULL(TAG, localTargetDeviceInfo, ERROR);
 
-    motCtx->selectedDeviceInfo= localTargetDeviceInfo;
+    motCtx->selectedDeviceInfo = localTargetDeviceInfo;
     motCtx->ctxResultCallback = resultCallback;
-    motCtx->ctxResultArraySize =1;
+    motCtx->ctxResultArraySize = 1;
     motCtx->ctxHasError = false;
     motCtx->userCtx = ctx;
-    motCtx->ctxResultArray = (OCProvisionResult_t*)OICCalloc(1, sizeof(OCProvisionResult_t));
+    motCtx->cred = pinCred;
+    motCtx->ctxResultArray = (OCProvisionResult_t *)OICCalloc(1, sizeof(OCProvisionResult_t));
     VERIFY_NOT_NULL(TAG, motCtx->ctxResultArray, ERROR);
 
-    //Send POST request
-    OCCallbackData cbData;
-    memset(&cbData, 0, sizeof(cbData));
-    cbData.cb = &MOTUpdateSecurityResourceCB;
-    cbData.context = (void *)motCtx;
-    OIC_LOG(DEBUG, TAG, "Sending POST Preconfiged PIN credenatial request to resource server");
-    postCredRes = OCDoResource(NULL, OC_REST_POST, query,
-                              &targetDeviceInfo->endpoint, (OCPayload*)secPayload,
-                              targetDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == postCredRes), ERROR);
-
-    freeFlag = false;
+    data = (Data_t *) OICCalloc(1, sizeof(Data_t));
+    VERIFY_NOT_NULL(TAG, data, ERROR);
+    data->type = MOT_TYPE;
+    data->ctx = motCtx;
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTProvisionPreconfigPIN");
+    if (SetDOS(data, DOS_RFPRO, MOTProvisionPreconfigPINCB) != OC_STACK_OK)
+    {
+        FreeData(data);
+        postCredRes = OC_STACK_ERROR;
+        goto exit;
+    }
 
-    return postCredRes;
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_OK;
 
 exit:
     //If POST request successfully sent, motCtx will be cleaned from response handler.
-    if(freeFlag && motCtx)
+    if (freeFlag && motCtx)
     {
         PMDeleteDeviceList(motCtx->selectedDeviceInfo);
+
+        if (motCtx->cred)
+        {
+            OICFree(motCtx->cred->credUsage);
+            OICFree(motCtx->cred->privateData.data);
+            OICFree(motCtx->cred);
+        }
+
         OICFree(motCtx->ctxResultArray);
         OICFree(motCtx);
     }
 
-    if(pinCred)
-    {
-        OICFree(pinCred->credUsage);
-        OICFree(pinCred->privateData.data);        
-        OICFree(pinCred);
-    }
+    OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
 
     return postCredRes;
 }
@@ -502,16 +651,14 @@ exit:
  * API for Sub Owner
  **********************************************************************/
 
-static OCStackResult StartMultipleOwnershipTransfer(OTMContext_tmotCtx,
-                                                    OCProvisionDev_t* selectedDevice);
+static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t *motCtx,
+        OCProvisionDev_t *selectedDevice);
 
-static OTMContext_t* g_MotCtx = NULL;
-
-static bool IsComplete(OTMContext_t* otmCtx)
+static bool IsComplete(OTMContext_t *otmCtx)
 {
-    for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
+    for (size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
     {
-        if(OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
+        if (OC_STACK_CONTINUE == otmCtx->ctxResultArray[i].res)
         {
             return false;
         }
@@ -520,45 +667,57 @@ static bool IsComplete(OTMContext_t* otmCtx)
     return true;
 }
 
+int MOTIsSupportedOnboardingType(OicSecDoxm_t *ptrDoxm)
+{
+    OIC_LOG_V(DEBUG, TAG, "Multiple Ownership Transfer type: %u", ptrDoxm->oxmSel);
+
+    if ((OIC_PRECONFIG_PIN != ptrDoxm->oxmSel) && (OIC_RANDOM_DEVICE_PIN != ptrDoxm->oxmSel))
+    {
+        OIC_LOG_V(ERROR, TAG, "Unsupported MOT device");
+        return 1;
+    }
+    return 0;
+}
+
 /**
  * Function to save the result of multiple ownership transfer.
  *
  * @param[in,out] motCtx   Context instance of multiple ownership transfer.
  * @param[in] res   result of multiple ownership transfer.
  */
-static void SetMOTResult(OTMContext_tmotCtx, const OCStackResult res)
+static void SetMOTResult(OTMContext_t *motCtx, const OCStackResult res)
 {
-    OIC_LOG_V(DEBUG, TAG, "IN SetMOTResult : %d ", res);
+    OIC_LOG_V(DEBUG, TAG, "IN %s: %d ", __func__, res);
+
     VERIFY_NOT_NULL(TAG, motCtx, ERROR);
 
-    if(motCtx->selectedDeviceInfo)
+    if (motCtx->selectedDeviceInfo)
     {
         //Revert psk_info callback in case of random PIN OxM
-        if(OIC_RANDOM_DEVICE_PIN == motCtx->selectedDeviceInfo->doxm->oxmSel ||
-           OIC_PRECONFIG_PIN == motCtx->selectedDeviceInfo->doxm->oxmSel)
+        if (!MOTIsSupportedOnboardingType(motCtx->selectedDeviceInfo->doxm))
         {
-            if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
+            if (CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
             {
                 OIC_LOG(WARNING, TAG, "Failed to revert the DTLS credential handler.");
             }
-            OicUuid_t emptyUuid = { .id={0}};
+            OicUuid_t emptyUuid = { .id = {0}};
             SetUuidForPinBasedOxm(&emptyUuid);
         }
 
         OCStackResult pdmRetVal = PDMSetDeviceState(&motCtx->selectedDeviceInfo->doxm->deviceID,
-                                                    PDM_DEVICE_ACTIVE);
+                                  PDM_DEVICE_ACTIVE);
         if (OC_STACK_OK != pdmRetVal)
         {
             OIC_LOG_V(ERROR, TAG, "Failed to add device information into PDM_DB : %d", res);
         }
 
-        for(size_t i = 0; i < motCtx->ctxResultArraySize; i++)
+        for (size_t i = 0; i < motCtx->ctxResultArraySize; i++)
         {
-            if(memcmp(motCtx->selectedDeviceInfo->doxm->deviceID.id,
-                      motCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
+            if (memcmp(motCtx->selectedDeviceInfo->doxm->deviceID.id,
+                       motCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0)
             {
                 motCtx->ctxResultArray[i].res = res;
-                if(OC_STACK_OK != res)
+                if (OC_STACK_OK != res)
                 {
                     motCtx->ctxHasError = true;
                 }
@@ -570,7 +729,7 @@ static void SetMOTResult(OTMContext_t* motCtx, const OCStackResult res)
                          motCtx->selectedDeviceInfo->securePort);
 
         //If there is a request being performed, cancel it to prevent retransmission.
-        if(motCtx->ocDoHandle)
+        if (motCtx->ocDoHandle)
         {
             if (OC_STACK_OK !=  OCCancel(motCtx->ocDoHandle, OC_HIGH_QOS, NULL, 0))
             {
@@ -580,10 +739,10 @@ static void SetMOTResult(OTMContext_t* motCtx, const OCStackResult res)
         }
 
         //If all request is completed, invoke the user callback.
-        if(IsComplete(motCtx))
+        if (IsComplete(motCtx))
         {
             motCtx->ctxResultCallback(motCtx->userCtx, motCtx->ctxResultArraySize,
-                                       motCtx->ctxResultArray, motCtx->ctxHasError);
+                                      motCtx->ctxResultArray, motCtx->ctxHasError);
 
             OICFree(motCtx->ctxResultArray);
             OICFree(motCtx);
@@ -591,8 +750,8 @@ static void SetMOTResult(OTMContext_t* motCtx, const OCStackResult res)
         }
         else
         {
-            if(OC_STACK_OK != StartMultipleOwnershipTransfer(motCtx,
-                                                     motCtx->selectedDeviceInfo->next))
+            if (OC_STACK_OK != StartMultipleOwnershipTransfer(motCtx,
+                    motCtx->selectedDeviceInfo->next))
             {
                 OIC_LOG(ERROR, TAG, "Failed to StartMultipleOwnershipTransfer");
             }
@@ -600,7 +759,7 @@ static void SetMOTResult(OTMContext_t* motCtx, const OCStackResult res)
     }
 
 exit:
-    OIC_LOG(DEBUG, TAG, "OUT SetMOTResult");
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
 }
 
 /**
@@ -614,10 +773,10 @@ exit:
  * @return OC_STACK_OK in case of success and other value otherwise.
  */
 OCStackResult MOTAddPreconfigPIN(const OCProvisionDev_t *targetDeviceInfo,
-                                 const charpreconfPIN, size_t preconfPINLen)
+                                 const char *preconfPIN, size_t preconfPINLen)
 {
     OCStackResult addCredRes = OC_STACK_INVALID_PARAM;
-    OicSecCred_tpinCred = NULL;
+    OicSecCred_t *pinCred = NULL;
 
     OIC_LOG(DEBUG, TAG, "IN MOTAddPreconfigPIN");
 
@@ -626,8 +785,8 @@ OCStackResult MOTAddPreconfigPIN(const OCProvisionDev_t *targetDeviceInfo,
     VERIFY_SUCCESS(TAG, (0 != preconfPINLen), ERROR);
     VERIFY_SUCCESS(TAG, (0 != preconfPINLen && OXM_PRECONFIG_PIN_MAX_SIZE >= preconfPINLen), ERROR);
 
-    OicSecCred_tprevCred = GetCredResourceData(&targetDeviceInfo->doxm->deviceID);
-    if(NULL != prevCred)
+    OicSecCred_t *prevCred = GetCredResourceData(&targetDeviceInfo->doxm->deviceID);
+    if (NULL != prevCred)
     {
         OIC_LOG(INFO, TAG, "PIN/PW Credential already exist!");
         return OC_STACK_OK;
@@ -635,10 +794,10 @@ OCStackResult MOTAddPreconfigPIN(const OCProvisionDev_t *targetDeviceInfo,
 
     addCredRes = OC_STACK_NO_MEMORY;
     //Generate PIN based credential
-    pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    pinCred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
     VERIFY_NOT_NULL(TAG, pinCred, ERROR);
 
-    pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPINLen + 1);
+    pinCred->privateData.data = (uint8_t *)OICMalloc(preconfPINLen + 1);
     VERIFY_NOT_NULL(TAG, pinCred->privateData.data, ERROR);
 
     memcpy(pinCred->privateData.data, preconfPIN, preconfPINLen);
@@ -651,16 +810,15 @@ OCStackResult MOTAddPreconfigPIN(const OCProvisionDev_t *targetDeviceInfo,
     addCredRes = AddCredential(pinCred);
     VERIFY_SUCCESS(TAG, (OC_STACK_OK == addCredRes), ERROR);
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTAddPreconfigPIN");
-
-    return addCredRes;
-
 exit:
-    if(pinCred)
+    if (OC_STACK_OK != addCredRes)
     {
         OICFree(pinCred->privateData.data);
         OICFree(pinCred);
     }
+
+    OIC_LOG(DEBUG, TAG, "OUT MOTAddPreconfigPIN");
+
     return addCredRes;
 }
 
@@ -690,7 +848,7 @@ static OCStackResult SaveSubOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
     }
 #endif
 
-    OicUuid_t ownerDeviceID = {.id={0}};
+    OicUuid_t ownerDeviceID = {.id = {0}};
     if (OC_STACK_OK != GetDoxmDeviceID(&ownerDeviceID))
     {
         OIC_LOG(ERROR, TAG, "Error while retrieving SubOwner's device ID");
@@ -706,11 +864,11 @@ static OCStackResult SaveSubOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
 
     //Generating SubOwnerPSK
     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
-            (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
-            strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
-            ownerDeviceID.id, sizeof(ownerDeviceID.id),
-            selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
-            ownerPSK, OWNER_PSK_LENGTH_128);
+                                           (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
+                                           strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)),
+                                           ownerDeviceID.id, sizeof(ownerDeviceID.id),
+                                           selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id),
+                                           ownerPSK, OWNER_PSK_LENGTH_128);
 
     if (CA_STATUS_OK == pskRet)
     {
@@ -718,13 +876,13 @@ static OCStackResult SaveSubOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
         OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
         //Generating new credential for provisioning tool
         OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
-                                      SYMMETRIC_PAIR_WISE_KEY, NULL,
-                                      &ownerKey, &ownerDeviceID, &ownerDeviceID);
+                                                SYMMETRIC_PAIR_WISE_KEY, NULL,
+                                                &ownerKey, &ownerDeviceID, &ownerDeviceID);
         VERIFY_NOT_NULL(TAG, cred, ERROR);
 
         size_t outSize = 0;
         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
-        char* b64Buf = (char*)OICCalloc(1, b64BufSize);
+        char *b64Buf = (char *)OICCalloc(1, b64BufSize);
         VERIFY_NOT_NULL(TAG, b64Buf, ERROR);
         b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize);
 
@@ -732,7 +890,7 @@ static OCStackResult SaveSubOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
         cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
         VERIFY_NOT_NULL(TAG, cred->privateData.data, ERROR);
 
-        strncpy((char*)(cred->privateData.data), b64Buf, outSize);
+        strncpy((char *)(cred->privateData.data), b64Buf, outSize);
         cred->privateData.data[outSize] = '\0';
         cred->privateData.encoding = OIC_ENCODING_BASE64;
         cred->privateData.len = outSize;
@@ -740,10 +898,11 @@ static OCStackResult SaveSubOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
 
         //Add SubOwnerPSK
         res = AddCredential(cred);
-        if(res != OC_STACK_OK)
+        if (OC_STACK_OK != res)
         {
+            OIC_LOG_V(ERROR, TAG, "%s: cannot add credential", __func__);
             DeleteCredList(cred);
-            return res;
+            goto exit;
         }
     }
     else
@@ -751,8 +910,8 @@ static OCStackResult SaveSubOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT SaveSubOwnerPSK");
 exit:
+    OIC_LOG(DEBUG, TAG, "OUT SaveSubOwnerPSK");
     return res;
 }
 
@@ -766,25 +925,28 @@ exit:
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult SubOwnerCredentialHandler(void *ctx, OCDoHandle UNUSED,
-                                OCClientResponse *clientResponse)
+static OCStackApplicationResult SubOwnerCredentialHandler(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
 {
+    OIC_LOG(DEBUG, TAG, "IN SubOwnerCredentialHandler");
+
+    OC_UNUSED(handle);
+
     VERIFY_NOT_NULL(TAG, clientResponse, WARNING);
     VERIFY_NOT_NULL(TAG, ctx, WARNING);
+    VERIFY_NOT_NULL(TAG, ((Data_t *)ctx)->ctx, ERROR);
 
-    OIC_LOG(DEBUG, TAG, "IN SubOwnerCredentialHandler");
-    (void)UNUSED;
-    OTMContext_t* motCtx = (OTMContext_t*)ctx;
+    OTMContext_t *motCtx = (OTMContext_t *)(((Data_t *)ctx)->ctx); //ctx;
 
-    if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+    if (OC_STACK_RESOURCE_CHANGED == clientResponse->result)
     {
-        if(motCtx && motCtx->selectedDeviceInfo)
+        if (motCtx && motCtx->selectedDeviceInfo)
         {
             //Close the temporal secure session to verify the owner credential
-            CAEndpoint_tendpoint = (CAEndpoint_t *)&motCtx->selectedDeviceInfo->endpoint;
+            CAEndpoint_t *endpoint = (CAEndpoint_t *)&motCtx->selectedDeviceInfo->endpoint;
             endpoint->port = motCtx->selectedDeviceInfo->securePort;
             CAResult_t caResult = CAcloseSslSession(endpoint);
-            if(CA_STATUS_OK != caResult)
+            if (CA_STATUS_OK != caResult)
             {
                 OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
                 SetMOTResult(motCtx, OC_STACK_ERROR);
@@ -792,7 +954,7 @@ static OCStackApplicationResult SubOwnerCredentialHandler(void *ctx, OCDoHandle
             }
 
             caResult = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, endpoint->adapter);
-            if(CA_STATUS_OK != caResult)
+            if (CA_STATUS_OK != caResult)
             {
                 OIC_LOG(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
                 SetMOTResult(motCtx, OC_STACK_ERROR);
@@ -809,37 +971,78 @@ static OCStackApplicationResult SubOwnerCredentialHandler(void *ctx, OCDoHandle
         SetMOTResult(motCtx, clientResponse->result);
     }
 
+exit:
     OIC_LOG(DEBUG, TAG, "OUT SubOwnerCredentialHandler");
 
-exit:
     return  OC_STACK_DELETE_TRANSACTION;
 }
 
+/**
+ * Restores pstat after change credential
+ */
+static OCStackApplicationResult RestoreCredCB(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    OC_UNUSED(handle);
+    OC_UNUSED(clientResponse);
+
+    VERIFY_NOT_NULL_RETURN(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+
+    if (OC_STACK_OK != SetDOS(ctx, DOS_RFNOP, SubOwnerCredentialHandler))
+    {
+        OIC_LOG_V(ERROR, TAG, "OUT %s", __func__);
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
 
-static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackApplicationResult PostSubOwnerCredentialCB(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
 {
-    OIC_LOG(DEBUG, TAG, "IN PostSubOwnerCredential");
+    OIC_LOG(DEBUG, TAG, "IN PostSubOwnerCredentialCB");
+
+    OC_UNUSED(handle);
+    OC_UNUSED(clientResponse);
 
-    if(!motCtx || !motCtx->selectedDeviceInfo)
+    Data_t *data = (Data_t *) ctx;
+    if (MOT_TYPE != data->type)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid type");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if (!(data->ctx))
     {
         OIC_LOG(ERROR, TAG, "Invalid parameters");
         return OC_STACK_INVALID_PARAM;
     }
 
-    OCProvisionDev_t* deviceInfo = motCtx->selectedDeviceInfo;
+    OTMContext_t *motCtx = (OTMContext_t *) (data->ctx);
+    if (!motCtx || !motCtx->selectedDeviceInfo)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid parameters");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCProvisionDev_t *deviceInfo = motCtx->selectedDeviceInfo;
     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
 
-    if(!PMGenerateQuery(true,
-                        deviceInfo->endpoint.addr, deviceInfo->securePort,
-                        deviceInfo->connType,
-                        query, sizeof(query), OIC_RSRC_CRED_URI))
+    if (!PMGenerateQuery(true,
+                         deviceInfo->endpoint.addr, deviceInfo->securePort,
+                         deviceInfo->connType,
+                         query, sizeof(query), OIC_RSRC_CRED_URI))
     {
         OIC_LOG(ERROR, TAG, "PostSubOwnerCredential : Failed to generate query");
         return OC_STACK_ERROR;
     }
     OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
-    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
-    if(!secPayload)
+    OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
+    if (!secPayload)
     {
         OIC_LOG(ERROR, TAG, "Failed to memory allocation");
         return OC_STACK_NO_MEMORY;
@@ -847,15 +1050,15 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
 
     //Generate sub-owner credential for new device
     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    const OicSecCred_townerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
-    if(!ownerCredential)
+    const OicSecCred_t *ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
+    if (!ownerCredential)
     {
         OIC_LOG(ERROR, TAG, "Can not find SubOwnerPSK.");
         return OC_STACK_NO_RESOURCE;
     }
 
-    OicUuid_t ownerId = {.id={0}};
-    if(OC_STACK_OK == GetDoxmDeviceID(&ownerId))
+    OicUuid_t ownerId = {.id = {0}};
+    if (OC_STACK_OK == GetDoxmDeviceID(&ownerId))
     {
         OicSecCred_t newCredential;
         memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
@@ -865,10 +1068,10 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
         memcpy(&(newCredential.subject), &ownerId, sizeof(OicUuid_t));
 
         //Set eowner ID as SubOwner's ID
-        if(NULL == newCredential.eownerID)
+        if (NULL == newCredential.eownerID)
         {
             newCredential.eownerID = OICCalloc(1, sizeof(OicUuid_t));
-            if(NULL == newCredential.eownerID)
+            if (NULL == newCredential.eownerID)
             {
                 return OC_STACK_NO_MEMORY;
             }
@@ -876,7 +1079,7 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
         memcpy(newCredential.eownerID->id, ownerId.id, sizeof(ownerId.id));
 
         //Fill private data as empty string
-        newCredential.privateData.data = (uint8_t*)"";
+        newCredential.privateData.data = (uint8_t *)"";
         newCredential.privateData.len = 0;
         newCredential.privateData.encoding = ownerCredential->privateData.encoding;
 
@@ -887,7 +1090,7 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
 #endif
         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
         if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
-                                        &secPayload->payloadSize, 0))
+                                             &secPayload->payloadSize, 0))
         {
             OICFree(secPayload);
             OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
@@ -897,11 +1100,11 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
 
         OCCallbackData cbData;
-        cbData.cb = &SubOwnerCredentialHandler;
-        cbData.context = (void *)motCtx;
+        cbData.cb = &RestoreCredCB;
+        cbData.context = ctx;
         cbData.cd = NULL;
         OCStackResult res = OCDoResource(NULL, OC_REST_POST, query,
-                                         &deviceInfo->endpoint, (OCPayload*)secPayload,
+                                         &deviceInfo->endpoint, (OCPayload *)secPayload,
                                          deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
         if (res != OC_STACK_OK)
         {
@@ -914,12 +1117,44 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
         return OC_STACK_NO_RESOURCE;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT PostSubOwnerCredentialCB");
+
+    return OC_STACK_OK;
+}
+
+static OCStackResult PostSubOwnerCredential(OTMContext_t *motCtx)
+{
+    OIC_LOG(DEBUG, TAG, "IN PostSubOwnerCredential");
+
+    if (!motCtx || !motCtx->selectedDeviceInfo)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid parameters");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    Data_t *data = NULL;
+    data = (Data_t *) OICCalloc(1, sizeof(Data_t));
+    if (!data)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+        return OC_STACK_NO_MEMORY;
+    }
+    data->type = MOT_TYPE;
+    data->ctx = motCtx;
+
+    if (SetDOS(data, DOS_RFPRO, PostSubOwnerCredentialCB) != OC_STACK_OK)
+    {
+        FreeData(data);
+        return OC_STACK_ERROR;
+    }
+
     OIC_LOG(DEBUG, TAG, "OUT PostSubOwnerCredential");
 
     return OC_STACK_OK;
 }
 
-static void MOTSessionEstablished(const CAEndpoint_t *endpoint, OicSecDoxm_t *newDevDoxm, OTMContext_t *motCtx)
+static void MOTSessionEstablished(const CAEndpoint_t *endpoint, OicSecDoxm_t *newDevDoxm,
+                                  OTMContext_t *motCtx)
 {
     OC_UNUSED(endpoint);
     OC_UNUSED(newDevDoxm);
@@ -953,7 +1188,8 @@ static void MOTSessionEstablished(const CAEndpoint_t *endpoint, OicSecDoxm_t *ne
     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
 }
 
-static void MOTSessionFailed(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info, OicSecDoxm_t *newDevDoxm, OTMContext_t *motCtx)
+static void MOTSessionFailed(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info,
+                             OicSecDoxm_t *newDevDoxm, OTMContext_t *motCtx)
 {
     OC_UNUSED(endpoint);
 
@@ -1029,32 +1265,23 @@ exit:
  */
 static void MOTDtlsHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
 {
-    OIC_LOG_V(INFO, TAG, "In %s(endpoint = %p, info = %p)", __func__, endpoint, info);
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
 
-    if (!endpoint || !info)
-    {
-        goto exit;
-    }
+    VERIFY_NOT_NULL(TAG, endpoint, ERROR);
+    VERIFY_NOT_NULL(TAG, info, ERROR);
 
     OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
               endpoint->addr, endpoint->port, info->result);
 
-    OTMContext_t* motCtx = GetOTMContext(endpoint->addr, endpoint->port);
-    if (!motCtx)
-    {
-        OIC_LOG(ERROR, TAG, "MOT context not found!");
-        goto exit;
-    }
+    OTMContext_t *motCtx = GetOTMContext(endpoint->addr, endpoint->port);
+    VERIFY_NOT_NULL(TAG, motCtx, ERROR);
 
-    OicSecDoxm_t* newDevDoxm = motCtx->selectedDeviceInfo->doxm;
-    if (!newDevDoxm)
-    {
-        OIC_LOG(ERROR, TAG, "New device doxm not found!");
-        goto exit;
-    }
+    OicSecDoxm_t *newDevDoxm = motCtx->selectedDeviceInfo->doxm;
+    VERIFY_NOT_NULL(TAG, newDevDoxm, ERROR);
 
     // Make sure the address matches.
-    if ((0 != strncmp(motCtx->selectedDeviceInfo->endpoint.addr, endpoint->addr, sizeof(endpoint->addr))) ||
+    if ((0 != strncmp(motCtx->selectedDeviceInfo->endpoint.addr, endpoint->addr,
+                      sizeof(endpoint->addr))) ||
         (motCtx->selectedDeviceInfo->securePort != endpoint->port))
     {
         OIC_LOG_V(ERROR, TAG, "Mismatched: expected address %s:%u",
@@ -1073,7 +1300,7 @@ static void MOTDtlsHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t
     }
 
 exit:
-    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
 }
 
 /**
@@ -1082,7 +1309,7 @@ exit:
  * @param  selectedDevice [IN] Device to add to the provisioning database.
  * @return OC_STACK_OK in case of success and other values otherwise.
  */
-static OCStackResult SetupMOTPDM(OCProvisionDev_tselectedDevice)
+static OCStackResult SetupMOTPDM(OCProvisionDev_t *selectedDevice)
 {
     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
 
@@ -1096,18 +1323,10 @@ static OCStackResult SetupMOTPDM(OCProvisionDev_t* selectedDevice)
     VERIFY_NOT_NULL(TAG, selectedDevice->doxm, ERROR);
 
     res = PMIsSubownerOfDevice(selectedDevice, &isSubowner);
-    if (OC_STACK_OK != res)
-    {
-        OIC_LOG_V(ERROR, TAG, "Internal error in PMIsSubownerOfDevice : %d", res);
-        return res;
-    }
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
 
     res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState);
-    if (OC_STACK_OK != res)
-    {
-        OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res);
-        return res;
-    }
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
 
     if (!OCConvertUuidToString(selectedDevice->doxm->deviceID.id, deviceId))
     {
@@ -1121,11 +1340,7 @@ static OCStackResult SetupMOTPDM(OCProvisionDev_t* selectedDevice)
         OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", deviceId);
 
         res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
-        if (OC_STACK_OK != res)
-        {
-            OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", deviceId);
-            goto exit;
-        }
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
     }
 
     // Checking duplication of Device ID.
@@ -1141,7 +1356,7 @@ static OCStackResult SetupMOTPDM(OCProvisionDev_t* selectedDevice)
         if (PDM_DEVICE_STALE == pdmState)
         {
             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
-                "device status will revert back to initial status.");
+                    "device status will revert back to initial status.");
             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
             if (OC_STACK_OK != res)
             {
@@ -1165,11 +1380,7 @@ static OCStackResult SetupMOTPDM(OCProvisionDev_t* selectedDevice)
     else
     {
         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
-        if (OC_STACK_OK != res)
-        {
-            OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res);
-            goto exit;
-        }
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
     }
 
 exit:
@@ -1177,13 +1388,13 @@ exit:
     return res;
 }
 
-static OCStackResult StartMultipleOwnershipTransfer(OTMContext_tmotCtx,
-                                                    OCProvisionDev_t* selectedDevice)
+static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t *motCtx,
+        OCProvisionDev_t *selectedDevice)
 {
-    OIC_LOG(INFO, TAG, "IN StartMultipleOwnershipTransfer");
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
 
     OCStackResult res = OC_STACK_INVALID_PARAM;
-    OicUuid_t myUuid = {.id={0}};
+    OicUuid_t myUuid = {.id = {0}};
 
     VERIFY_NOT_NULL(TAG, motCtx, ERROR);
     VERIFY_NOT_NULL(TAG, selectedDevice, ERROR);
@@ -1191,14 +1402,14 @@ static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t* motCtx,
     motCtx->selectedDeviceInfo = selectedDevice;
 
     res = GetDoxmDeviceID(&myUuid);
-    if(OC_STACK_OK != res)
+    if (OC_STACK_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Failed to GetDoxmDeviceID");
         SetMOTResult(motCtx, res);
         return res;
     }
 
-    if(memcmp(selectedDevice->doxm->owner.id, myUuid.id, sizeof(myUuid.id)) == 0)
+    if (memcmp(selectedDevice->doxm->owner.id, myUuid.id, sizeof(myUuid.id)) == 0)
     {
         res = OC_STACK_INVALID_DEVICE_INFO;
         OIC_LOG(ERROR, TAG, "Owner cannot be registered as sub-owner.");
@@ -1208,14 +1419,13 @@ static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t* motCtx,
 
     if ((NULL == selectedDevice->doxm->mom) ||
         (selectedDevice->doxm->mom &&
-        (OIC_MULTIPLE_OWNER_DISABLE == selectedDevice->doxm->mom->mode)))
+         (OIC_MULTIPLE_OWNER_DISABLE == selectedDevice->doxm->mom->mode)))
     {
         res = OC_STACK_NOT_ACCEPTABLE;
         OIC_LOG(ERROR, TAG, "MOT is disabled for the selected device.");
         SetMOTResult(motCtx, res);
         return res;
     }
-
     // Setup PDM to perform the MOT, PDM will be cleanup if necessary.
     res = SetupMOTPDM(selectedDevice);
     if (OC_STACK_OK != res)
@@ -1226,34 +1436,25 @@ static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t* motCtx,
     }
 
     // Register DTLS event handler to catch the dtls event while handshake
-    if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MOTDtlsHandshakeCB))
+    if (CA_STATUS_OK != CAregisterSslHandshakeCallback(MOTDtlsHandshakeCB))
     {
         OIC_LOG(WARNING, TAG, "StartOwnershipTransfer : Failed to register DTLS handshake callback.");
     }
 
     OicSecOxm_t oxmSel = selectedDevice->doxm->oxmSel;
-    OIC_LOG_V(DEBUG, TAG, "Multiple Ownership Transfer method = %d", (int)oxmSel);
 
-    if((OIC_PRECONFIG_PIN != oxmSel) && (OIC_RANDOM_DEVICE_PIN != oxmSel))
-    {
-        OIC_LOG(ERROR, TAG, "Unsupported OxM");
-        return OC_STACK_ERROR;
-    }
+    VERIFY_SUCCESS(TAG, 0 == MOTIsSupportedOnboardingType(selectedDevice->doxm), ERROR);
 
     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &motCtx->otmCallback);
-    if(OC_STACK_OK != res)
-    {
-        OIC_LOG_V(ERROR, TAG, "Error in OTMSetOTCallback : %d", res);
-        return res;
-    }
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
 
     // Only two functions required for MOT
     VERIFY_NOT_NULL(TAG, motCtx->otmCallback.loadSecretCB, ERROR);
     VERIFY_NOT_NULL(TAG, motCtx->otmCallback.createSecureSessionCB, ERROR);
 
-    if(OIC_RANDOM_DEVICE_PIN == oxmSel)
+    if (OIC_RANDOM_DEVICE_PIN == oxmSel)
     {
-        if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForRandomPinOxm))
+        if (CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskForRandomPinOxm))
         {
             OIC_LOG(ERROR, TAG, "Failed to register DTLS credential handler for Random PIN OxM.");
         }
@@ -1269,26 +1470,26 @@ static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t* motCtx,
     res = motCtx->otmCallback.createSecureSessionCB(motCtx);
     VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
 
-    OIC_LOG(INFO, TAG, "OUT StartMultipleOwnershipTransfer");
-
 exit:
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return res;
 }
 
-OCStackResult MOTDoOwnershipTransfer(voidctx,
+OCStackResult MOTDoOwnershipTransfer(void *ctx,
                                      OCProvisionDev_t *selectedDevicelist,
                                      OCProvisionResultCB resultCallback)
 {
-    OIC_LOG(DEBUG, TAG, "IN MOTDoOwnershipTransfer");
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     OCStackResult res = OC_STACK_INVALID_PARAM;
-    OTMContext_tmotCtx = NULL;
-    OCProvisionDev_tpCurDev = NULL;
+    OTMContext_t *motCtx = NULL;
+    OCProvisionDev_t *pCurDev = NULL;
 
     VERIFY_NOT_NULL(TAG, selectedDevicelist, ERROR);
     VERIFY_NOT_NULL(TAG, resultCallback, ERROR);
 
     res = OC_STACK_NO_MEMORY;
-    motCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t));
+    motCtx = (OTMContext_t *)OICCalloc(1, sizeof(OTMContext_t));
     VERIFY_NOT_NULL(TAG, motCtx, ERROR);
 
     motCtx->ctxResultCallback = resultCallback;
@@ -1301,7 +1502,7 @@ OCStackResult MOTDoOwnershipTransfer(void* ctx,
     }
 
     motCtx->ctxResultArray =
-        (OCProvisionResult_t*)OICCalloc(motCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
+        (OCProvisionResult_t *)OICCalloc(motCtx->ctxResultArraySize, sizeof(OCProvisionResult_t));
     VERIFY_NOT_NULL(TAG, motCtx->ctxResultArray, ERROR);
 
     //Fill the device UUID for result array.
@@ -1319,16 +1520,21 @@ OCStackResult MOTDoOwnershipTransfer(void* ctx,
     motCtx->selectedDeviceInfo = selectedDevicelist;
     res = StartMultipleOwnershipTransfer(motCtx, selectedDevicelist);
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTDoOwnershipTransfer");
-    return res;
 exit:
-    if(OC_STACK_OK != res)
+    if (OC_STACK_OK != res)
     {
-        if(motCtx)
+        if (motCtx)
         {
             OICFree(motCtx->ctxResultArray);
             OICFree(motCtx);
         }
     }
+    else
+    {
+        OIC_LOG_V(DEBUG, TAG, "%s: otm ok", __func__);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
     return res;
 }
index f382da3..3f9fde8 100644 (file)
@@ -1294,6 +1294,7 @@ OCStackResult PMSingleDeviceDiscoveryInUnicast(unsigned short waittime, const Oi
 #ifdef MULTIPLE_OWNER
 
 static const unsigned int IOTIVITY_USECS_PER_MSEC = 1000;
+extern int MOTIsSupportedOnboardingType(OicSecDoxm_t *ptrDoxm);
 
 static OCStackApplicationResult MOTDeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                 OCClientResponse *clientResponse)
index f2c4232..d842950 100644 (file)
 
 trustCertChainContext_t g_trustCertChainNotifier;
 
-// Enum type index for data types.
-typedef enum
-{
-    CHAIN_TYPE = 0,                       /**< Certificate trust chain.**/
-    ACL_TYPE,                             /**< Access control list.**/
-    PSK_TYPE,                             /**< Pre-Shared Key.**/
-    CERT_TYPE                             /**< X.509 certificate.**/
-} DataType_t;
-
-/**
- * Structure to carry general data to callback.
- */
-typedef struct Data
-{
-    void *ctx;                                   /**< Pointer to user context.**/
-    DataType_t type;                             /**< Data type of the context.**/
-} Data_t;
-
 /**
  * Structure to carry credential data to callback.
  */
@@ -224,8 +206,6 @@ static OCStackResult provisionCredentials(OicSecCred_t *cred,
         OCClientResponseHandler responseHandler);
 static OCStackApplicationResult  ProvisionPskCB(void *ctx, OCDoHandle UNUSED,
         OCClientResponse *clientResponse);
-static OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t dos,
-                            OCClientResponseHandler resultCallback);
 
 typedef enum {
     DEVICE_1_FINISHED,
@@ -238,7 +218,7 @@ typedef enum {
  *
  * @param[in] data    Pointer to block of memory previously allocated for Data_t.
  */
-static void FreeData(Data_t *data)
+void FreeData(Data_t *data)
 {
     if(NULL == data)
     {
@@ -276,16 +256,22 @@ static void FreeData(Data_t *data)
             }
         case CERT_TYPE:
             {
-                CertData_t *certData = (CertData_t *)data->ctx;
+                CertData_t *certData = (CertData_t *) data->ctx;
                 if (NULL != certData->resArr)
                 {
                      OICFreeAndSetToNull((void**)&certData->resArr);
                 }
                 FreeCred(certData->credInfo);
-
                 OICFreeAndSetToNull((void**)&certData);
                 break;
             }
+        case MOT_TYPE:
+            {
+                OTMContext_t *motData = (OTMContext_t *) data->ctx;
+                OICFree(motData->ctxResultArray);
+                OICFree(motData);
+                break;
+            }
         default:
             {
                 OIC_LOG_V(INFO, TAG, "Unknown type %d", data->type);
@@ -820,10 +806,7 @@ static OCStackApplicationResult SetReadyForNormalOperationCB(void *ctx, OCDoHand
     return OC_STACK_DELETE_TRANSACTION;
 }
 
-/**
- * Updates pstat resource of server.
- */
-static OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t dos,
+OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t dos,
                             OCClientResponseHandler resultCallback)
 {
     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
@@ -834,7 +817,6 @@ static OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t do
         return OC_STACK_INVALID_PARAM;
     }
 
-
     const OCProvisionDev_t *pTargetDev = NULL;
 
     switch (data->type)
@@ -860,6 +842,11 @@ static OCStackResult SetDOS(const Data_t *data, OicSecDeviceOnboardingState_t do
             pTargetDev = ((CertData_t *)data->ctx)->targetDev;
             break;
         }
+        case MOT_TYPE:
+        {
+            pTargetDev = ((OTMContext_t *)data->ctx)->selectedDeviceInfo;
+            break;
+        }
         default:
         {
             OIC_LOG_V(ERROR, TAG, "Unknown type: %d", data->type);
index 7f23048..c9dccd0 100644 (file)
@@ -106,7 +106,11 @@ static const uint8_t gDoxmPropertyAccessModes[DOXM_PROPERTY_COUNT][DOS_STATE_COU
 { // RESET RFOTM  RFPRO   RFNOP   SRESET
     { R,    R,      R,      R,      R   }, // .oxmtype TODO [IOT-2105]
     { R,    R,      R,      R,      R   }, // .oxms
+#ifdef MULTIPLE_OWNER
+    { R,    RW,     RW,     R,      R   }, // .oxmsel
+#else
     { R,    RW,     R,      R,      R   }, // .oxmsel
+#endif // MULTIPLE_OWNER
     { R,    R,      R,      R,      R   }, // .sct
     { R,    RW,     R,      R,      R   }, // .owned
 #ifdef MULTIPLE_OWNER