Merge remote-tracking branch 'origin/routing-manager'
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / camessagehandler.c
index 3021d8d..982f1a8 100644 (file)
@@ -71,8 +71,9 @@ static void CAErrorHandler(const CAEndpoint_t *endpoint,
                            const void *data, uint32_t dataLen,
                            CAResult_t result);
 
-static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, const void *data,
-                                       CADataType_t dataType);
+static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint,
+                                       const CARemoteId_t *identity,
+                                       const void *data, CADataType_t dataType);
 
 static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info,
                             CAResult_t result);
@@ -82,7 +83,8 @@ static void CAProcessReceivedData(CAData_t *data);
 #endif
 static void CADestroyData(void *data, uint32_t size);
 static void CALogPayloadInfo(CAInfo_t *info);
-static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *endpoint, uint16_t id);
+static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *endpoint, uint16_t id,
+                                CAToken_t token, uint8_t tokenLength);
 
 #ifdef WITH_BWT
 void CAAddDataToSendThread(CAData_t *data)
@@ -111,7 +113,7 @@ void CAAddDataToReceiveThread(CAData_t *data)
 static bool CAIsSelectedNetworkAvailable()
 {
     u_arraylist_t *list = CAGetSelectedNetworkList();
-    if (!list || list->length == 0)
+    if (!list || u_arraylist_length(list) == 0)
     {
         OIC_LOG(ERROR, TAG, "No selected network");
         return false;
@@ -120,15 +122,13 @@ static bool CAIsSelectedNetworkAvailable()
     return true;
 }
 
-static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, const void *data, CADataType_t dataType)
+static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint,
+                                       const CARemoteId_t *identity,
+                                       const void *data, CADataType_t dataType)
 {
     OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData IN");
-
-    CAResponseInfo_t* resInfo = NULL;
-    CARequestInfo_t* reqInfo = NULL;
-    CAErrorInfo_t *errorInfo = NULL;
-
-    CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof (CAData_t));
+    CAInfo_t *info = NULL;
+    CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
     if (!cadata)
     {
         OIC_LOG(ERROR, TAG, "memory allocation failed");
@@ -139,7 +139,8 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, const void
     if (!ep)
     {
         OIC_LOG(ERROR, TAG, "endpoint clone failed");
-        goto errorexit;
+        OICFree(cadata);
+        return NULL;
     }
 
     OIC_LOG_V(DEBUG, TAG, "address : %s", ep->addr);
@@ -147,96 +148,110 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, const void
 
     if(CA_RESPONSE_DATA == dataType)
     {
-        resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof (CAResponseInfo_t));
+        CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t));
         if (!resInfo)
         {
             OIC_LOG(ERROR, TAG, "memory allocation failed");
-            goto errorexit;
+            OICFree(cadata);
+            CAFreeEndpoint(ep);
+            return NULL;
         }
 
-        result = CAGetResponseInfoFromPDU(data, resInfo);
+        result = CAGetResponseInfoFromPDU(data, resInfo, endpoint);
         if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, TAG, "CAGetResponseInfoFromPDU Failed");
-            goto errorexit;
+            CAFreeEndpoint(ep);
+            CADestroyResponseInfoInternal(resInfo);
+            OICFree(cadata);
+            return NULL;
         }
-
-        if (CADropSecondMessage(&caglobals.ca.responseHistory, endpoint, resInfo->info.messageId))
+        cadata->responseInfo = resInfo;
+        info = &resInfo->info;
+        if (identity)
         {
-            OIC_LOG(ERROR, TAG, "Second Response with same messageID, Drop it");
-            goto errorexit;
+            info->identity = *identity;
         }
-
-        cadata->responseInfo = resInfo;
         OIC_LOG(DEBUG, TAG, "Response Info :");
-        CALogPayloadInfo(&resInfo->info);
+        CALogPayloadInfo(info);
     }
     else if (CA_REQUEST_DATA == dataType)
     {
-        reqInfo = (CARequestInfo_t*)OICCalloc(1, sizeof (CARequestInfo_t));
+        CARequestInfo_t* reqInfo = (CARequestInfo_t*)OICCalloc(1, sizeof(CARequestInfo_t));
         if (!reqInfo)
         {
             OIC_LOG(ERROR, TAG, "memory allocation failed");
-            goto errorexit;
+            OICFree(cadata);
+            CAFreeEndpoint(ep);
+            return NULL;
         }
 
-        result = CAGetRequestInfoFromPDU(data, reqInfo);
+        result = CAGetRequestInfoFromPDU(data, endpoint, reqInfo);
         if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, TAG, "CAGetRequestInfoFromPDU failed");
-            goto errorexit;
+            CAFreeEndpoint(ep);
+            CADestroyRequestInfoInternal(reqInfo);
+            OICFree(cadata);
+            return NULL;
         }
 
-        if (CADropSecondMessage(&caglobals.ca.requestHistory, endpoint, reqInfo->info.messageId))
+        if (CADropSecondMessage(&caglobals.ca.requestHistory, endpoint, reqInfo->info.messageId,
+                                reqInfo->info.token, reqInfo->info.tokenLength))
         {
-            OIC_LOG(ERROR, TAG, "Second Request with same messageID, Drop it");
-            goto errorexit;
+            OIC_LOG(ERROR, TAG, "Second Request with same Token, Drop it");
+            CAFreeEndpoint(ep);
+            CADestroyRequestInfoInternal(reqInfo);
+            OICFree(cadata);
+            return NULL;
         }
 
         cadata->requestInfo = reqInfo;
+        info = &reqInfo->info;
+        if (identity)
+        {
+            info->identity = *identity;
+        }
         OIC_LOG(DEBUG, TAG, "Request Info :");
-        CALogPayloadInfo(&reqInfo->info);
-    }
+        CALogPayloadInfo(info);
+   }
     else if (CA_ERROR_DATA == dataType)
     {
-        errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
+        CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t));
         if (!errorInfo)
         {
             OIC_LOG(ERROR, TAG, "Memory allocation failed!");
-            goto errorexit;
+            OICFree(cadata);
+            CAFreeEndpoint(ep);
+            return NULL;
         }
 
-        result = CAGetErrorInfoFromPDU(data, errorInfo);
+        CAResult_t result = CAGetErrorInfoFromPDU(data, endpoint, errorInfo);
         if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, TAG, "CAGetErrorInfoFromPDU failed");
-            goto errorexit;
+            CAFreeEndpoint(ep);
+            OICFree(errorInfo);
+            OICFree(cadata);
+            return NULL;
         }
 
         cadata->errorInfo = errorInfo;
+        info = &errorInfo->info;
+        if (identity)
+        {
+            info->identity = *identity;
+        }
         OIC_LOG(DEBUG, TAG, "error Info :");
-        CALogPayloadInfo(&errorInfo->info);
-    }
-    else
-    {
-        OIC_LOG_V(ERROR, TAG, "bad dataType: %d", dataType);
-        goto errorexit;
+        CALogPayloadInfo(info);
     }
 
     cadata->remoteEndpoint = ep;
     cadata->dataType = dataType;
 
-    OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData OUT");
-
     return cadata;
 
-errorexit:
-    CAFreeEndpoint(ep);
-    OICFree(cadata);
-    OICFree(resInfo);
-    OICFree(reqInfo);
-    OICFree(errorInfo);
-    return NULL;
+    OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData OUT");
 }
 
 static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uint32_t size)
@@ -265,7 +280,8 @@ static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uin
     resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size);
     resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
 
-    CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *) pdu, &(resInfo->info));
+    CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *) pdu, &(resInfo->info),
+                                       endpoint);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
@@ -332,7 +348,6 @@ static void CADestroyData(void *data, uint32_t size)
         CADestroyErrorInfoInternal(cadata->errorInfo);
     }
 
-    OICFree(cadata->options);
     OICFree(cadata);
     OIC_LOG(DEBUG, TAG, "CADestroyData OUT");
 }
@@ -408,13 +423,23 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
 
     if (SEND_TYPE_UNICAST == type)
     {
-
         OIC_LOG(DEBUG,TAG,"Unicast message");
+#ifdef ROUTING_GATEWAY
+        /*
+         * When forwarding a packet, do not attempt retransmission as its the responsibility of
+         * packet originator node
+         */
+        bool skipRetransmission = false;
+#endif
+
         if (NULL != data->requestInfo)
         {
             OIC_LOG(DEBUG, TAG, "requestInfo is available..");
 
             info = &data->requestInfo->info;
+#ifdef ROUTING_GATEWAY
+            skipRetransmission = data->requestInfo->info.skipRetransmission;
+#endif
             pdu = CAGeneratePDU(data->requestInfo->method, info, data->remoteEndpoint);
         }
         else if (NULL != data->responseInfo)
@@ -422,6 +447,9 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
             OIC_LOG(DEBUG, TAG, "responseInfo is available..");
 
             info = &data->responseInfo->info;
+#ifdef ROUTING_GATEWAY
+            skipRetransmission = data->responseInfo->info.skipRetransmission;
+#endif
             pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint);
         }
         else
@@ -434,7 +462,11 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
         if (NULL != pdu)
         {
 #ifdef WITH_BWT
-            if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter)
+            if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter
+#ifdef TCP_ADAPTER
+                    && CA_ADAPTER_TCP != data->remoteEndpoint->adapter
+#endif
+                    )
             {
                 // Blockwise transfer
                 if (NULL != info)
@@ -451,7 +483,7 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
                 }
             }
 #endif
-            CALogPDUInfo(pdu);
+            CALogPDUInfo(pdu, data->remoteEndpoint);
 
             res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
             if (CA_STATUS_OK != res)
@@ -461,15 +493,28 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
                 coap_delete_pdu(pdu);
                 return res;
             }
-            // for retransmission
-            res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr,
-                                           pdu->length);
-            if ((CA_STATUS_OK != res) && (CA_NOT_SUPPORTED != res))
+
+#ifdef TCP_ADAPTER
+            if (CA_ADAPTER_TCP == data->remoteEndpoint->adapter)
             {
-                //when retransmission not supported this will return CA_NOT_SUPPORTED, ignore
-                OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res);
-                coap_delete_pdu(pdu);
-                return res;
+                OIC_LOG(INFO, TAG, "retransmission will be not worked");
+            }
+            else
+#endif
+#ifdef ROUTING_GATEWAY
+            if(!skipRetransmission)
+#endif
+            {
+                // for retransmission
+                res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr,
+                                               pdu->length);
+                if ((CA_STATUS_OK != res) && (CA_NOT_SUPPORTED != res))
+                {
+                    //when retransmission not supported this will return CA_NOT_SUPPORTED, ignore
+                    OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res);
+                    coap_delete_pdu(pdu);
+                    return res;
+                }
             }
 
             coap_delete_pdu(pdu);
@@ -493,7 +538,11 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
             if (NULL != pdu)
             {
 #ifdef WITH_BWT
-                if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter)
+                if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter
+#ifdef TCP_ADAPTER
+                        && CA_ADAPTER_TCP != data->remoteEndpoint->adapter
+#endif
+                        )
                 {
                     // Blockwise transfer
                     CAResult_t res = CAAddBlockOption(&pdu, data->requestInfo->info,
@@ -507,18 +556,45 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
                     }
                 }
 #endif
-                CALogPDUInfo(pdu);
+            }
+            else
+            {
+                OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU");
+                CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
+                return CA_SEND_FAILED;
+            }
+        }
+        else if (NULL != data->responseInfo)
+        {
+            OIC_LOG(DEBUG, TAG, "responseInfo is available..");
 
-                res = CASendMulticastData(data->remoteEndpoint, pdu->hdr, pdu->length);
-                if (CA_STATUS_OK != res)
+            info = &data->responseInfo->info;
+            pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint);
+
+            if (NULL != pdu)
+            {
+#ifdef WITH_BWT
+                if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter
+#ifdef TCP_ADAPTER
+                        && CA_ADAPTER_TCP != data->remoteEndpoint->adapter
+#endif
+                        )
                 {
-                    OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
-                    CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
-                    coap_delete_pdu(pdu);
-                    return res;
+                    // Blockwise transfer
+                    if (NULL != info)
+                    {
+                        CAResult_t res = CAAddBlockOption(&pdu, *info,
+                                data->remoteEndpoint);
+                        if (CA_STATUS_OK != res)
+                        {
+                            OIC_LOG(INFO, TAG, "to write block option has failed");
+                            CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
+                            coap_delete_pdu(pdu);
+                            return res;
+                        }
+                    }
                 }
-
-                coap_delete_pdu(pdu);
+#endif
             }
             else
             {
@@ -529,12 +605,27 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
         }
         else
         {
-            OIC_LOG(ERROR, TAG, "request info is empty");
+            OIC_LOG(ERROR, TAG, "request or response info is empty");
             return CA_SEND_FAILED;
         }
+
+        CALogPDUInfo(pdu, data->remoteEndpoint);
+
+        OIC_LOG(DEBUG, TAG, "pdu to send :");
+        OIC_LOG_BUFFER(DEBUG, TAG,  pdu->hdr, pdu->length);
+
+        res = CASendMulticastData(data->remoteEndpoint, pdu->hdr, pdu->length);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
+            CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
+            coap_delete_pdu(pdu);
+            return res;
+        }
+
+        coap_delete_pdu(pdu);
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -548,10 +639,11 @@ static void CASendThreadProcess(void *threadData)
 #endif
 
 /*
- * If a second message arrives with the same token and the other address
+ * If a second message arrives with the same message ID, token and the other address
  * family, drop it.  Typically, IPv6 beats IPv4, so the IPv4 message is dropped.
  */
-static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, uint16_t id)
+static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, uint16_t id,
+                                CAToken_t token, uint8_t tokenLength)
 {
     if (!ep)
     {
@@ -566,13 +658,23 @@ static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, ui
         return false;
     }
 
+    if (tokenLength > CA_MAX_TOKEN_LEN)
+    {
+        /*
+         * If token length is more than CA_MAX_TOKEN_LEN,
+         * we compare the first CA_MAX_TOKEN_LEN bytes only.
+         */
+        tokenLength = CA_MAX_TOKEN_LEN;
+    }
+
     bool ret = false;
     CATransportFlags_t familyFlags = ep->flags & CA_IPFAMILY_MASK;
 
-    for (int i = 0; i < sizeof(history->items) / sizeof(history->items[0]); i++)
+    for (size_t i = 0; i < sizeof(history->items) / sizeof(history->items[0]); i++)
     {
         CAHistoryItem_t *item = &(history->items[i]);
-        if (id == item->messageId)
+        if (id == item->messageId && tokenLength == item->tokenLength
+            && memcmp(item->token, token, tokenLength) == 0)
         {
             if ((familyFlags ^ item->flags) == CA_IPFAMILY_MASK)
             {
@@ -586,6 +688,12 @@ static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, ui
 
     history->items[history->nextIndex].flags = familyFlags;
     history->items[history->nextIndex].messageId = id;
+    if (token && tokenLength)
+    {
+        memcpy(history->items[history->nextIndex].token, token, tokenLength);
+        history->items[history->nextIndex].tokenLength = tokenLength;
+    }
+
     if (++history->nextIndex >= HISTORYSIZE)
     {
         history->nextIndex = 0;
@@ -594,17 +702,21 @@ static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, ui
     return ret;
 }
 
-static void CAReceivedPacketCallback(const CAEndpoint_t *remoteEndpoint, const void *data,
-        uint32_t dataLen)
+static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
+                                     const void *data, uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    VERIFY_NON_NULL_VOID(remoteEndpoint, TAG, "remoteEndpoint");
+    VERIFY_NON_NULL_VOID(sep, TAG, "remoteEndpoint");
     VERIFY_NON_NULL_VOID(data, TAG, "data");
 
+    OIC_LOG(DEBUG, TAG, "received pdu data :");
+    OIC_LOG_BUFFER(DEBUG, TAG,  data, dataLen);
+
     uint32_t code = CA_NOT_FOUND;
     CAData_t *cadata = NULL;
 
-    coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
+    coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code,
+                                                &(sep->endpoint));
     if (NULL == pdu)
     {
         OIC_LOG(ERROR, TAG, "Parse PDU failed");
@@ -614,7 +726,7 @@ static void CAReceivedPacketCallback(const CAEndpoint_t *remoteEndpoint, const v
     OIC_LOG_V(DEBUG, TAG, "code = %d", code);
     if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
     {
-        cadata = CAGenerateHandlerData(remoteEndpoint, pdu, CA_REQUEST_DATA);
+        cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity), pdu, CA_REQUEST_DATA);
         if (!cadata)
         {
             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
@@ -624,7 +736,7 @@ static void CAReceivedPacketCallback(const CAEndpoint_t *remoteEndpoint, const v
     }
     else
     {
-        cadata = CAGenerateHandlerData(remoteEndpoint, pdu, CA_RESPONSE_DATA);
+        cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity), pdu, CA_RESPONSE_DATA);
         if (!cadata)
         {
             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
@@ -632,28 +744,37 @@ static void CAReceivedPacketCallback(const CAEndpoint_t *remoteEndpoint, const v
             return;
         }
 
-        // for retransmission
-        void *retransmissionPdu = NULL;
-        CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->hdr,
-                                     pdu->length, &retransmissionPdu);
-
-        // get token from saved data in retransmission list
-        if (retransmissionPdu && CA_EMPTY == code)
+#ifdef TCP_ADAPTER
+        if (CA_ADAPTER_TCP == sep->endpoint.adapter)
         {
-            if (cadata->responseInfo)
+            OIC_LOG(INFO, TAG, "retransmission is not supported");
+        }
+        else
+#endif
+        {
+            // for retransmission
+            void *retransmissionPdu = NULL;
+            CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->hdr,
+                                         pdu->length, &retransmissionPdu);
+
+            // get token from saved data in retransmission list
+            if (retransmissionPdu && CA_EMPTY == code)
             {
-                CAInfo_t *info = &cadata->responseInfo->info;
-                CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu,
-                                                   info);
-                if (CA_STATUS_OK != res)
+                if (cadata->responseInfo)
                 {
-                    OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
-                    OICFree(info->token);
-                    info->tokenLength = 0;
+                    CAInfo_t *info = &cadata->responseInfo->info;
+                    CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu,
+                                                       info, &(sep->endpoint));
+                    if (CA_STATUS_OK != res)
+                    {
+                        OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
+                        OICFree(info->token);
+                        info->tokenLength = 0;
+                    }
                 }
             }
+            OICFree(retransmissionPdu);
         }
-        OICFree(retransmissionPdu);
     }
 
     cadata->type = SEND_TYPE_UNICAST;
@@ -662,24 +783,28 @@ static void CAReceivedPacketCallback(const CAEndpoint_t *remoteEndpoint, const v
     CAProcessReceivedData(cadata);
 #else
 #ifdef WITH_BWT
-        if (CA_ADAPTER_GATT_BTLE != remoteEndpoint->adapter)
+    if (CA_ADAPTER_GATT_BTLE != sep->endpoint.adapter
+#ifdef TCP_ADAPTER
+            && CA_ADAPTER_TCP != sep->endpoint.adapter
+#endif
+            )
+    {
+        CAResult_t res = CAReceiveBlockWiseData(pdu, &(sep->endpoint), cadata, dataLen);
+        if (CA_NOT_SUPPORTED == res)
         {
-            CAResult_t res = CAReceiveBlockWiseData(pdu, remoteEndpoint, cadata, dataLen);
-            if (CA_NOT_SUPPORTED == res)
-            {
-                OIC_LOG(ERROR, TAG, "this message does not have block option");
-                CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
-            }
-            else
-            {
-                CADestroyData(cadata, sizeof(CAData_t));
-            }
+            OIC_LOG(ERROR, TAG, "this message does not have block option");
+            CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
         }
         else
-#endif
         {
-            CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
+            CADestroyData(cadata, sizeof(CAData_t));
         }
+    }
+    else
+#endif
+    {
+        CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
+    }
 #endif
 
     coap_delete_pdu(pdu);
@@ -756,7 +881,6 @@ static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sen
                                    CADataType_t dataType)
 {
     OIC_LOG(DEBUG, TAG, "CAPrepareSendData IN");
-    CAInfo_t *info = NULL;
 
     CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
     if (!cadata)
@@ -778,7 +902,6 @@ static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sen
         }
 
         cadata->type = request->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
-        info = &request->info;
         cadata->requestInfo =  request;
     }
     else if(CA_RESPONSE_DATA == dataType)
@@ -793,8 +916,7 @@ static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sen
             return NULL;
         }
 
-        cadata->type = SEND_TYPE_UNICAST;
-        info = &response->info;
+        cadata->type = response->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST;
         cadata->responseInfo = response;
     }
     else
@@ -804,25 +926,6 @@ static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sen
         return NULL;
     }
 
-    if (NULL != info->options && 0 < info->numOptions)
-    {
-        uint8_t numOptions = info->numOptions;
-        // copy data
-        CAHeaderOption_t *headerOption = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t)
-                                                                        * numOptions);
-        if(!headerOption)
-        {
-            OIC_LOG(ERROR, TAG, "memory allocation failed");
-            CADestroyData(cadata, sizeof(CAData_t));
-            return NULL;
-        }
-
-        memcpy(headerOption, info->options, sizeof(CAHeaderOption_t) * numOptions);
-
-        cadata->options = headerOption;
-        cadata->numOptions = numOptions;
-    }
-
     CAEndpoint_t* ep = CACloneEndpoint(endpoint);
     if (!ep)
     {
@@ -875,7 +978,11 @@ CAResult_t CADetachRequestMessage(const CAEndpoint_t *object, const CARequestInf
     CADestroyData(data, sizeof(CAData_t));
 #else
 #ifdef WITH_BWT
-    if (CA_ADAPTER_GATT_BTLE != object->adapter)
+    if (CA_ADAPTER_GATT_BTLE != object->adapter
+#ifdef TCP_ADAPTER
+            && CA_ADAPTER_TCP != object->adapter
+#endif
+            )
     {
         // send block data
         CAResult_t res = CASendBlockWiseData(data);
@@ -932,7 +1039,11 @@ CAResult_t CADetachResponseMessage(const CAEndpoint_t *object,
     CADestroyData(data, sizeof(CAData_t));
 #else
 #ifdef WITH_BWT
-    if (CA_ADAPTER_GATT_BTLE != object->adapter)
+    if (CA_ADAPTER_GATT_BTLE != object->adapter
+#ifdef TCP_ADAPTER
+            && CA_ADAPTER_TCP != object->adapter
+#endif
+            )
     {
         // send block data
         CAResult_t res = CASendBlockWiseData(data);
@@ -1140,19 +1251,30 @@ void CATerminateMessageHandler()
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-void CALogPDUInfo(coap_pdu_t *pdu)
+void CALogPDUInfo(coap_pdu_t *pdu, const CAEndpoint_t *endpoint)
 {
     VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
 
     OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
 
-    OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type);
+#ifdef TCP_ADAPTER
+    if (CA_ADAPTER_TCP == endpoint->adapter)
+    {
+        OIC_LOG(DEBUG, TAG, "pdu header data :");
+        OIC_LOG_BUFFER(DEBUG, TAG,  pdu->hdr, pdu->length);
+    }
+    else
+#endif
+    {
+        OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->coap_hdr_udp_t.type);
 
-    OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
+        OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->coap_hdr_udp_t.code);
 
-    OIC_LOG(DEBUG, TAG, "PDU Maker - token :");
+        OIC_LOG(DEBUG, TAG, "PDU Maker - token :");
 
-    OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length);
+        OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->coap_hdr_udp_t.token,
+                       pdu->hdr->coap_hdr_udp_t.token_length);
+    }
 }
 
 static void CALogPayloadInfo(CAInfo_t *info)
@@ -1203,14 +1325,14 @@ void CAErrorHandler(const CAEndpoint_t *endpoint,
     uint32_t code = CA_NOT_FOUND;
     //Do not free remoteEndpoint and data. Currently they will be freed in data thread
     //Get PDU data
-    coap_pdu_t *pdu = (coap_pdu_t *)CAParsePDU((const char *)data, dataLen, &code);
+    coap_pdu_t *pdu = (coap_pdu_t *)CAParsePDU((const char *)data, dataLen, &code, endpoint);
     if (NULL == pdu)
     {
         OIC_LOG(ERROR, TAG, "Parse PDU failed");
         return;
     }
 
-    CAData_t *cadata = CAGenerateHandlerData(endpoint, pdu, CA_ERROR_DATA);
+    CAData_t *cadata = CAGenerateHandlerData(endpoint, NULL, pdu, CA_ERROR_DATA);
     if(!cadata)
     {
         OIC_LOG(ERROR, TAG, "CAErrorHandler, CAGenerateHandlerData failed!");