replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / provisioning / src / OCProvisioningManager.cpp
index 8a2c076..3c18238 100644 (file)
@@ -21,7 +21,9 @@
 #include "ocstack.h"
 #include "srmutility.h"
 #include "base64.h"
-#include "OCProvisioningManager.h"
+#include "OCProvisioningManager.hpp"
+#include "mbedtls/x509_crt.h"
+
 
 namespace OC
 {
@@ -30,7 +32,7 @@ namespace OC
         OCStackResult result;
         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCInitPM(dbPath.c_str());
@@ -44,6 +46,23 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecure::terminatePM()
+    {
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCTerminatePM();
+            return OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            return OC_STACK_ERROR;
+        }
+    }
+
     OCStackResult OCSecure::discoverUnownedDevices(unsigned short timeout,
             DeviceList_t &list)
     {
@@ -52,7 +71,7 @@ namespace OC
         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
         auto cLock = csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCDiscoverUnownedDevices(timeout, &pDevList);
@@ -91,7 +110,7 @@ namespace OC
         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
         auto cLock = csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCDiscoverOwnedDevices(timeout, &pDevList);
@@ -121,31 +140,116 @@ namespace OC
         return result;
     }
 
-    OCStackResult OCSecure::setOwnerTransferCallbackData(OicSecOxm_t oxm,
-            OTMCallbackData_t* callbackData, InputPinCallback inputPin)
+    OCStackResult OCSecure::discoverSingleDevice(unsigned short timeout,
+            const OicUuid_t* deviceID,
+            std::shared_ptr<OCSecureResource> &foundDevice)
     {
-        if(NULL == callbackData || oxm >= OIC_OXM_COUNT)
+        OCStackResult result;
+        OCProvisionDev_t *pDev = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
+
+        if (cLock)
         {
-            oclog() <<"Invalid callbackData or OXM type";
-            return OC_STACK_INVALID_PARAM;
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDiscoverSingleDevice(timeout, deviceID, &pDev);
+            if (result == OC_STACK_OK)
+            {
+                if (pDev)
+                {
+                    foundDevice.reset(new OCSecureResource(csdkLock, pDev));
+                }
+                else
+                {
+                    oclog() <<"Not found Secure resource!";
+                    foundDevice.reset();
+                }
+            }
+            else
+            {
+                oclog() <<"Secure resource discovery failed!";
+            }
         }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+    OCStackResult OCSecure::discoverSingleDeviceInUnicast(unsigned short timeout,
+            const OicUuid_t* deviceID,
+            const std::string& hostAddress,
+            OCConnectivityType connType,
+            std::shared_ptr<OCSecureResource> &foundDevice)
+    {
+        OCStackResult result = OC_STACK_ERROR;
+        OCProvisionDev_t *pDev = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
 
-        if((OIC_RANDOM_DEVICE_PIN == oxm) && !inputPin)
+        if (cLock)
         {
-            oclog() <<"for OXM type DEVICE_PIN, inputPin callback can't be null";
-            return OC_STACK_INVALID_PARAM;
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDiscoverSingleDeviceInUnicast(timeout, deviceID, hostAddress.c_str(),
+                            connType, &pDev);
+
+            if (result == OC_STACK_OK)
+            {
+                if (pDev)
+                {
+                    foundDevice.reset(new OCSecureResource(csdkLock, pDev));
+                }
+                else
+                {
+                    oclog() <<"Not found Secure resource!";
+                    foundDevice.reset();
+                }
+            }
+            else
+            {
+                oclog() <<"Secure resource discovery failed!";
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
         }
 
+        return result;
+    }
+
+#ifdef MULTIPLE_OWNER
+    OCStackResult OCSecure::discoverMultipleOwnerEnabledDevices(unsigned short timeout,
+            DeviceList_t &list)
+    {
         OCStackResult result;
-        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCSetOwnerTransferCallbackData(oxm, callbackData);
-            if(result == OC_STACK_OK && (OIC_RANDOM_DEVICE_PIN == oxm))
+            result = OCDiscoverMultipleOwnerEnabledDevices(timeout, &pDevList);
+            if (result == OC_STACK_OK)
             {
-                SetInputPinCB(inputPin);
+                pCurDev = pDevList;
+                while (pCurDev)
+                {
+                    tmp = pCurDev;
+                    list.push_back(std::shared_ptr<OCSecureResource>(
+                                new OCSecureResource(csdkLock, pCurDev)));
+                    pCurDev = pCurDev->next;
+                    tmp->next = nullptr;
+                }
+            }
+            else
+            {
+                oclog() <<"MultipleOwner Enabled device discovery failed!";
             }
         }
         else
@@ -155,7 +259,104 @@ namespace OC
         }
 
         return result;
+    }
+
+    OCStackResult OCSecure::discoverMultipleOwnedDevices(unsigned short timeout,
+            DeviceList_t &list)
+    {
+        OCStackResult result;
+        OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDiscoverMultipleOwnedDevices(timeout, &pDevList);
+            if (result == OC_STACK_OK)
+            {
+                pCurDev = pDevList;
+                while (pCurDev)
+                {
+                    tmp = pCurDev;
+                    list.push_back(std::shared_ptr<OCSecureResource>(
+                                new OCSecureResource(csdkLock, pCurDev)));
+                    pCurDev = pCurDev->next;
+                    tmp->next = nullptr;
+                }
+            }
+            else
+            {
+                oclog() <<"Multiple Owned device discovery failed!";
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
 
+        return result;
+    }
+
+#endif
+    OCStackResult OCSecure::setInputPinCallback(InputPinCallback inputPin)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetInputPinCB(inputPin);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+
+    OCStackResult OCSecure::unsetInputPinCallback()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            UnsetInputPinCB();
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+    OCStackResult OCSecure::setRandomPinPolicy(size_t pinSize, OicSecPinType_t pinType)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = SetRandomPinPolicy(pinSize, pinType);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
     }
 
     OCStackResult OCSecure::getDevInfoFromNetwork(unsigned short timeout,
@@ -167,7 +368,7 @@ namespace OC
         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
         auto cLock = csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
 
@@ -207,7 +408,7 @@ namespace OC
 
     OCStackResult OCSecure::setDisplayPinCB(GeneratePinCallback displayPin)
     {
-        if(!displayPin)
+        if (!displayPin)
         {
             oclog() <<"displayPin can't be null";
             return OC_STACK_INVALID_PARAM;
@@ -216,7 +417,7 @@ namespace OC
         OCStackResult result = OC_STACK_OK;
         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             SetGeneratePinCB(displayPin);
@@ -230,6 +431,456 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecure::removeDeviceWithUuid(unsigned short waitTimeForOwnedDeviceDiscovery,
+            std::string uuid,
+            ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() << "Result calback can't be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+
+            OicUuid_t targetDev;
+            result = ConvertStrToUuid(uuid.c_str(), &targetDev);
+            if(OC_STACK_OK == result)
+            {
+                result = OCRemoveDeviceWithUuid(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
+                        &targetDev, &OCSecureResource::callbackWrapper);
+            }
+            else
+            {
+                oclog() <<"Can not convert struuid to uuid";
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::saveACL(const OicSecAcl_t* acl)
+    {
+        if (!acl)
+        {
+            oclog() <<"ACL can't be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSaveACL(const_cast<OicSecAcl_t*>(acl));
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::displayNumCallbackWrapper(void* ctx,
+            uint8_t verifNum[MUTUAL_VERIF_NUM_LEN])
+    {
+        uint8_t *number = NULL;
+
+        DisplayNumContext* context = static_cast<DisplayNumContext*>(ctx);
+        if (!context)
+        {
+            oclog() << "Invalid context";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        if (NULL != verifNum) {
+            number = new uint8_t[MUTUAL_VERIF_NUM_LEN];
+            memcpy(number, verifNum, MUTUAL_VERIF_NUM_LEN);
+        }
+
+        return context->callback(number);
+    }
+
+    OCStackResult OCSecure::registerDisplayNumCallback(DisplayNumCB displayNumCB)
+    {
+        if(!displayNumCB)
+        {
+            oclog() << "Failed to register callback for display.";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result = OCSecure::deregisterDisplayNumCallback();
+        if (OC_STACK_OK != result)
+        {
+            oclog() << "Failed to de-register callback for display."<<std::endl;
+            return result;
+        }
+
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            DisplayNumContext* context = new DisplayNumContext(displayNumCB);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetDisplayNumCB(static_cast<void*>(context), &OCSecure::displayNumCallbackWrapper);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::deregisterDisplayNumCallback()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            DisplayNumContext* context = static_cast<DisplayNumContext*>(UnsetDisplayNumCB());
+            if (context)
+            {
+                oclog() << "Delete registered display num context"<<std::endl;
+                delete context;
+            }
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::confirmUserCallbackWrapper(void* ctx)
+    {
+        UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(ctx);
+        if (!context)
+        {
+            oclog() << "Invalid context";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        return context->callback();
+    }
+
+    OCStackResult OCSecure::registerUserConfirmCallback(UserConfirmNumCB userConfirmCB)
+    {
+        if(!userConfirmCB)
+        {
+            oclog() << "Failed to set callback for confirming verifying callback.";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result = OCSecure::deregisterUserConfirmCallback();
+        if (OC_STACK_OK != result)
+        {
+            oclog() << "Failed to de-register callback for comfirm."<<std::endl;
+            return result;
+        }
+
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            UserConfirmNumContext* context = new UserConfirmNumContext(userConfirmCB);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetUserConfirmCB(static_cast<void*>(context), &OCSecure::confirmUserCallbackWrapper);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::deregisterUserConfirmCallback()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(UnsetUserConfirmCB());
+            if (context)
+            {
+                oclog() << "Delete registered user confirm context"<<std::endl;
+                delete context;
+            }
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::setVerifyOptionMask(VerifyOptionBitmask_t optionMask)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetVerifyOption(optionMask);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::pdmCleanupForTimeout()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            result = OCPDMCleanupForTimeout();
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::configSelfOwnership()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCConfigSelfOwnership();
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
+                                        OicEncodingType_t encodingType, uint16_t *credId)
+    {
+        if (!trustCertChain)
+        {
+            oclog() <<"trustCertChain can't be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (!credId)
+        {
+            oclog() <<"cred ID can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId );
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::readTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
+            size_t *chainSize)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCReadTrustCertChain(credId, trustCertChain, chainSize);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    void OCSecure::certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain,
+            size_t chainSize)
+    {
+        TrustCertChainContext* context = static_cast<TrustCertChainContext*>(ctx);
+        uint8_t *certChain = new uint8_t[chainSize];
+        memcpy(certChain, trustCertChain, chainSize);
+        std::thread exec(context->callback, credId, certChain, chainSize);
+        exec.detach();
+        delete context;
+    }
+
+    OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback)
+    {
+        if (!callback)
+        {
+            oclog() <<"callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            TrustCertChainContext* context = new TrustCertChainContext(callback);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCRegisterTrustCertChainNotifier(static_cast<void*>(context),
+                    &OCSecure::certCallbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+
+    OCStackResult OCSecure::removeTrustCertChangeNotifier()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCRemoveTrustCertChainNotifier();
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::setDeviceIdSeed(const uint8_t* seed, size_t seedSize)
+    {
+        if (!seed)
+        {
+            oclog() <<"seed can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = SetDeviceIdSeed(seed, seedSize);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    int OCSecure::peerCertCallbackWrapper(void *ctx, const mbedtls_x509_crt *cert,
+            int depth)
+    {
+        OCStackResult ret = OC_STACK_ERROR;
+
+        PeerCertContext *context = static_cast<PeerCertContext*>(ctx);
+        if (NULL == context)
+        {
+            oclog() << "Invalid Context";
+            return 1;
+        }
+
+        if (context->callback)
+        {
+            ret = context->callback(cert, depth);
+        }
+
+        if (0 == depth)
+        {
+            delete context;
+        }
+
+        return (OC_STACK_OK == ret)? 0 : 1;
+    }
+
+    OCStackResult OCSecure::setPeerCertCallback(PeerCertCB peerCertCallback)
+    {
+        OCStackResult result;
+        // UNSET cb
+        if (NULL == peerCertCallback)
+        {
+            result = OCSetPeerCertCallback(NULL, NULL);
+            if (OC_STACK_OK != result)
+            {
+                oclog() << "OCSetPeerCertCallback() Failed";
+                return result;
+            }
+        }
+
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            PeerCertContext *context = new PeerCertContext(peerCertCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSetPeerCertCallback(static_cast<void*>(context),
+                    &OCSecure::peerCertCallbackWrapper);
+            if (OC_STACK_OK != result)
+            {
+                oclog() << "OCSetPeerCertCallback() Failed";
+            }
+        }
+        else
+        {
+            oclog() << "Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+#endif // __WITH_DTLS__ || __WITH_TLS__
+
     void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
     {
         PMResultList_t *results = nullptr;
@@ -261,23 +912,51 @@ namespace OC
     {
     }
 
-    OCSecureResource::OCSecureResource(std::weak_ptr<std::recursive_mutex> csdkLock,
-            OCProvisionDev_t *dPtr)
-        :m_csdkLock(csdkLock), devPtr(dPtr)
-    {
-    }
+    OCSecureResource::OCSecureResource(std::weak_ptr<std::recursive_mutex> csdkLock,
+            OCProvisionDev_t *dPtr)
+        :m_csdkLock(csdkLock), devPtr(dPtr)
+    {
+    }
+
+    OCSecureResource::~OCSecureResource()
+    {
+        if (devPtr)
+        {
+            OCDeleteDiscoveredDevices(devPtr);
+        }
+    }
+
+    OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"Result callback can't be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
 
-    OCSecureResource::~OCSecureResource()
-    {
-        if(devPtr)
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDoOwnershipTransfer(static_cast<void*>(context),
+                    devPtr, &OCSecureResource::callbackWrapper);
+        }
+        else
         {
-            OCDeleteDiscoveredDevices(devPtr);
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
         }
+        return result;
     }
 
-    OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback)
+#ifdef MULTIPLE_OWNER
+    OCStackResult OCSecureResource::doMultipleOwnershipTransfer(ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() <<"Result callback can't be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -286,12 +965,12 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCDoOwnershipTransfer(static_cast<void*>(context),
+            result = OCDoMultipleOwnershipTransfer(static_cast<void*>(context),
                     devPtr, &OCSecureResource::callbackWrapper);
         }
         else
@@ -302,15 +981,27 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecureResource::getSubOwnerList(UuidList_t &uuidList)
+    {
+        validateSecureResource();
+        OicSecSubOwner_t* tmp = NULL;
+        for (tmp = devPtr->doxm->subOwners; tmp; tmp = tmp->next)
+        {
+            uuidList.push_back(tmp->uuid);
+        }
+        return OC_STACK_OK;
+    }
+
+#endif
     OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
             ResultCallBack resultCallback)
     {
-        if(!acl)
+        if (!acl)
         {
             oclog() <<"ACL can't be null";
             return OC_STACK_INVALID_PARAM;
         }
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() <<"result callback can not be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -319,7 +1010,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -339,7 +1030,7 @@ namespace OC
     OCStackResult OCSecureResource::provisionCredentials(const Credential &cred,
             const OCSecureResource &device2, ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() << "Result calback can't be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -348,7 +1039,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -371,7 +1062,7 @@ namespace OC
             const OicSecAcl_t* acl1, const OCSecureResource &device2, const OicSecAcl_t* acl2,
             ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() << "Result callback can not be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -380,7 +1071,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -403,7 +1094,7 @@ namespace OC
     OCStackResult OCSecureResource::unlinkDevices(const OCSecureResource &device2,
             ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() << "Result calback can't be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -412,7 +1103,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -432,7 +1123,7 @@ namespace OC
     OCStackResult OCSecureResource::removeDevice(unsigned short waitTimeForOwnedDeviceDiscovery,
             ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() << "Result calback can't be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -441,7 +1132,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -465,7 +1156,7 @@ namespace OC
         auto devUuid = devPtr->doxm->deviceID;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
 
@@ -488,6 +1179,76 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecureResource::provisionDirectPairing( const OicSecPconf_t* pconf,
+            ResultCallBack resultCallback)
+    {
+        if (!pconf)
+        {
+            oclog() <<"PCONF can't be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCProvisionDirectPairing(static_cast<void*>(context),
+                    devPtr, const_cast<OicSecPconf_t*>(pconf),
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    OCStackResult OCSecureResource::provisionTrustCertChain(OicSecCredType_t type, uint16_t credId,
+                    ResultCallBack resultCallback)
+    {
+        if (SIGNED_ASYMMETRIC_KEY != type)
+        {
+            oclog() <<"Invalid key type";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCProvisionTrustCertChain(static_cast<void*>(context),
+                    type, credId, devPtr,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
     std::string OCSecureResource::getDeviceID()
     {
         std::ostringstream deviceId("");
@@ -498,6 +1259,7 @@ namespace OC
         if (OC_STACK_OK == ConvertUuidToStr(&(devPtr->doxm->deviceID), &devID))
         {
             deviceId << devID;
+            free(devID);
         }
         else
         {
@@ -537,4 +1299,247 @@ namespace OC
             throw OCException("Incomplete secure resource", OC_STACK_RESOURCE_ERROR);
         }
     }
+
+    OCStackResult OCSecureResource::getOTMethod(OicSecOxm_t* oxm)
+    {
+        if(!oxm)
+        {
+            oclog() << "Null param";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            if(devPtr && devPtr->doxm)
+            {
+                result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
+                                                  oxm, SUPER_OWNER);
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+        }
+        return result;
+    }
+
+
+#ifdef MULTIPLE_OWNER
+    OCStackResult OCSecureResource::getMOTMethod( OicSecOxm_t* oxm)
+    {
+        if (!oxm)
+        {
+            oclog() << "Null param";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            if (devPtr && devPtr->doxm)
+            {
+                result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
+                                                  oxm, SUB_OWNER);
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+        }
+        return result;
+    }
+
+    bool OCSecureResource::isMOTSupported()
+    {
+        if (devPtr && devPtr->doxm)
+        {
+            return (devPtr->doxm->mom ? true : false);
+        }
+        return false;
+    }
+
+    bool OCSecureResource::isMOTEnabled()
+    {
+        if (devPtr && devPtr->doxm && devPtr->doxm->mom)
+        {
+            if (OIC_MULTIPLE_OWNER_DISABLE != devPtr->doxm->mom->mode)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    OCStackResult OCSecureResource::selectMOTMethod( const OicSecOxm_t oxmSelVal,
+            ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSelectMOTMethod(static_cast<void*>(context),
+                    devPtr, oxmSelVal,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::changeMOTMode( const OicSecMomType_t momType,
+            ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCChangeMOTMode(static_cast<void*>(context),
+                    devPtr, momType,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+
+    OCStackResult OCSecureResource::addPreconfigPIN(const char* preconfPIN,
+            size_t preconfPINLength)
+    {
+        if (!preconfPIN)
+        {
+            oclog() <<"pre config pin can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (preconfPINLength <= 0)
+        {
+            oclog() <<"pre config pin length can not be zero or less";
+            return OC_STACK_INVALID_PARAM;
+        }
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCAddPreconfigPin(devPtr, preconfPIN,
+                    preconfPINLength);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::provisionPreconfPin(const char * preconfPin,
+            size_t preconfPinLength, ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+        if (!preconfPin)
+        {
+            oclog() <<"pre config pin can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (preconfPinLength <= 0)
+        {
+            oclog() <<"pre config pin length can not be zero or less";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCProvisionPreconfigPin(static_cast<void*>(context),
+                    devPtr, preconfPin, preconfPinLength,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::removeSubOwner(const OicUuid_t* subOwnerId, ResultCallBack resultCallback)
+    {
+        validateSecureResource();
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+            result = OCRemoveSubOwner(static_cast<void*>(context),
+                devPtr, subOwnerId, &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() << "Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::removeAllSubOwner(ResultCallBack resultCallback)
+    {
+        validateSecureResource();
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+            result =OCRemoveAllSubOwner(static_cast<void*>(context),
+                devPtr, &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() << "Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+#endif // MULTIPLE_OWNER
 }