Svace issues fixed
[platform/upstream/iotivity.git] / resource / csdk / security / src / directpairing.c
index e9525ff..387df18 100644 (file)
-/* *****************************************************************\r
- *\r
- * Copyright 2016 Samsung Electronics All Rights Reserved.\r
- *\r
- *\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * *****************************************************************/\r
-#ifndef _POSIX_C_SOURCE\r
-#define _POSIX_C_SOURCE 200112L\r
-#endif\r
-\r
-#ifndef WITH_ARDUINO\r
-#include <unistd.h>\r
-#include <string.h>\r
-#include <time.h>\r
-#include <sys/time.h>\r
-#endif\r
-#include <string.h>\r
-\r
-#include "ocstack.h"\r
-#include "oic_malloc.h"\r
-#include "oic_string.h"\r
-#include "logger.h"\r
-#include "cJSON.h"\r
-#include "utlist.h"\r
-#include "ocpayload.h"\r
-#include "payload_logging.h"\r
-#include "cainterface.h"\r
-\r
-#include "directpairing.h"\r
-#include "srmresourcestrings.h" //@note: SRM's internal header\r
-#include "doxmresource.h"       //@note: SRM's internal header\r
-#include "pconfresource.h"       //@note: SRM's internal header\r
-#include "dpairingresource.h"       //@note: SRM's internal header\r
-#include "credresource.h"\r
-\r
-#include "pmtypes.h"\r
-#include "pmutility.h"\r
-\r
-#include "srmutility.h"\r
-\r
-#ifdef __WITH_DTLS__\r
-#include "global.h"\r
-#endif\r
-\r
-\r
-#define TAG ("DP")\r
-\r
-/**\r
- * Structure to carry direct-pairing API data to callback.\r
- */\r
-typedef struct DPairData\r
-{\r
-    OCDirectPairingDev_t        *peer;                         /**< Pointer to pairing target info.**/\r
-    char                                  pin[DP_PIN_LENGTH];  /**< PIN **/\r
-    OCDirectPairingResultCB    resultCallback;           /**< Pointer to result callback.**/\r
-} DPairData_t;\r
-\r
-static OCDirectPairingDev_t *g_dp_paired = NULL;\r
-static OCDirectPairingDev_t *g_dp_discover = NULL;\r
-static DPairData_t *g_dp_proceed_ctx = NULL;\r
-\r
-/**\r
- * Function to search node in linked list that matches given IP and port.\r
- *\r
- * @param[in] pList         List of OCProvisionDev_t.\r
- * @param[in] addr          address of target device.\r
- * @param[in] port          port of remote server.\r
- *\r
- * @return pointer of OCProvisionDev_t if exist, otherwise NULL\r
- */\r
-OCDirectPairingDev_t* getDev(OCDirectPairingDev_t **ppList, const char* addr, const uint16_t port)\r
-{\r
-    if(NULL == addr)\r
-    {\r
-        OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);\r
-        return NULL;\r
-    }\r
-\r
-    OCDirectPairingDev_t *ptr = NULL;\r
-    LL_FOREACH(*ppList, ptr)\r
-    {\r
-        if( strcmp(ptr->endpoint.addr, addr) == 0 && port == ptr->endpoint.port)\r
-        {\r
-            return ptr;\r
-        }\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-\r
-\r
-/**\r
- * Add device information to list.\r
- *\r
- * @param[in] pList         List of OCProvisionDev_t.\r
- * @param[in] addr          address of target device.\r
- * @param[in] port          port of remote server.\r
- * @param[in] adapter       adapter type of endpoint.\r
- * @param[in] doxm          pointer to doxm instance.\r
- * @param[in] connType  connectivity type of endpoint\r
- *\r
- * @return OC_STACK_OK for success and errorcode otherwise.\r
- */\r
-OCStackResult addDev(OCDirectPairingDev_t **ppList, OCDevAddr *endpoint,\r
-                                      OCConnectivityType conn, OicSecPconf_t *pconf)\r
-{\r
-    if(NULL == endpoint || NULL == pconf)\r
-    {\r
-        OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);\r
-        return OC_STACK_INVALID_PARAM;\r
-    }\r
-\r
-    OCDirectPairingDev_t *ptr = getDev(ppList, endpoint->addr, endpoint->port);\r
-    if(!ptr)\r
-    {\r
-        ptr = (OCDirectPairingDev_t *)OICCalloc(1, sizeof (OCDirectPairingDev_t));\r
-        if (NULL == ptr)\r
-        {\r
-            OIC_LOG(ERROR, TAG, "Error while allocating memory for linkedlist node !!");\r
-            return OC_STACK_NO_MEMORY;\r
-        }\r
-\r
-        memcpy(&ptr->endpoint, endpoint, sizeof(OCDevAddr));\r
-        ptr->connType = conn;\r
-        ptr->securePort = DEFAULT_SECURE_PORT;\r
-        ptr->edp = pconf->edp;\r
-        ptr->prm = pconf->prm;\r
-        pconf->prm = NULL;  // to prevent free\r
-        ptr->prmLen = pconf->prmLen;\r
-        memcpy(&ptr->deviceID, &pconf->deviceID, sizeof(OicUuid_t));\r
-        memcpy(&ptr->rowner, &pconf->rowner, sizeof(OicUuid_t));\r
-        ptr->next = NULL;\r
-\r
-        LL_PREPEND(*ppList, ptr);\r
-        OIC_LOG(INFO, TAG, "device added !");\r
-    }\r
-\r
-    return OC_STACK_OK;\r
-}\r
-\r
-\r
-/**\r
- * Add device information to list.\r
- *\r
- * @param[in] ppList         List of OCProvisionDev_t.\r
- * @param[in] pDev          target device.\r
- *\r
- * @return OC_STACK_OK for success and errorcode otherwise.\r
- */\r
-OCStackResult addDev2(OCDirectPairingDev_t **ppList, OCDirectPairingDev_t *pDev)\r
-{\r
-    if(NULL == pDev)\r
-    {\r
-        OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);\r
-        return OC_STACK_INVALID_PARAM;\r
-    }\r
-\r
-    OCDirectPairingDev_t *ptr = getDev(ppList, pDev->endpoint.addr, pDev->endpoint.port);\r
-    if(!ptr)\r
-    {\r
-        ptr = (OCDirectPairingDev_t *)OICCalloc(1, sizeof (OCDirectPairingDev_t));\r
-        if (NULL == ptr)\r
-        {\r
-            OIC_LOG(ERROR, TAG, "Error while allocating memory for linkedlist node !!");\r
-            return OC_STACK_NO_MEMORY;\r
-        }\r
-\r
-        memcpy(&ptr->endpoint, &pDev->endpoint, sizeof(OCDevAddr));\r
-        ptr->connType = pDev->connType;\r
-        ptr->securePort = pDev->securePort;\r
-        ptr->edp = pDev->edp;\r
-        ptr->prmLen = pDev->prmLen;\r
-        ptr->prm = (OicSecPrm_t*)OICCalloc(ptr->prmLen, sizeof (OicSecPrm_t));\r
-        if (NULL == ptr->prm)\r
-        {\r
-            OIC_LOG(ERROR, TAG, "Error while allocating memory for prm !!");\r
-            return OC_STACK_NO_MEMORY;\r
-        }\r
-        memcpy(ptr->prm, pDev->prm, sizeof(OicSecPrm_t)*ptr->prmLen);\r
-        memcpy(&ptr->deviceID, &pDev->deviceID, sizeof(OicUuid_t));\r
-        memcpy(&ptr->rowner, &pDev->rowner, sizeof(OicUuid_t));\r
-        ptr->next = NULL;\r
-\r
-        LL_PREPEND(*ppList, ptr);\r
-        OIC_LOG(INFO, TAG, "device added !");\r
-    }\r
-\r
-    return OC_STACK_OK;\r
-}\r
-\r
-\r
-\r
-/**\r
- * This function deletes list of provision target devices\r
- *\r
- * @param[in] pDevicesList         List of OCProvisionDev_t.\r
- */\r
-void delList(OCDirectPairingDev_t *pList)\r
-{\r
-    if(pList)\r
-    {\r
-        OCDirectPairingDev_t *del = NULL, *tmp = NULL;\r
-        LL_FOREACH_SAFE(pList, del, tmp)\r
-        {\r
-            LL_DELETE(pList, del);\r
-            if (del && del->prm)\r
-            {\r
-                OICFree(del->prm);\r
-            }\r
-        }\r
-    }\r
-}\r
-\r
-bool DPGenerateQuery(bool isSecure,\r
-                     const char* address, const uint16_t port,\r
-                     const OCConnectivityType connType,\r
-                     char* buffer, size_t bufferSize, const char* uri)\r
-{\r
-    if(!address || !buffer || !uri)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "DPGenerateQuery : Invalid parameters.");\r
-        return false;\r
-    }\r
-\r
-    static char QPREFIX_COAP[] =  "coap://";\r
-    static char QPREFIX_COAPS[] = "coaps://";\r
-\r
-    int snRet = 0;\r
-    char* prefix = (isSecure == true) ? QPREFIX_COAPS : QPREFIX_COAP;\r
-\r
-    switch(connType & CT_MASK_ADAPTER)\r
-    {\r
-        case CT_ADAPTER_IP:\r
-            switch(connType & CT_MASK_FLAGS & ~CT_FLAG_SECURE)\r
-            {\r
-                case CT_IP_USE_V4:\r
-                        snRet = snprintf(buffer, bufferSize, "%s%s:%d%s",\r
-                                         prefix, address, port, uri);\r
-                    break;\r
-                case CT_IP_USE_V6:\r
-                        snRet = snprintf(buffer, bufferSize, "%s[%s]:%d%s",\r
-                                         prefix, address, port, uri);\r
-                    break;\r
-                default:\r
-                    OIC_LOG(ERROR, TAG, "Unknown address format.");\r
-                    return false;\r
-            }\r
-            // snprintf return value check\r
-            if (snRet < 0)\r
-            {\r
-                OIC_LOG_V(ERROR, TAG, "DPGenerateQuery : Error (snprintf) %d\n", snRet);\r
-                return false;\r
-            }\r
-            else if ((size_t)snRet >= bufferSize)\r
-            {\r
-                OIC_LOG_V(ERROR, TAG, "DPGenerateQuery : Truncated (snprintf) %d\n", snRet);\r
-                return false;\r
-            }\r
-\r
-            break;\r
-#ifndef WITH_ARDUINO\r
-        // TODO: We need to verify tinyDTLS in below cases\r
-        case CT_ADAPTER_GATT_BTLE:\r
-        case CT_ADAPTER_RFCOMM_BTEDR:\r
-            OIC_LOG(ERROR, TAG, "Not supported connectivity adapter.");\r
-            return false;\r
-            break;\r
-#endif\r
-        default:\r
-            OIC_LOG(ERROR, TAG, "Unknown connectivity adapter.");\r
-            return false;\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-const OCDirectPairingDev_t* DPGetDiscoveredDevices()\r
-{\r
-    return g_dp_discover;\r
-}\r
-\r
-const OCDirectPairingDev_t* DPGetPairedDevices()\r
-{\r
-    return g_dp_paired;\r
-}\r
-\r
-void DPDeleteLists()\r
-{\r
-    delList(g_dp_discover);\r
-    delList(g_dp_paired);\r
-}\r
-\r
-/**\r
- * Callback handler of FinalizeDirectPairing.\r
- *\r
- * @param[in] ctx             ctx value passed to callback from calling function.\r
- * @param[in] UNUSED          handle to an invocation\r
- * @param[in] clientResponse  Response from queries to remote servers.\r
- * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction\r
- *          and  OC_STACK_KEEP_TRANSACTION to keep it.\r
- */\r
-static OCStackApplicationResult DirectPairingFinalizeHandler(void *ctx, OCDoHandle UNUSED,\r
-                                                  OCClientResponse *clientResponse)\r
-{\r
-    OIC_LOG_V(INFO, TAG, "IN DirectPairingFinalizeHandler()");\r
-    (void)UNUSED;\r
-    if(NULL == ctx)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "Context is Null");\r
-        return OC_STACK_DELETE_TRANSACTION;\r
-    }\r
-\r
-    OCStackResult res;\r
-    DPairData_t *dpairData = (DPairData_t*)ctx;\r
-    OCDirectPairingDev_t *peer = dpairData->peer;\r
-    OCDirectPairingResultCB resultCallback = dpairData->resultCallback;\r
-\r
-    if (clientResponse)\r
-    {\r
-        if(OC_STACK_OK == clientResponse->result)\r
-        {\r
-            // result\r
-            OIC_LOG(INFO, TAG, "DirectPairingFinalizeHandler : success PUT request to /oic/sec/dpairing");\r
-\r
-            CAEndpoint_t endpoint;\r
-            memset(&endpoint, 0x00, sizeof(CAEndpoint_t));\r
-            OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, peer->endpoint.addr);\r
-            endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';\r
-            endpoint.port = peer->securePort;\r
-\r
-            OicUuid_t ptDeviceID = {.id={0}};\r
-            if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))\r
-            {\r
-                OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");\r
-                resultCallback(peer, OC_STACK_ERROR);\r
-                return OC_STACK_DELETE_TRANSACTION;\r
-            }\r
-\r
-#ifdef __WITH_DTLS__\r
-            res = SavePairingPSK((OCDevAddr*)&endpoint, &peer->deviceID, &ptDeviceID, false);\r
-            if(OC_STACK_OK != res)\r
-            {\r
-                OIC_LOG(ERROR, TAG, "Failed to PairingPSK generation");\r
-                resultCallback(peer, res);\r
-                return OC_STACK_DELETE_TRANSACTION;\r
-            }\r
-\r
-            //  close temporary sesion\r
-            CAResult_t caResult = CACloseDtlsSession((const CAEndpoint_t*)&endpoint);\r
-            if(CA_STATUS_OK != caResult)\r
-            {\r
-                OIC_LOG(INFO, TAG, "Fail to close temporary dtls session");\r
-            }\r
-\r
-            caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL);\r
-            if(CA_STATUS_OK != caResult)\r
-            {\r
-                OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");\r
-            }\r
-#endif // __WITH_DTLS__\r
-\r
-            OIC_LOG(INFO, TAG, "Direct-Papring was successfully completed.");\r
-\r
-            // update paired list\r
-            OCDirectPairingDev_t *dev = getDev(&g_dp_discover, peer->endpoint.addr, peer->endpoint.port);\r
-            res = addDev2(&g_dp_paired, dev);\r
-            if (OC_STACK_OK != res)\r
-            {\r
-                OIC_LOG(ERROR, TAG, "Error while adding a device to paired list.");\r
-            }\r
-\r
-            resultCallback(peer, OC_STACK_OK);\r
-\r
-            return OC_STACK_DELETE_TRANSACTION;\r
-        }\r
-        else\r
-        {\r
-            OIC_LOG(INFO, TAG, "Direct-Papring received error response.");\r
-        }\r
-    }\r
-    else\r
-    {\r
-        OIC_LOG(ERROR, TAG, "DirectPairingFinalizeHandler received Null clientResponse");\r
-    }\r
-\r
-    resultCallback(peer, OC_STACK_ERROR);\r
-    OICFree(dpairData);\r
-    return OC_STACK_DELETE_TRANSACTION;\r
-}\r
-\r
-/**\r
- * Finalize direct-pairing .\r
- *\r
- * @param[in] peer  target device to establish direct-pairing.\r
- * @param[in] resultCallback  result event callback.\r
- *\r
- * @return OC_STACK_OK on success otherwise error.\r
- */\r
-OCStackResult FinalizeDirectPairing(OCDirectPairingDev_t* peer,\r
-                                                     OCDirectPairingResultCB resultCallback)\r
-{\r
-    if(NULL == peer)\r
-    {\r
-        return OC_STACK_INVALID_PARAM;\r
-    }\r
-\r
-    OicUuid_t deviceID =   {.id={0}};\r
-    if (OC_STACK_OK != GetDoxmDeviceID(&deviceID))\r
-    {\r
-        OIC_LOG(ERROR, TAG, "Error while retrieving device ID");\r
-        return OC_STACK_ERROR;\r
-    }\r
-\r
-    OicSecDpairing_t dpair;\r
-    memset(&dpair, 0, sizeof(OicSecDpairing_t));\r
-    dpair.spm = (OicSecPrm_t)PRM_NOT_ALLOWED;\r
-    memcpy(&dpair.pdeviceID, &deviceID, sizeof(OicUuid_t));\r
-\r
-    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));\r
-    if(!secPayload)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "Failed to memory allocation");\r
-        return OC_STACK_NO_MEMORY;\r
-    }\r
-    secPayload->base.type = PAYLOAD_TYPE_SECURITY;\r
-    secPayload->securityData = BinToDpairingJSON(&dpair);\r
-    if(NULL == secPayload->securityData)\r
-    {\r
-        OICFree(secPayload);\r
-        OIC_LOG(ERROR, TAG, "Failed to BinToDpairingJSON");\r
-        return OC_STACK_NO_MEMORY;\r
-    }\r
-    OIC_LOG_V(INFO, TAG, "DPARING : %s", secPayload->securityData);\r
-\r
-    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};\r
-    if(!DPGenerateQuery(true,\r
-                        peer->endpoint.addr,\r
-                        peer->securePort,\r
-                        peer->connType,\r
-                        query, sizeof(query), OIC_RSRC_DPAIRING_URI))\r
-    {\r
-        OIC_LOG(ERROR, TAG, "DPDirectPairing : Failed to generate query");\r
-        return OC_STACK_ERROR;\r
-    }\r
-    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);\r
-\r
-    DPairData_t *dpairData = (DPairData_t *) OICCalloc(1, sizeof(DPairData_t));\r
-    if (dpairData == NULL)\r
-    {\r
-        OICFree(secPayload->securityData);\r
-        OICFree(secPayload);\r
-        OIC_LOG(ERROR, TAG, "Unable to allocate memory");\r
-        return OC_STACK_NO_MEMORY;\r
-    }\r
-    dpairData->peer = peer;\r
-    dpairData->resultCallback = resultCallback;\r
-\r
-    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};\r
-    cbData.cb = DirectPairingFinalizeHandler;\r
-    cbData.context = (void*)dpairData;\r
-    cbData.cd = NULL;\r
-\r
-    OCMethod method = OC_REST_PUT;\r
-    OCDoHandle handle = NULL;\r
-    OIC_LOG(DEBUG, TAG, "Sending DPAIRNG setting to resource server");\r
-    OCStackResult ret = OCDoResource(&handle, method, query,\r
-            &peer->endpoint, (OCPayload*)secPayload,\r
-            peer->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
-    if(OC_STACK_OK != ret)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "error in OCDoResource");\r
-        return OC_STACK_ERROR;\r
-    }\r
-\r
-    return OC_STACK_OK;\r
- }\r
-\r
-/**\r
- * Function to handle the handshake result in Direct-Pairing.\r
- * This function will be invoked after DTLS handshake\r
- * @param   endPoint  [IN] The remote endpoint.\r
- * @param   errorInfo [IN] Error information from the endpoint.\r
- * @return  NONE\r
- */\r
-void DirectPairingDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)\r
-{\r
-    OIC_LOG_V(INFO, TAG, "IN DirectPairingDTLSHandshakeCB");\r
-\r
-\r
-    if(g_dp_proceed_ctx && g_dp_proceed_ctx->peer && endpoint && info)\r
-    {\r
-        OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",\r
-                 endpoint->addr, endpoint->port, info->result);\r
-\r
-        OCDirectPairingDev_t *peer = g_dp_proceed_ctx->peer;\r
-        OCDirectPairingResultCB resultCallback = g_dp_proceed_ctx->resultCallback;\r
-        OCStackResult res;\r
-\r
-        //Make sure the address matches.\r
-        if(strncmp(peer->endpoint.addr, endpoint->addr, sizeof(endpoint->addr)) == 0 &&\r
-                         peer->securePort == endpoint->port)\r
-        {\r
-            //In case of success, send next coaps request.\r
-            if(CA_STATUS_OK == info->result)\r
-            {\r
-                OIC_LOG(INFO, TAG, "Now, finalize Direct-Pairing procedure.");\r
-\r
-                res = FinalizeDirectPairing(peer, resultCallback);\r
-                if(OC_STACK_OK != res)\r
-                {\r
-                    OIC_LOG(ERROR, TAG, "Failed to finalize direct-pairing");\r
-                    resultCallback(peer, res);\r
-                }\r
-            }\r
-            else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)\r
-            {\r
-                OIC_LOG(INFO, TAG, "DirectPairingDTLSHandshakeCB - Authentication failed");\r
-                resultCallback(peer, OC_STACK_AUTHENTICATION_FAILURE);\r
-            }\r
-\r
-#ifdef __WITH_DTLS__\r
-            CARegisterDTLSHandshakeCallback(NULL);\r
-#endif // __WITH_DTLS__\r
-            res = RemoveCredential(&peer->deviceID);\r
-            if(OC_STACK_RESOURCE_DELETED != res)\r
-            {\r
-                OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);\r
-            }\r
-\r
-            OICFree(g_dp_proceed_ctx);\r
-            g_dp_proceed_ctx = NULL;\r
-        }\r
-        else\r
-        {\r
-            OIC_LOG_V(INFO, TAG, "DirectPairingDTLSHandshakeCB - Not matched to peer address");\r
-        }\r
-    }\r
-\r
-    OIC_LOG_V(INFO, TAG, "OUT DirectPairingDTLSHandshakeCB");\r
-}\r
-\r
-/**\r
- * Callback handler of DPDirectPairing.\r
- *\r
- * @param[in] ctx             ctx value passed to callback from calling function.\r
- * @param[in] UNUSED          handle to an invocation\r
- * @param[in] clientResponse  Response from queries to remote servers.\r
- * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction\r
- *          and  OC_STACK_KEEP_TRANSACTION to keep it.\r
- */\r
-static OCStackApplicationResult DirectPairingHandler(void *ctx, OCDoHandle UNUSED,\r
-                                                  OCClientResponse *clientResponse)\r
-{\r
-    OIC_LOG_V(INFO, TAG, "IN DirectPairingHandler.");\r
-    (void)UNUSED;\r
-    if(NULL == ctx)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "Context is Null");\r
-        return OC_STACK_DELETE_TRANSACTION;\r
-    }\r
-\r
-    OCStackResult res = OC_STACK_ERROR;\r
-    DPairData_t *dpairData = (DPairData_t*)ctx;\r
-    OCDirectPairingResultCB resultCallback = (OCDirectPairingResultCB)dpairData->resultCallback;\r
-    OicUuid_t subjectId = {.id={0}};\r
-\r
-    if (clientResponse)\r
-    {\r
-        if(OC_STACK_RESOURCE_CREATED == clientResponse->result)\r
-        {\r
-            // result\r
-            OIC_LOG(INFO, TAG, "DirectPairingHandler : success POST request to /oic/sec/dpairing");\r
-\r
-#ifdef __WITH_DTLS__\r
-            // Add temporary psk\r
-            res = AddTmpPskWithPIN(&dpairData->peer->deviceID,\r
-                           SYMMETRIC_PAIR_WISE_KEY,\r
-                           (char*)dpairData->pin, DP_PIN_LENGTH,\r
-                           1, &dpairData->peer->rowner, &subjectId);\r
-            VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);\r
-\r
-\r
-            // Start to establish a secure channel with Pin-based PSK cipher suite\r
-            CAResult_t caresult;\r
-\r
-            caresult = CAEnableAnonECDHCipherSuite(false);\r
-            VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);\r
-\r
-            caresult = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);\r
-            VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);\r
-\r
-            //Register proceeding peer info. & DTLS event handler to catch the dtls event while handshake\r
-            g_dp_proceed_ctx = dpairData;\r
-            res = CARegisterDTLSHandshakeCallback(DirectPairingDTLSHandshakeCB);\r
-            VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);\r
-\r
-            // initiate dtls\r
-            CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));\r
-            VERIFY_NON_NULL(TAG, endpoint, FATAL);\r
-            memcpy(endpoint,&dpairData->peer->endpoint,sizeof(CAEndpoint_t));\r
-            endpoint->port = dpairData->peer->securePort;\r
-            OIC_LOG_V(INFO, TAG, "Initiate DTLS handshake to %s(%d)", endpoint->addr, endpoint->port);\r
-\r
-            caresult = CAInitiateHandshake(endpoint);\r
-            OICFree(endpoint);\r
-            VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);\r
-#endif // __WITH_DTLS__\r
-\r
-            res = OC_STACK_OK;\r
-        }\r
-        else\r
-        {\r
-            // result\r
-            OIC_LOG(INFO, TAG, "DirectPairingHandler : fail POST request to /oic/sec/dpairing");\r
-        }\r
-    }\r
-    else\r
-    {\r
-        OIC_LOG(ERROR, TAG, "DirectPairingHandler received Null clientResponse");\r
-    }\r
-\r
-#ifdef __WITH_DTLS__\r
-exit:\r
-#endif // __WITH_DTLS__\r
-\r
-    if (OC_STACK_OK != res)\r
-    {\r
-        if (0 < strlen((const char*)subjectId.id))\r
-        {\r
-            RemoveCredential(&dpairData->peer->deviceID);\r
-            OICFree(dpairData);\r
-            g_dp_proceed_ctx = NULL;\r
-        }\r
-\r
-        resultCallback(dpairData->peer, res);\r
-    }\r
-    OIC_LOG_V(INFO, TAG, "OUT DirectPairingHandler.");\r
-    return OC_STACK_DELETE_TRANSACTION;\r
-}\r
-\r
-/**\r
- * Start direct-pairing .\r
- *\r
- * @param[in] peer  target device to establish direct-pairing.\r
- * @param[in] pmSel  selected pairing method.\r
- * @param[in] pinNumber  secret value for dtls connection.\r
- *\r
- * @return OC_STACK_OK on success otherwise error.\r
- */\r
-OCStackResult DPDirectPairing(OCDirectPairingDev_t* peer, OicSecPrm_t pmSel, char *pinNumber,\r
-                                                     OCDirectPairingResultCB resultCallback)\r
-{\r
-    if(NULL == peer || NULL == pinNumber)\r
-    {\r
-        return OC_STACK_INVALID_PARAM;\r
-    }\r
-\r
-    OicUuid_t deviceID =   {.id={0}};\r
-    if (OC_STACK_OK != GetDoxmDeviceID(&deviceID))\r
-    {\r
-        OIC_LOG(ERROR, TAG, "Error while retrieving device ID");\r
-        return OC_STACK_ERROR;\r
-    }\r
-\r
-    OicSecDpairing_t dpair;\r
-    memset(&dpair, 0, sizeof(OicSecDpairing_t));\r
-    dpair.spm = pmSel;\r
-    memcpy(&dpair.pdeviceID, &deviceID, sizeof(OicUuid_t));\r
-\r
-    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));\r
-    if(!secPayload)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "Failed to memory allocation");\r
-        return OC_STACK_NO_MEMORY;\r
-    }\r
-    secPayload->base.type = PAYLOAD_TYPE_SECURITY;\r
-    secPayload->securityData = BinToDpairingJSON(&dpair);\r
-    if(NULL == secPayload->securityData)\r
-    {\r
-        OICFree(secPayload);\r
-        OIC_LOG(ERROR, TAG, "Failed to BinToDpairingJSON");\r
-        return OC_STACK_NO_MEMORY;\r
-    }\r
-    OIC_LOG_V(INFO, TAG, "DPAIRING : %s", secPayload->securityData);\r
-\r
-    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};\r
-    if(!DPGenerateQuery(false,\r
-                        peer->endpoint.addr,\r
-                        peer->endpoint.port,\r
-                        //peer->securePort,\r
-                        peer->connType,\r
-                        query, sizeof(query), OIC_RSRC_DPAIRING_URI))\r
-    {\r
-        OIC_LOG(ERROR, TAG, "DPDirectPairing : Failed to generate query");\r
-        return OC_STACK_ERROR;\r
-    }\r
-    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);\r
-\r
-    DPairData_t *dpairData = (DPairData_t *) OICCalloc(1, sizeof(DPairData_t));\r
-    if (dpairData == NULL)\r
-    {\r
-        OICFree(secPayload->securityData);\r
-        OICFree(secPayload);\r
-        OIC_LOG(ERROR, TAG, "Unable to allocate memory");\r
-        return OC_STACK_NO_MEMORY;\r
-    }\r
-    dpairData->peer = peer;\r
-    memcpy(dpairData->pin, pinNumber, DP_PIN_LENGTH);\r
-    dpairData->resultCallback = resultCallback;\r
-\r
-    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};\r
-    cbData.cb = DirectPairingHandler;\r
-    cbData.context = (void*)dpairData;\r
-    cbData.cd = NULL;\r
-\r
-    OCMethod method = OC_REST_POST;\r
-    OCDoHandle handle = NULL;\r
-    OIC_LOG(DEBUG, TAG, "Sending DPAIRNG setting to resource server");\r
-    OCStackResult ret = OCDoResource(&handle, method, query,\r
-            &peer->endpoint, (OCPayload*)secPayload,\r
-            peer->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
-    if(OC_STACK_OK != ret)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "error in OCDoResource");\r
-        return OC_STACK_ERROR;\r
-    }\r
-\r
-    return OC_STACK_OK;\r
-\r
- }\r
-\r
-/**\r
- * Callback handler for getting secure port information using /oic/res discovery.\r
- *\r
- * @param[in] ctx             user context\r
- * @param[in] handle          Handle for response\r
- * @param[in] clientResponse  Response information(It will contain payload)\r
- *\r
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and\r
- *         OC_STACK_DELETE_TRANSACTION to delete it.\r
- */\r
-static OCStackApplicationResult DirectPairingPortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,\r
-                                 OCClientResponse *clientResponse)\r
-{\r
-    OIC_LOG(INFO, TAG, "Callback Context for Direct-Pairing Secure Port DISCOVER query recvd successfully");\r
-\r
-    (void)ctx;\r
-    (void)UNUSED;\r
-    if (clientResponse)\r
-    {\r
-        if  (NULL == clientResponse->payload)\r
-        {\r
-            OIC_LOG(INFO, TAG, "Skiping Null payload");\r
-        }\r
-        else\r
-        {\r
-            if (PAYLOAD_TYPE_DISCOVERY != clientResponse->payload->type)\r
-            {\r
-                OIC_LOG(INFO, TAG, "Wrong payload type");\r
-                return OC_STACK_DELETE_TRANSACTION;\r
-            }\r
-\r
-            uint16_t securePort = 0;\r
-            OCResourcePayload* resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources;\r
-            OIC_LOG_PAYLOAD(INFO, clientResponse->payload);\r
-\r
-            if (resPayload && resPayload->secure)\r
-            {\r
-                securePort = resPayload->port;\r
-            }\r
-            else\r
-            {\r
-                OIC_LOG(INFO, TAG, "Can not find secure port information.");\r
-                return OC_STACK_DELETE_TRANSACTION;\r
-            }\r
-\r
-            OCDirectPairingDev_t *ptr = getDev(&g_dp_discover,\r
-                    clientResponse->devAddr.addr, clientResponse->devAddr.port);\r
-            if(!ptr)\r
-            {\r
-                OIC_LOG(ERROR, TAG, "Can not find device information in the discovery device list");\r
-                return OC_STACK_DELETE_TRANSACTION;\r
-            }\r
-            ptr->securePort = securePort;\r
-\r
-            OIC_LOG(INFO, TAG, "Exiting DirectPairingPortDiscoveryHandler.");\r
-        }\r
-\r
-        return  OC_STACK_DELETE_TRANSACTION;\r
-    }\r
-    else\r
-    {\r
-        OIC_LOG(INFO, TAG, "Skiping Null response");\r
-    }\r
-    return  OC_STACK_DELETE_TRANSACTION;\r
-}\r
-\r
-/**\r
- * Callback handler for DPDeviceDiscovery API.\r
- *\r
- * @param[in] ctx             User context\r
- * @param[in] handle          Handler for response\r
- * @param[in] clientResponse  Response information (It will contain payload)\r
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and\r
- *         OC_STACK_DELETE_TRANSACTION to delete it.\r
- */\r
-static OCStackApplicationResult DirectPairingDiscoveryHandler(void* ctx, OCDoHandle UNUSED,\r
-        OCClientResponse * clientResponse)\r
-{\r
-    OIC_LOG(INFO, TAG, "Callback Context for Direct-Pairing DISCOVER query recvd successfully");\r
-\r
-    (void)ctx;\r
-    (void)UNUSED;\r
-    if (clientResponse)\r
-    {\r
-        OIC_LOG_V(INFO, TAG, "StackResult: %d", clientResponse->result);\r
-        OIC_LOG_V(INFO, TAG,\r
-                "Device =============> Discovered @ %s:%d",\r
-                clientResponse->devAddr.addr,\r
-                clientResponse->devAddr.port);\r
-\r
-        if  (NULL == clientResponse->payload)\r
-        {\r
-            OIC_LOG(INFO, TAG, "Skiping Null payload");\r
-            return OC_STACK_KEEP_TRANSACTION;\r
-        }\r
-        if (OC_STACK_OK != clientResponse->result)\r
-        {\r
-            OIC_LOG(INFO, TAG, "Error in response");\r
-            return OC_STACK_KEEP_TRANSACTION;\r
-        }\r
-\r
-        OIC_LOG_PAYLOAD(INFO, clientResponse->payload);\r
-        OicSecPconf_t *pconf = JSONToPconfBin(\r
-                    ((OCSecurityPayload*)clientResponse->payload)->securityData);\r
-        if (NULL == pconf)\r
-        {\r
-            OIC_LOG(INFO, TAG, "Ignoring malformed JSON");\r
-            return OC_STACK_KEEP_TRANSACTION;\r
-        }\r
-        else\r
-        {\r
-            OCDevAddr endpoint;\r
-            memcpy(&endpoint, &clientResponse->devAddr, sizeof(OCDevAddr));\r
-\r
-            OCStackResult res = addDev(&g_dp_discover, &endpoint,\r
-                        clientResponse->connType, pconf);\r
-            DeletePconfBinData(pconf);\r
-            if (OC_STACK_OK != res)\r
-            {\r
-                OIC_LOG(ERROR, TAG, "Error while adding data to linkedlist.");\r
-                return OC_STACK_KEEP_TRANSACTION;\r
-            }\r
-\r
-\r
-            char rsrc_uri[MAX_URI_LENGTH+1] = {0};\r
-            int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",\r
-                      OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DPAIRING);\r
-            if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))\r
-            {\r
-                OIC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");\r
-                return OC_STACK_KEEP_TRANSACTION;\r
-            }\r
-\r
-            //Try to the unicast discovery to getting secure port\r
-            char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};\r
-            if(!DPGenerateQuery(false,\r
-                                clientResponse->devAddr.addr, clientResponse->devAddr.port,\r
-                                clientResponse->connType,\r
-                                query, sizeof(query), rsrc_uri))\r
-            {\r
-                OIC_LOG(ERROR, TAG, "DirectPairingDiscoveryHandler : Failed to generate query");\r
-                return OC_STACK_KEEP_TRANSACTION;\r
-            }\r
-            OIC_LOG_V(DEBUG, TAG, "Query=%s", query);\r
-\r
-            OCCallbackData cbData;\r
-            cbData.cb = &DirectPairingPortDiscoveryHandler;\r
-            cbData.context = NULL;\r
-            cbData.cd = NULL;\r
-            OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,\r
-                    clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
-            if(OC_STACK_OK != ret)\r
-            {\r
-                OIC_LOG(ERROR, TAG, "Failed to Secure Port Discovery");\r
-                return OC_STACK_KEEP_TRANSACTION;\r
-            }\r
-            else\r
-            {\r
-                OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);\r
-            }\r
-\r
-            return  OC_STACK_KEEP_TRANSACTION;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        OIC_LOG(INFO, TAG, "Skiping Null response");\r
-    }\r
-\r
-    return OC_STACK_DELETE_TRANSACTION;\r
-}\r
-\r
-#ifndef WITH_ARDUINO\r
-/**\r
- * Discover direct-pairing devices in the same IP subnet. .\r
- *\r
- * @param[in] waittime  Timeout in seconds.\r
- *\r
- * @return OC_STACK_OK on success otherwise error.\r
- */\r
-OCStackResult DPDeviceDiscovery(unsigned short waittime)\r
-{\r
-    OIC_LOG(DEBUG, TAG, "IN DPDeviceDiscovery");\r
-\r
-    if (g_dp_discover)\r
-    {\r
-        delList(g_dp_discover);\r
-        g_dp_discover = NULL;\r
-    }\r
-\r
-    OCStackResult ret;\r
-    struct timespec startTime = {.tv_sec=0, .tv_nsec=0};\r
-    struct timespec currTime  = {.tv_sec=0, .tv_nsec=0};\r
-    struct timespec timeout;\r
-\r
-    const char DP_DISCOVERY_QUERY[] = "/oic/sec/pconf";\r
-\r
-    OCCallbackData cbData;\r
-    cbData.cb = DirectPairingDiscoveryHandler;\r
-    cbData.context = NULL;\r
-    cbData.cd = NULL;\r
-\r
-    /* Start a DP discovery query*/\r
-    OIC_LOG_V(INFO, TAG, "Initiating Direct-Pairing Discovery : %s\n", DP_DISCOVERY_QUERY);\r
-    OCDoHandle handle = NULL;\r
-    ret = OCDoResource(&handle, OC_REST_DISCOVER, DP_DISCOVERY_QUERY, 0, 0, CT_DEFAULT,\r
-                       OC_LOW_QOS, &cbData, NULL, 0);\r
-    if (ret != OC_STACK_OK)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "OCStack resource error");\r
-        return ret;\r
-    }\r
-\r
-    // wait..\r
-    timeout.tv_sec  = 0;\r
-    timeout.tv_nsec = 100000000L;\r
-\r
-    int clock_res = -1;\r
-#if defined(__ANDROID__) || _POSIX_TIMERS > 0\r
-    clock_res = clock_gettime(CLOCK_MONOTONIC, &startTime);\r
-#endif\r
-    if (0 != clock_res)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "clock error");\r
-        if(OC_STACK_OK !=  OCCancel(handle, OC_LOW_QOS, NULL, 0))\r
-        {\r
-            OIC_LOG(ERROR, TAG, "Failed to remove registered callback");\r
-        }\r
-        return OC_STACK_ERROR;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-#if defined(__ANDROID__) || _POSIX_TIMERS > 0\r
-        clock_res = clock_gettime(CLOCK_MONOTONIC, &currTime);\r
-#endif\r
-        if (0 != clock_res)\r
-        {\r
-            OIC_LOG(ERROR, TAG, "clock error");\r
-            ret = OC_STACK_ERROR;\r
-            break;\r
-        }\r
-        long elapsed = (currTime.tv_sec - startTime.tv_sec);\r
-        if (elapsed > waittime)\r
-        {\r
-            break;\r
-        }\r
-        else\r
-        {\r
-            nanosleep(&timeout, NULL);\r
-        }\r
-    }\r
-\r
-    //Waiting for each response.\r
-    ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);\r
-    if (OC_STACK_OK != ret)\r
-    {\r
-        OIC_LOG(ERROR, TAG, "Failed to remove registered callback");\r
-    }\r
-    OIC_LOG(DEBUG, TAG, "OUT DPDeviceDiscovery");\r
-    return ret;\r
-}\r
-#endif\r
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200112L
+#endif
+#include "iotivity_config.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "logger.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
+#include "cJSON.h"
+#endif
+#include "utlist.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
+#include "cainterface.h"
+
+#include "directpairing.h"
+#include "srmresourcestrings.h" //@note: SRM's internal header
+#include "doxmresource.h"       //@note: SRM's internal header
+#include "pconfresource.h"       //@note: SRM's internal header
+#include "dpairingresource.h"       //@note: SRM's internal header
+#include "credresource.h"
+
+#include "pmtypes.h"
+#include "pmutility.h"
+
+#include "srmutility.h"
+
+#define TAG ("OIC_DP")
+static const uint16_t CBOR_SIZE = 1024;
+
+/**
+ * Structure to carry direct-pairing API data to callback.
+ */
+typedef struct DPairData
+{
+    OCDirectPairingDev_t        *peer;                         /**< Pointer to pairing target info.**/
+    char                                  pin[DP_PIN_LENGTH];  /**< PIN **/
+    OCDirectPairingResultCB    resultCallback;           /**< Pointer to result callback.**/
+    void *userCtx;                                      /** < user context to pass in callback **/
+} DPairData_t;
+
+static OCDirectPairingDev_t *g_dp_paired = NULL;
+static OCDirectPairingDev_t *g_dp_discover = NULL;
+static DPairData_t *g_dp_proceed_ctx = NULL;
+
+
+/**
+ * Function to search node in linked list that matches given IP and port.
+ *
+ * @param[in] pList         List of OCProvisionDev_t.
+ * @param[in] addr          address of target device.
+ * @param[in] port          port of remote server.
+ *
+ * @return pointer of OCProvisionDev_t if exist, otherwise NULL
+ */
+OCDirectPairingDev_t* getDev(OCDirectPairingDev_t **ppList, const char* addr, const uint16_t port)
+{
+    if(NULL == addr)
+    {
+        OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);
+        return NULL;
+    }
+
+    OCDirectPairingDev_t *ptr = NULL;
+    LL_FOREACH(*ppList, ptr)
+    {
+        if( strcmp(ptr->endpoint.addr, addr) == 0 && port == ptr->endpoint.port)
+        {
+            return ptr;
+        }
+    }
+
+    return NULL;
+}
+
+
+
+/**
+ * Add device information to list.
+ *
+ * @param[in] pList         List of OCProvisionDev_t.
+ * @param[in] addr          address of target device.
+ * @param[in] port          port of remote server.
+ * @param[in] adapter       adapter type of endpoint.
+ * @param[in] doxm          pointer to doxm instance.
+ * @param[in] connType  connectivity type of endpoint
+ *
+ * @return OC_STACK_OK for success and errorcode otherwise.
+ */
+OCStackResult addDev(OCDirectPairingDev_t **ppList, OCDevAddr *endpoint,
+                                      OCConnectivityType conn, OicSecPconf_t *pconf)
+{
+    if(NULL == endpoint || NULL == pconf)
+    {
+        OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCDirectPairingDev_t *ptr = getDev(ppList, endpoint->addr, endpoint->port);
+    if(!ptr)
+    {
+        ptr = (OCDirectPairingDev_t *)OICCalloc(1, sizeof (OCDirectPairingDev_t));
+        if (NULL == ptr)
+        {
+            OIC_LOG(ERROR, TAG, "Error while allocating memory for linkedlist node !!");
+            return OC_STACK_NO_MEMORY;
+        }
+
+        memcpy(&ptr->endpoint, endpoint, sizeof(OCDevAddr));
+        ptr->connType = conn;
+        ptr->securePort = DEFAULT_SECURE_PORT;
+        ptr->edp = pconf->edp;
+        ptr->prm = pconf->prm;
+        pconf->prm = NULL;  // to prevent free
+        ptr->prmLen = pconf->prmLen;
+        memcpy(&ptr->deviceID, &pconf->deviceID, sizeof(OicUuid_t));
+        memcpy(&ptr->rowner, &pconf->rownerID, sizeof(OicUuid_t));
+        ptr->next = NULL;
+
+        LL_PREPEND(*ppList, ptr);
+        OIC_LOG(INFO, TAG, "device added !");
+    }
+
+    return OC_STACK_OK;
+}
+
+
+/**
+ * Add device information to list.
+ *
+ * @param[in] ppList         List of OCProvisionDev_t.
+ * @param[in] pDev          target device.
+ *
+ * @return OC_STACK_OK for success and errorcode otherwise.
+ */
+OCStackResult addDev2(OCDirectPairingDev_t **ppList, OCDirectPairingDev_t *pDev)
+{
+    if(NULL == pDev)
+    {
+        OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCDirectPairingDev_t *ptr = getDev(ppList, pDev->endpoint.addr, pDev->endpoint.port);
+    if(!ptr)
+    {
+        ptr = (OCDirectPairingDev_t *)OICCalloc(1, sizeof (OCDirectPairingDev_t));
+        if (NULL == ptr)
+        {
+            OIC_LOG(ERROR, TAG, "Error while allocating memory for linkedlist node !!");
+            return OC_STACK_NO_MEMORY;
+        }
+
+        memcpy(&ptr->endpoint, &pDev->endpoint, sizeof(OCDevAddr));
+        ptr->connType = pDev->connType;
+        ptr->securePort = pDev->securePort;
+        ptr->edp = pDev->edp;
+        ptr->prmLen = pDev->prmLen;
+        ptr->prm = (OicSecPrm_t*)OICCalloc(ptr->prmLen, sizeof (OicSecPrm_t));
+        if (NULL == ptr->prm)
+        {
+            OIC_LOG(ERROR, TAG, "Error while allocating memory for prm !!");
+            OICFree(ptr);
+            return OC_STACK_NO_MEMORY;
+        }
+        memcpy(ptr->prm, pDev->prm, sizeof(OicSecPrm_t)*ptr->prmLen);
+        memcpy(&ptr->deviceID, &pDev->deviceID, sizeof(OicUuid_t));
+        memcpy(&ptr->rowner, &pDev->rowner, sizeof(OicUuid_t));
+        ptr->next = NULL;
+
+        LL_PREPEND(*ppList, ptr);
+        OIC_LOG(INFO, TAG, "device added !");
+    }
+
+    return OC_STACK_OK;
+}
+
+
+
+/**
+ * This function deletes list of provision target devices
+ *
+ * @param[in] pDevicesList         List of OCProvisionDev_t.
+ */
+void delList(OCDirectPairingDev_t *pList)
+{
+    if(pList)
+    {
+        OCDirectPairingDev_t *del = NULL, *tmp = NULL;
+        LL_FOREACH_SAFE(pList, del, tmp)
+        {
+            LL_DELETE(pList, del);
+            if (del && del->prm)
+            {
+                OICFree(del->prm);
+            }
+        }
+    }
+}
+
+bool DPGenerateQuery(bool isSecure,
+                     const char* address, const uint16_t port,
+                     const OCConnectivityType connType,
+                     char* buffer, size_t bufferSize, const char* uri)
+{
+    if(!address || !buffer || !uri)
+    {
+        OIC_LOG(ERROR, TAG, "DPGenerateQuery : Invalid parameters.");
+        return false;
+    }
+
+    static char QPREFIX_COAP[] =  "coap://";
+    static char QPREFIX_COAPS[] = "coaps://";
+    static char QPREFIX_COAP_TCP[] =  "coap+tcp://";
+    static char QPREFIX_COAPS_TCP[] = "coaps+tcp://";
+
+    int snRet = 0;
+    char* prefix = (isSecure == true) ? QPREFIX_COAPS : QPREFIX_COAP;
+
+    switch(connType & CT_MASK_ADAPTER)
+    {
+// @todo: Remove this ifdef. On Arduino, CT_ADAPTER_TCP resolves to the same value
+// as CT_ADAPTER_IP, resulting in a compiler error.
+#ifdef WITH_TCP
+#ifndef WITH_ARDUINO
+        case CT_ADAPTER_TCP:
+            prefix = (isSecure == true) ? QPREFIX_COAPS_TCP : QPREFIX_COAP_TCP;
+#endif
+#endif
+        case CT_ADAPTER_IP:
+            switch(connType & CT_MASK_FLAGS & ~CT_FLAG_SECURE)
+            {
+                case CT_IP_USE_V4:
+                    snRet = snprintf(buffer, bufferSize, "%s%s:%d%s",
+                                     prefix, address, port, uri);
+                    break;
+                case CT_IP_USE_V6:
+                {
+                    char addressEncoded[CA_MAX_URI_LENGTH] = {0};
+
+                    OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
+                                                                     sizeof(addressEncoded),
+                                                                     address);
+                    if (OC_STACK_OK != result)
+                    {
+                        OIC_LOG_V(ERROR, TAG, "DPGenerateQuery : encoding error %d\n", result);
+                        return false;
+                    }
+
+                    snRet = snprintf(buffer, bufferSize, "%s[%s]:%d%s",
+                                     prefix, addressEncoded, port, uri);
+                    break;
+                }
+                default:
+                    OIC_LOG(ERROR, TAG, "Unknown address format.");
+                    return false;
+            }
+            // snprintf return value check
+            if (snRet < 0)
+            {
+                OIC_LOG_V(ERROR, TAG, "DPGenerateQuery : Error (snprintf) %d\n", snRet);
+                return false;
+            }
+            else if ((size_t)snRet >= bufferSize)
+            {
+                OIC_LOG_V(ERROR, TAG, "DPGenerateQuery : Truncated (snprintf) %d\n", snRet);
+                return false;
+            }
+
+            break;
+#ifndef WITH_ARDUINO
+        // TODO: We need to verify tinyDTLS in below cases
+        case CT_ADAPTER_GATT_BTLE:
+        case CT_ADAPTER_RFCOMM_BTEDR:
+            OIC_LOG(ERROR, TAG, "Not supported connectivity adapter.");
+            return false;
+            break;
+#endif
+        default:
+            OIC_LOG(ERROR, TAG, "Unknown connectivity adapter.");
+            return false;
+    }
+
+    return true;
+}
+
+const OCDirectPairingDev_t* DPGetDiscoveredDevices()
+{
+    return g_dp_discover;
+}
+
+const OCDirectPairingDev_t* DPGetPairedDevices()
+{
+    return g_dp_paired;
+}
+
+void DPDeleteLists()
+{
+    delList(g_dp_discover);
+    delList(g_dp_paired);
+}
+
+/**
+ * Callback handler of FinalizeDirectPairing.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult DirectPairingFinalizeHandler(void *ctx, OCDoHandle UNUSED,
+                                                  OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(INFO, TAG, "IN DirectPairingFinalizeHandler()");
+    (void)UNUSED;
+    if(NULL == ctx)
+    {
+        OIC_LOG(ERROR, TAG, "Context is Null");
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OCStackResult res;
+    DPairData_t *dpairData = (DPairData_t*)ctx;
+    OCDirectPairingDev_t *peer = dpairData->peer;
+    OCDirectPairingResultCB resultCallback = dpairData->resultCallback;
+
+    if (clientResponse)
+    {
+        if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        {
+            // result
+            OIC_LOG(INFO, TAG, "DirectPairingFinalizeHandler : success PUT"
+                    " request to /oic/sec/dpairing");
+
+            CAEndpoint_t endpoint;
+            memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
+            OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, peer->endpoint.addr);
+            endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
+            endpoint.port = peer->securePort;
+
+            OicUuid_t ptDeviceID = {.id={0}};
+            if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
+            {
+                OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+                resultCallback(dpairData->userCtx, peer, OC_STACK_ERROR);
+                return OC_STACK_DELETE_TRANSACTION;
+            }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+            res = SavePairingPSK((OCDevAddr*)&endpoint, &peer->deviceID, &ptDeviceID, false);
+            if(OC_STACK_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "Failed to PairingPSK generation");
+                resultCallback(dpairData->userCtx, peer, res);
+                return OC_STACK_DELETE_TRANSACTION;
+            }
+
+            //  close temporary sesion
+            CAResult_t caResult = CAcloseSslSession((const CAEndpoint_t*)&endpoint);
+            if(CA_STATUS_OK != caResult)
+            {
+                OIC_LOG(INFO, TAG, "Fail to close temporary dtls session");
+            }
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
+            OIC_LOG(INFO, TAG, "Direct-Papring was successfully completed.");
+
+            // update paired list
+            OCDirectPairingDev_t *dev = getDev(&g_dp_discover, peer->endpoint.addr,
+                    peer->endpoint.port);
+            res = addDev2(&g_dp_paired, dev);
+            if (OC_STACK_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "Error while adding a device to paired list.");
+            }
+
+            resultCallback(dpairData->userCtx, peer, OC_STACK_OK);
+
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "Direct-Papring received error response.");
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "DirectPairingFinalizeHandler received Null clientResponse");
+    }
+
+    resultCallback(dpairData->userCtx, peer, OC_STACK_ERROR);
+    OICFree(dpairData);
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+/**
+ * Finalize direct-pairing .
+ *
+ * @param[in] peer  target device to establish direct-pairing.
+ * @param[in] resultCallback  result event callback.
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+OCStackResult FinalizeDirectPairing(void *ctx, OCDirectPairingDev_t* peer,
+                                                     OCDirectPairingResultCB resultCallback)
+{
+    if(NULL == peer)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OicUuid_t deviceID =   {.id={0}};
+    if (OC_STACK_OK != GetDoxmDeviceID(&deviceID))
+    {
+        OIC_LOG(ERROR, TAG, "Error while retrieving device ID");
+        return OC_STACK_ERROR;
+    }
+
+    OicSecDpairing_t dpair;
+    memset(&dpair, 0, sizeof(OicSecDpairing_t));
+    dpair.spm = (OicSecPrm_t)PRM_NOT_ALLOWED;
+    memcpy(&dpair.pdeviceID, &deviceID, sizeof(OicUuid_t));
+
+    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+    if(!secPayload)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+        return OC_STACK_NO_MEMORY;
+    }
+    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+
+    OCStackResult ret = DpairingToCBORPayload(&dpair, &(secPayload->securityData),
+            &(secPayload->payloadSize));
+
+    if(OC_STACK_OK != ret)
+    {
+        OICFree(secPayload);
+        OIC_LOG(ERROR, TAG, "Failed to DpairingToCBORPayload");
+        return OC_STACK_NO_MEMORY;
+    }
+    OIC_LOG(DEBUG, TAG, "DPARING CBOR data:");
+    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if(!DPGenerateQuery(true,
+                        peer->endpoint.addr,
+                        peer->securePort,
+                        peer->connType,
+                        query, sizeof(query), OIC_RSRC_DPAIRING_URI))
+    {
+        OIC_LOG(ERROR, TAG, "DPDirectPairing : Failed to generate query");
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    DPairData_t *dpairData = (DPairData_t *) OICCalloc(1, sizeof(DPairData_t));
+    if (dpairData == NULL)
+    {
+        OICFree(secPayload->securityData);
+        OICFree(secPayload);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    dpairData->peer = peer;
+    dpairData->resultCallback = resultCallback;
+    dpairData->userCtx = ctx;
+
+    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
+    cbData.cb = DirectPairingFinalizeHandler;
+    cbData.context = (void*)dpairData;
+    cbData.cd = NULL;
+
+    OCMethod method = OC_REST_PUT;
+    OCDoHandle handle = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending DPAIRNG setting to resource server");
+    ret = OCDoResource(&handle, method, query,
+            &peer->endpoint, (OCPayload*)secPayload,
+            peer->connType, OC_LOW_QOS, &cbData, NULL, 0);
+    if(OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "error in OCDoResource");
+        return OC_STACK_ERROR;
+    }
+
+    return OC_STACK_OK;
+ }
+
+/**
+ * Function to handle the handshake result in Direct-Pairing.
+ * This function will be invoked after DTLS handshake
+ * @param   endPoint  [IN] The remote endpoint.
+ * @param   errorInfo [IN] Error information from the endpoint.
+ * @return  NONE
+ */
+void DirectPairingDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
+{
+    OIC_LOG_V(INFO, TAG, "IN DirectPairingDTLSHandshakeCB");
+
+
+    if(g_dp_proceed_ctx && g_dp_proceed_ctx->peer && endpoint && info)
+    {
+        OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
+                 endpoint->addr, endpoint->port, info->result);
+
+        OCDirectPairingDev_t *peer = g_dp_proceed_ctx->peer;
+        OCDirectPairingResultCB resultCallback = g_dp_proceed_ctx->resultCallback;
+        OCStackResult res;
+
+        //Make sure the address matches.
+        if(strncmp(peer->endpoint.addr, endpoint->addr, sizeof(endpoint->addr)) == 0 &&
+                         peer->securePort == endpoint->port)
+        {
+            //In case of success, send next coaps request.
+            if(CA_STATUS_OK == info->result)
+            {
+                OIC_LOG(INFO, TAG, "Now, finalize Direct-Pairing procedure.");
+
+                res = FinalizeDirectPairing(g_dp_proceed_ctx->userCtx, peer, resultCallback);
+                if(OC_STACK_OK != res)
+                {
+                    OIC_LOG(ERROR, TAG, "Failed to finalize direct-pairing");
+                    resultCallback(g_dp_proceed_ctx->userCtx, peer, res);
+                }
+            }
+            else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
+            {
+                OIC_LOG(INFO, TAG, "DirectPairingDTLSHandshakeCB - Authentication failed");
+                resultCallback(g_dp_proceed_ctx->userCtx, peer, OC_STACK_AUTHENTICATION_FAILURE);
+            }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+            CAregisterSslHandshakeCallback(NULL);
+#endif // __WITH_DTLS__ or __WITH_TLS__
+            res = RemoveCredential(&peer->deviceID);
+            if(OC_STACK_RESOURCE_DELETED != res)
+            {
+                OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
+            }
+
+            OICFree(g_dp_proceed_ctx);
+            g_dp_proceed_ctx = NULL;
+        }
+        else
+        {
+            OIC_LOG_V(INFO, TAG, "DirectPairingDTLSHandshakeCB - Not matched to peer address");
+        }
+    }
+
+    OIC_LOG_V(INFO, TAG, "OUT DirectPairingDTLSHandshakeCB");
+}
+
+/**
+ * Callback handler of DPDirectPairing.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult DirectPairingHandler(void *ctx, OCDoHandle UNUSED,
+                                                  OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(INFO, TAG, "IN DirectPairingHandler.");
+    (void)UNUSED;
+    if(NULL == ctx)
+    {
+        OIC_LOG(ERROR, TAG, "Context is Null");
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OCStackResult res = OC_STACK_ERROR;
+    DPairData_t *dpairData = (DPairData_t*)ctx;
+    OCDirectPairingResultCB resultCallback = (OCDirectPairingResultCB)dpairData->resultCallback;
+    OicUuid_t subjectId = {.id={0}};
+
+    if (clientResponse)
+    {
+        if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
+        {
+            // result
+            OIC_LOG(INFO, TAG, "DirectPairingHandler : success POST request to /oic/sec/dpairing");
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+            // Add temporary psk
+            res = AddTmpPskWithPIN(&dpairData->peer->deviceID,
+                           SYMMETRIC_PAIR_WISE_KEY,
+                           (char*)dpairData->pin, DP_PIN_LENGTH,
+                           &dpairData->peer->rowner, &subjectId);
+            VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
+
+
+            // Start to establish a secure channel with Pin-based PSK cipher suite
+            CAResult_t caresult;
+
+            caresult = CAEnableAnonECDHCipherSuite(false);
+            VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);
+
+            caresult = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP);
+            VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);
+
+            //Register proceeding peer info. & DTLS event handler to catch the dtls event while handshake
+            g_dp_proceed_ctx = dpairData;
+            res = CAregisterSslHandshakeCallback(DirectPairingDTLSHandshakeCB);
+            VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);
+
+            // initiate dtls
+            CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
+            VERIFY_NON_NULL(TAG, endpoint, FATAL);
+            memcpy(endpoint,&dpairData->peer->endpoint,sizeof(CAEndpoint_t));
+            endpoint->port = dpairData->peer->securePort;
+            OIC_LOG_V(INFO, TAG, "Initiate DTLS handshake to %s(%d)", endpoint->addr,
+                    endpoint->port);
+
+            caresult = CAInitiateHandshake(endpoint);
+            OICFree(endpoint);
+            VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
+            res = OC_STACK_OK;
+        }
+        else
+        {
+            // result
+            OIC_LOG(INFO, TAG, "DirectPairingHandler : fail POST request to /oic/sec/dpairing");
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "DirectPairingHandler received Null clientResponse");
+    }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+exit:
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
+    if (OC_STACK_OK != res)
+    {
+        if (0 < strlen((const char*)subjectId.id))
+        {
+            RemoveCredential(&dpairData->peer->deviceID);
+            OICFree(dpairData);
+            g_dp_proceed_ctx = NULL;
+            OIC_LOG_V(INFO, TAG, "OUT DirectPairingHandler.");
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+
+        resultCallback(dpairData->userCtx, dpairData->peer, res);
+    }
+    OIC_LOG_V(INFO, TAG, "OUT DirectPairingHandler.");
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+/**
+ * Start direct-pairing .
+ *
+ * @param[in] peer  target device to establish direct-pairing.
+ * @param[in] pmSel  selected pairing method.
+ * @param[in] pinNumber  secret value for dtls connection.
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+OCStackResult DPDirectPairing(void *ctx, OCDirectPairingDev_t* peer, OicSecPrm_t pmSel,
+                                char *pinNumber, OCDirectPairingResultCB resultCallback)
+{
+    if(NULL == peer || NULL == pinNumber)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OicUuid_t deviceID =   {.id={0}};
+    if (OC_STACK_OK != GetDoxmDeviceID(&deviceID))
+    {
+        OIC_LOG(ERROR, TAG, "Error while retrieving device ID");
+        return OC_STACK_ERROR;
+    }
+
+    OicSecDpairing_t dpair;
+    memset(&dpair, 0, sizeof(OicSecDpairing_t));
+    dpair.spm = pmSel;
+    memcpy(&dpair.pdeviceID, &deviceID, sizeof(OicUuid_t));
+
+    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+    if(!secPayload)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+        return OC_STACK_NO_MEMORY;
+    }
+    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+
+    OCStackResult ret = DpairingToCBORPayload(&dpair, &(secPayload->securityData),
+            &(secPayload->payloadSize));
+
+    if(OC_STACK_OK != ret)
+    {
+        OICFree(secPayload);
+        OIC_LOG(ERROR, TAG, "Failed to DpairingToCBORPayload");
+        return OC_STACK_NO_MEMORY;
+    }
+    OIC_LOG(DEBUG, TAG, "DPARING CBOR data:");
+    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if(!DPGenerateQuery(false,
+                        peer->endpoint.addr,
+                        peer->endpoint.port,
+                        //peer->securePort,
+                        peer->connType,
+                        query, sizeof(query), OIC_RSRC_DPAIRING_URI))
+    {
+        OIC_LOG(ERROR, TAG, "DPDirectPairing : Failed to generate query");
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    DPairData_t *dpairData = (DPairData_t *) OICCalloc(1, sizeof(DPairData_t));
+    if (dpairData == NULL)
+    {
+        OICFree(secPayload->securityData);
+        OICFree(secPayload);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    dpairData->peer = peer;
+    memcpy(dpairData->pin, pinNumber, DP_PIN_LENGTH);
+    dpairData->resultCallback = resultCallback;
+    dpairData->userCtx = ctx;
+
+    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
+    cbData.cb = DirectPairingHandler;
+    cbData.context = (void*)dpairData;
+    cbData.cd = NULL;
+
+    OCMethod method = OC_REST_POST;
+    OCDoHandle handle = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending DPAIRNG setting to resource server");
+    ret = OCDoResource(&handle, method, query,
+            &peer->endpoint, (OCPayload*)secPayload,
+            peer->connType, OC_LOW_QOS, &cbData, NULL, 0);
+    if(OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "error in OCDoResource");
+        return OC_STACK_ERROR;
+    }
+
+    return OC_STACK_OK;
+
+ }
+
+/**
+ * Callback handler for getting secure port information using /oic/res discovery.
+ *
+ * @param[in] ctx             user context
+ * @param[in] handle          Handle for response
+ * @param[in] clientResponse  Response information(It will contain payload)
+ *
+ * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
+ *         OC_STACK_DELETE_TRANSACTION to delete it.
+ */
+static OCStackApplicationResult DirectPairingPortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+                                 OCClientResponse *clientResponse)
+{
+    OIC_LOG(INFO, TAG, "Callback Context for Direct-Pairing Secure Port DISCOVER "
+            "query recvd successfully");
+
+    (void)ctx;
+    (void)UNUSED;
+    if (clientResponse)
+    {
+        if  (NULL == clientResponse->payload)
+        {
+            OIC_LOG(INFO, TAG, "Skiping Null payload");
+        }
+        else
+        {
+            if (PAYLOAD_TYPE_DISCOVERY != clientResponse->payload->type)
+            {
+                OIC_LOG(INFO, TAG, "Wrong payload type");
+                return OC_STACK_DELETE_TRANSACTION;
+            }
+
+            uint16_t securePort = 0;
+            OCResourcePayload* resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
+            OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
+
+            if (resPayload && resPayload->secure)
+            {
+                securePort = resPayload->port;
+            }
+            else
+            {
+                OIC_LOG(INFO, TAG, "Can not find secure port information.");
+                return OC_STACK_DELETE_TRANSACTION;
+            }
+
+            OCDirectPairingDev_t *ptr = getDev(&g_dp_discover,
+                    clientResponse->devAddr.addr, clientResponse->devAddr.port);
+            if(!ptr)
+            {
+                OIC_LOG(ERROR, TAG, "Can not find device information in the discovery device list");
+                return OC_STACK_DELETE_TRANSACTION;
+            }
+            ptr->securePort = securePort;
+
+            OIC_LOG(INFO, TAG, "Exiting DirectPairingPortDiscoveryHandler.");
+        }
+
+        return  OC_STACK_DELETE_TRANSACTION;
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "Skiping Null response");
+    }
+    return  OC_STACK_DELETE_TRANSACTION;
+}
+
+/**
+ * Callback handler for DPDeviceDiscovery API.
+ *
+ * @param[in] ctx             User context
+ * @param[in] handle          Handler for response
+ * @param[in] clientResponse  Response information (It will contain payload)
+ * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
+ *         OC_STACK_DELETE_TRANSACTION to delete it.
+ */
+static OCStackApplicationResult DirectPairingDiscoveryHandler(void* ctx, OCDoHandle UNUSED,
+        OCClientResponse * clientResponse)
+{
+    OIC_LOG(INFO, TAG, "Callback Context for Direct-Pairing DISCOVER query recvd successfully");
+
+    (void)ctx;
+    (void)UNUSED;
+    if (clientResponse)
+    {
+        OIC_LOG_V(INFO, TAG, "StackResult: %d", clientResponse->result);
+        OIC_LOG_V(INFO, TAG,
+                "Device =============> Discovered @ %s:%d",
+                clientResponse->devAddr.addr,
+                clientResponse->devAddr.port);
+
+        if  (NULL == clientResponse->payload)
+        {
+            OIC_LOG(INFO, TAG, "Skiping Null payload");
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+        if (OC_STACK_OK != clientResponse->result)
+        {
+            OIC_LOG(INFO, TAG, "Error in response");
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
+        OicSecPconf_t *pconf = NULL;
+
+        OCStackResult res = CBORPayloadToPconf(
+                ((OCSecurityPayload*)clientResponse->payload)->securityData,
+                CBOR_SIZE,&pconf);
+        if (OC_STACK_OK != res )
+        {
+            OIC_LOG(INFO, TAG, "Ignoring malformed CBOR");
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+        else
+        {
+            if(pconf->edp)
+            {
+                OCDevAddr endpoint;
+                memcpy(&endpoint, &clientResponse->devAddr, sizeof(OCDevAddr));
+
+                OCStackResult res = addDev(&g_dp_discover, &endpoint,
+                            clientResponse->connType, pconf);
+                DeletePconfBinData(pconf);
+                if (OC_STACK_OK != res)
+                {
+                    OIC_LOG(ERROR, TAG, "Error while adding data to linkedlist.");
+                    return OC_STACK_KEEP_TRANSACTION;
+                }
+
+
+                char rsrc_uri[MAX_URI_LENGTH+1] = {0};
+                int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",
+                          OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DPAIRING);
+                if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))
+                {
+                    OIC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");
+                    return OC_STACK_KEEP_TRANSACTION;
+                }
+
+                //Try to the unicast discovery to getting secure port
+                char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};
+                if(!DPGenerateQuery(false,
+                                    clientResponse->devAddr.addr, clientResponse->devAddr.port,
+                                    clientResponse->connType,
+                                    query, sizeof(query), rsrc_uri))
+                {
+                    OIC_LOG(ERROR, TAG, "DirectPairingDiscoveryHandler : Failed to generate query");
+                    return OC_STACK_KEEP_TRANSACTION;
+                }
+                OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+                OCCallbackData cbData;
+                cbData.cb = &DirectPairingPortDiscoveryHandler;
+                cbData.context = NULL;
+                cbData.cd = NULL;
+                OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,
+                        clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);
+                if(OC_STACK_OK != ret)
+                {
+                    OIC_LOG(ERROR, TAG, "Failed to Secure Port Discovery");
+                    return OC_STACK_KEEP_TRANSACTION;
+                }
+                else
+                {
+                    OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);
+                }
+            }
+            return  OC_STACK_KEEP_TRANSACTION;
+        }
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "Skiping Null response");
+    }
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+#ifndef WITH_ARDUINO
+/**
+ * Discover direct-pairing devices in the same IP subnet. .
+ *
+ * @param[in] waittime  Timeout in seconds.
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+OCStackResult DPDeviceDiscovery(unsigned short waittime)
+{
+    OIC_LOG(DEBUG, TAG, "IN DPDeviceDiscovery");
+
+    if (g_dp_discover)
+    {
+        delList(g_dp_discover);
+        g_dp_discover = NULL;
+    }
+
+    OCStackResult ret;
+
+    const char DP_DISCOVERY_QUERY[] = "/oic/sec/pconf";
+
+    OCCallbackData cbData;
+    cbData.cb = DirectPairingDiscoveryHandler;
+    cbData.context = NULL;
+    cbData.cd = NULL;
+
+    /* Start a DP discovery query*/
+    OIC_LOG_V(INFO, TAG, "Initiating Direct-Pairing Discovery : %s\n", DP_DISCOVERY_QUERY);
+    OCDoHandle handle = NULL;
+    ret = OCDoResource(&handle, OC_REST_DISCOVER, DP_DISCOVERY_QUERY, 0, 0, CT_DEFAULT,
+                       OC_LOW_QOS, &cbData, NULL, 0);
+    if (ret != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+        return ret;
+    }
+
+    // wait..
+
+    int clock_res = -1;
+#if defined(_MSC_VER)
+    time_t startTime = NULL;
+    clock_res = (time(&startTime) == -1);
+#else
+    struct timespec startTime = {.tv_sec=0, .tv_nsec=0};
+#if defined(__ANDROID__) || _POSIX_TIMERS > 0
+    clock_res = clock_gettime(CLOCK_MONOTONIC, &startTime);
+#endif
+#endif
+    if (0 != clock_res)
+    {
+        OIC_LOG(ERROR, TAG, "clock error");
+        if(OC_STACK_OK !=  OCCancel(handle, OC_LOW_QOS, NULL, 0))
+        {
+            OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
+        }
+        return OC_STACK_ERROR;
+    }
+
+    while (1)
+    {
+#if defined(_MSC_VER)
+        time_t currTime = NULL;
+        clock_res = (time(&currTime) == -1);
+#else
+        struct timespec currTime  = {.tv_sec=0, .tv_nsec=0};
+#if defined(__ANDROID__) || _POSIX_TIMERS > 0
+        clock_res = clock_gettime(CLOCK_MONOTONIC, &currTime);
+#endif
+#endif
+        if (0 != clock_res)
+        {
+            OIC_LOG(ERROR, TAG, "clock error");
+            ret = OC_STACK_ERROR;
+            break;
+        }
+#if defined(_MSC_VER)
+        long elapsed = currTime - startTime;
+#else
+        long elapsed = (currTime.tv_sec - startTime.tv_sec);
+#endif
+        if (elapsed > waittime)
+        {
+            break;
+        }
+        else
+        {
+            struct timespec timeout = {.tv_sec=0, .tv_nsec=100000000L};
+            OCProcess();
+            nanosleep(&timeout, NULL);
+        }
+    }
+
+    // Waiting for each response.
+    ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
+    }
+    OIC_LOG(DEBUG, TAG, "OUT DPDeviceDiscovery");
+    return ret;
+}
+#endif