1 /* ****************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #ifndef __STDC_FORMAT_MACROS
27 #define __STDC_FORMAT_MACROS
31 #include "cainterface.h"
32 #include "caipnwmonitor.h"
33 #include "catcpadapter.h"
34 #include "catcpinterface.h"
35 #include "caqueueingthread.h"
36 #include "caadapterutils.h"
38 #include "uarraylist.h"
39 #include "caremotehandler.h"
41 #include "oic_malloc.h"
43 #include "ca_adapter_net_ssl.h"
47 * Logging tag for module name.
49 #define TAG "OIC_CA_TCP_ADAP"
52 * Holds internal thread TCP data information.
56 CAEndpoint_t *remoteEndpoint;
62 #define CA_TCP_LISTEN_BACKLOG 3
64 #define CA_TCP_SELECT_TIMEOUT 10
67 * Mutex to synchronize TCP adapter access.
69 static oc_mutex g_mutexAdapter = NULL;
72 * State to control closing of TCP servers on interface down event.
74 static bool g_skipCloseOnIFDown;
77 * Queue handle for Send Data.
79 static CAQueueingThread_t *g_sendQueueHandle = NULL;
82 * Network Packet Received Callback to CA.
84 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
87 * Adapter Changed Callback to CA.
89 static CAAdapterChangeCallback g_networkChangeCallback = NULL;
92 * Connection Changed Callback to CA.
94 static CAConnectionChangeCallback g_connectionChangeCallback = NULL;
97 * error Callback to CA adapter.
99 static CAErrorHandleCallback g_errorCallback = NULL;
102 * KeepAlive Connected or Disconnected Callback to CA adapter.
104 static CAKeepAliveConnectionCallback g_connKeepAliveCallback = NULL;
106 static CAResult_t CATCPPacketReceivedCB(const CASecureEndpoint_t *sep,
107 const void *data, uint32_t dataLength);
109 static void CATCPErrorHandler(const CAEndpoint_t *endpoint, const void *data,
110 size_t dataLength, CAResult_t result);
112 static CAResult_t CATCPInitializeQueueHandles();
114 static void CATCPDeinitializeQueueHandles(CAQueueingThread_t *queueHandle);
116 static void CATCPSendDataThread(void *threadData);
118 static CATCPData *CACreateTCPData(const CAEndpoint_t *remoteEndpoint,
119 const void *data, size_t dataLength,
121 void CAFreeTCPData(CATCPData *ipData);
123 static void CADataDestroyer(void *data, uint32_t size);
125 CAResult_t CATCPInitializeQueueHandles()
127 // Check if the message queue is already initialized
128 if (g_sendQueueHandle)
130 OIC_LOG(DEBUG, TAG, "send queue handle is already initialized!");
134 // Create send message queue
135 g_sendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
136 if (!g_sendQueueHandle)
138 OIC_LOG(ERROR, TAG, "Memory allocation failed!");
139 return CA_MEMORY_ALLOC_FAILED;
142 if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle,
143 (const ca_thread_pool_t)caglobals.tcp.threadpool,
144 CATCPSendDataThread, CADataDestroyer))
146 OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
147 OICFree(g_sendQueueHandle);
148 g_sendQueueHandle = NULL;
149 return CA_STATUS_FAILED;
155 void CATCPDeinitializeQueueHandles(CAQueueingThread_t *queueHandle)
157 CAQueueingThreadDestroy(queueHandle);
158 OICFree(queueHandle);
161 void CATCPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status)
167 CAResult_t CATCPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
170 VERIFY_NON_NULL(sep, TAG, "sep is NULL");
171 VERIFY_NON_NULL(data, TAG, "data is NULL");
173 OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", sep->endpoint.addr, sep->endpoint.port);
175 CAResult_t res = CA_STATUS_OK;
177 if (g_networkPacketCallback)
179 res = g_networkPacketCallback(sep, data, dataLength);
180 if (CA_STATUS_OK != res)
182 OIC_LOG(ERROR, TAG, "Error parsing CoAP data");
186 unsigned char *buffer = (unsigned char*)data;
187 size_t bufferLen = dataLength;
190 //get remote device information from file descriptor.
191 CATCPSessionInfo_t *svritem = CAGetTCPSessionInfoFromEndpoint(&sep->endpoint, &index);
194 OIC_LOG(ERROR, TAG, "there is no connection information in list");
195 return CA_STATUS_INVALID_PARAM;
197 if (UNKNOWN == svritem->protocol)
199 OIC_LOG(ERROR, TAG, "invalid protocol type");
200 return CA_STATUS_INVALID_PARAM;
203 //totalLen filled only when header fully read and parsed
204 while (0 != bufferLen)
206 res = CAConstructCoAP(svritem, &buffer, &bufferLen);
207 if (CA_STATUS_OK != res)
209 OIC_LOG_V(ERROR, TAG, "CAConstructCoAP return error : %d", res);
213 //when successfully read all required data - pass them to upper layer.
214 if (svritem->len == svritem->totalLen)
216 if (g_networkPacketCallback)
218 res = g_networkPacketCallback(sep, svritem->data, svritem->totalLen);
219 if (CA_STATUS_OK != res)
221 OIC_LOG(ERROR, TAG, "Error parsing CoAP data");
225 CACleanData(svritem);
229 OIC_LOG_V(DEBUG, TAG, "%zd bytes required for complete CoAP",
230 svritem->totalLen - svritem->len);
238 static ssize_t CATCPPacketSendCB(CAEndpoint_t *endpoint, const void *data, size_t dataLength)
240 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
241 VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint is NULL", -1);
242 VERIFY_NON_NULL_RET(data, TAG, "data is NULL", -1);
244 OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", endpoint->addr, endpoint->port);
245 OIC_LOG_BUFFER(DEBUG, TAG, data, dataLength);
247 ssize_t ret = CATCPSendData(endpoint, data, dataLength);
248 OIC_LOG_V(DEBUG, TAG, "Out %s : %zd bytes sent", __func__, ret);
253 static void CATCPErrorHandler(const CAEndpoint_t *endpoint, const void *data,
254 size_t dataLength, CAResult_t result)
256 VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");
257 VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
261 g_errorCallback(endpoint, data, dataLength, result);
265 static void CATCPConnectionHandler(const CAEndpoint_t *endpoint, bool isConnected, bool isClient)
267 // Pass the changed connection status to RI Layer for keepalive.
268 if (g_connKeepAliveCallback)
270 g_connKeepAliveCallback(endpoint, isConnected, isClient);
273 // Pass the changed connection status to CAUtil.
274 if (g_connectionChangeCallback)
276 g_connectionChangeCallback(endpoint, isConnected);
280 void CATCPSetKeepAliveCallbacks(CAKeepAliveConnectionCallback ConnHandler)
282 g_connKeepAliveCallback = ConnHandler;
285 void CATCPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
287 if (g_networkChangeCallback)
289 g_networkChangeCallback(adapter, status);
292 if (CA_INTERFACE_DOWN == status)
294 OIC_LOG(INFO, TAG, "Network status is down, close all session");
296 CAResult_t res = CAQueueingThreadClearData(g_sendQueueHandle);
297 if (res != CA_STATUS_OK)
299 OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res);
302 oc_mutex_lock(g_mutexAdapter);
303 if (!g_skipCloseOnIFDown)
309 OIC_LOG(INFO, TAG, "Skip closing servers!");
311 oc_mutex_unlock(g_mutexAdapter);
313 else if (CA_INTERFACE_UP == status)
315 OIC_LOG(INFO, TAG, "Network status is up, create new socket for listening");
317 CAResult_t ret = CA_STATUS_FAILED;
318 #ifndef SINGLE_THREAD
319 ret = CATCPStartServer((const ca_thread_pool_t)caglobals.tcp.threadpool);
321 ret = CATCPStartServer();
323 if (CA_STATUS_OK != ret)
325 OIC_LOG_V(ERROR, TAG, "CATCPStartServer failed[%d]", ret);
330 static void CAInitializeTCPGlobals()
332 caglobals.tcp.ipv4.fd = -1;
333 caglobals.tcp.ipv4s.fd = -1;
334 caglobals.tcp.ipv6.fd = -1;
335 caglobals.tcp.ipv6s.fd = -1;
337 // Set the port number received from application.
338 caglobals.tcp.ipv4.port = caglobals.ports.tcp.u4;
339 caglobals.tcp.ipv4s.port = caglobals.ports.tcp.u4s;
340 caglobals.tcp.ipv6.port = caglobals.ports.tcp.u6;
341 caglobals.tcp.ipv6s.port = caglobals.ports.tcp.u6s;
343 caglobals.tcp.selectTimeout = CA_TCP_SELECT_TIMEOUT;
344 caglobals.tcp.listenBacklog = CA_TCP_LISTEN_BACKLOG;
345 caglobals.tcp.svrlist = NULL;
347 CATransportFlags_t flags = 0;
348 if (caglobals.client)
350 flags |= caglobals.clientFlags;
353 #ifndef DISABLE_TCP_SERVER
354 if (caglobals.server)
356 flags |= caglobals.serverFlags;
360 caglobals.tcp.ipv4tcpenabled = flags & CA_IPV4;
361 caglobals.tcp.ipv6tcpenabled = flags & CA_IPV6;
364 CAResult_t CAInitializeTCP(CARegisterConnectivityCallback registerCallback,
365 CANetworkPacketReceivedCallback networkPacketCallback,
366 CAAdapterChangeCallback netCallback,
367 CAConnectionChangeCallback connCallback,
368 CAErrorHandleCallback errorCallback, ca_thread_pool_t handle)
370 OIC_LOG(DEBUG, TAG, "IN");
371 VERIFY_NON_NULL(registerCallback, TAG, "registerCallback");
372 VERIFY_NON_NULL(networkPacketCallback, TAG, "networkPacketCallback");
373 VERIFY_NON_NULL(netCallback, TAG, "netCallback");
374 #ifndef SINGLE_THREAD
375 VERIFY_NON_NULL(handle, TAG, "thread pool handle");
378 g_networkChangeCallback = netCallback;
379 g_connectionChangeCallback = connCallback;
380 g_networkPacketCallback = networkPacketCallback;
381 g_errorCallback = errorCallback;
383 CAInitializeTCPGlobals();
385 // Create Mutex for synchronize access at adapter level
388 g_mutexAdapter = oc_mutex_new();
391 OIC_LOG(ERROR, TAG, "Failed to create mutex!");
392 return CA_STATUS_FAILED;
396 g_skipCloseOnIFDown = false;
398 CAResult_t res = CATCPCreateMutex();
399 if (CA_STATUS_OK == res)
401 res = CATCPCreateCond();
403 if (CA_STATUS_OK != res)
405 OIC_LOG(ERROR, TAG, "failed to create mutex/cond");
411 res = CATCPCreateSendMutex();
412 if (CA_STATUS_OK == res)
414 res = CATCPCreateSendCond();
416 if (CA_STATUS_OK != res)
418 OIC_LOG(ERROR, TAG, "failed to create send data mutex/cond");
421 CATCPDestroySendMutex();
422 CATCPDestroySendCond();
426 #ifndef SINGLE_THREAD
427 caglobals.tcp.threadpool = handle;
430 CATCPSetConnectionChangedCallback(CATCPConnectionHandler);
431 CATCPSetPacketReceiveCallback(CATCPPacketReceivedCB);
432 CATCPSetErrorHandler(CATCPErrorHandler);
435 CAsetSslAdapterCallbacks(CATCPPacketReceivedCB, CATCPPacketSendCB, CA_ADAPTER_TCP);
438 CAConnectivityHandler_t tcpHandler = {
439 .startAdapter = CAStartTCP,
440 .startListenServer = CAStartTCPListeningServer,
441 .stopListenServer = CAStopTCPListeningServer,
442 .startDiscoveryServer = CAStartTCPDiscoveryServer,
443 .sendData = CASendTCPUnicastData,
444 .sendDataToAll = CASendTCPMulticastData,
445 .GetnetInfo = CAGetTCPInterfaceInformation,
446 .readData = CAReadTCPData,
447 .stopAdapter = CAStopTCP,
448 .terminate = CATerminateTCP,
449 .cType = CA_ADAPTER_TCP};
451 registerCallback(tcpHandler);
453 OIC_LOG(INFO, TAG, "OUT IntializeTCP is Success");
457 CAResult_t CAStartTCP()
459 OIC_LOG(DEBUG, TAG, "IN");
461 #ifndef SINGLE_THREAD
462 if (CA_STATUS_OK != CATCPInitializeQueueHandles())
464 OIC_LOG(ERROR, TAG, "Failed to Initialize Queue Handle");
466 return CA_STATUS_FAILED;
469 // Start send queue thread
471 if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
473 if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle, "IoT_TCPSendQueue"))
476 OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
477 return CA_STATUS_FAILED;
480 CAResult_t ret = CATCPStartServer();
481 if (CA_STATUS_OK != ret)
483 OIC_LOG_V(DEBUG, TAG, "CATCPStartServer failed[%d]", ret);
488 // Start network monitoring to receive adapter status changes.
489 CAIPStartNetworkMonitor(CATCPAdapterHandler, CA_ADAPTER_TCP);
494 static bool CAClearQueueEndpointDataContext(void *data, uint32_t size, void *ctx)
498 if (NULL == data || NULL == ctx)
503 CATCPData *tcpData = (CATCPData *)data;
504 CAEndpoint_t *endpoint = (CAEndpoint_t *)ctx;
506 if (NULL != tcpData && NULL != tcpData->remoteEndpoint)
508 if (strcmp(tcpData->remoteEndpoint->addr, endpoint->addr) == 0
509 && tcpData->remoteEndpoint->port == endpoint->port)
517 CAResult_t CATCPDisconnectSession(const CAEndpoint_t *endpoint)
519 CAResult_t res = CAQueueingThreadClearContextData(g_sendQueueHandle,
520 CAClearQueueEndpointDataContext,
522 if (CA_STATUS_OK != res)
524 OIC_LOG(ERROR, TAG, "failed to clear context data");
528 res = CAcloseSslConnection(endpoint);
529 if (CA_STATUS_OK != res)
531 OIC_LOG(ERROR, TAG, "failed to close TLS session");
535 res = CASearchAndDeleteTCPSession(endpoint);
536 if (CA_STATUS_OK != res)
538 OIC_LOG(ERROR, TAG, "failed to close TCP session");
544 void CATCPSkipCloseOnInterfaceDown(bool state)
546 oc_mutex_lock(g_mutexAdapter);
547 g_skipCloseOnIFDown = state;
548 oc_mutex_unlock(g_mutexAdapter);
551 CAResult_t CAStartTCPListeningServer()
553 #if !defined(SINGLE_THREAD) && !defined(DISABLE_TCP_SERVER)
554 if (!caglobals.server)
556 caglobals.server = true; // only needed to run CA tests
559 CAResult_t ret = CATCPStartServer((const ca_thread_pool_t)caglobals.tcp.threadpool);
560 if (CA_STATUS_OK != ret)
562 OIC_LOG_V(ERROR, TAG, "Failed to start listening server![%d]", ret);
570 CAResult_t CAStopTCPListeningServer()
575 CAResult_t CAStartTCPDiscoveryServer()
577 if (!caglobals.client)
579 caglobals.client = true; // only needed to run CA tests
582 CAResult_t ret = CATCPStartServer((const ca_thread_pool_t)caglobals.tcp.threadpool);
583 if (CA_STATUS_OK != ret)
585 OIC_LOG_V(ERROR, TAG, "Failed to start discovery server![%d]", ret);
592 static size_t CAQueueTCPData(bool isMulticast, const CAEndpoint_t *endpoint,
593 const void *data, size_t dataLength)
595 VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint", -1);
596 VERIFY_NON_NULL_RET(data, TAG, "data", -1);
600 OIC_LOG(ERROR, TAG, "Invalid Data Length");
604 VERIFY_NON_NULL_RET(g_sendQueueHandle, TAG, "sendQueueHandle", -1);
606 // Create TCPData to add to queue
607 CATCPData *tcpData = CACreateTCPData(endpoint, data, dataLength, isMulticast);
610 OIC_LOG(ERROR, TAG, "Failed to create ipData!");
613 // Add message to send queue
614 CAQueueingThreadAddData(g_sendQueueHandle, tcpData, sizeof(CATCPData));
619 int32_t CASendTCPUnicastData(const CAEndpoint_t *endpoint,
620 const void *data, uint32_t dataLength,
621 CADataType_t dataType)
623 OIC_LOG(DEBUG, TAG, "IN");
625 #ifndef SINGLE_THREAD
626 return CAQueueTCPData(false, endpoint, data, dataLength);
628 return CATCPSendData(endpoint, data, dataLength);
632 int32_t CASendTCPMulticastData(const CAEndpoint_t *endpoint,
633 const void *data, uint32_t dataLength,
634 CADataType_t dataType)
641 OIC_LOG(ERROR, TAG, "TCP adapter does not support multicast sending!");
645 CAResult_t CAReadTCPData()
647 OIC_LOG(DEBUG, TAG, "IN");
654 CAResult_t CAStopTCP()
656 CAIPStopNetworkMonitor(CA_ADAPTER_TCP);
658 /* Some times send queue thread fails to terminate as it's worker
659 thread gets blocked at TCP session's socket connect operation.
660 So closing sockets which are in connect operation at the time
661 of termination of adapter would save send queue thread from
663 CATCPCloseInProgressConnections();
665 #ifndef SINGLE_THREAD
666 // Stop send queue thread.
667 if (g_sendQueueHandle != NULL)
669 // g_sendQueueHandle is set to NULL to prevent new requests from being enqueued.
670 CAQueueingThread_t *queueHandle = g_sendQueueHandle;
671 g_sendQueueHandle = NULL;
673 if (queueHandle->threadMutex)
675 CAQueueingThreadStop(queueHandle);
677 CATCPDeinitializeQueueHandles(queueHandle);
681 // Close TCP servers and established connections.
684 // Re-initializing the Globals to start them again.
685 CAInitializeTCPGlobals();
690 void CATerminateTCP()
692 CATCPSetPacketReceiveCallback(NULL);
697 CATCPDestroySendMutex();
698 CATCPDestroySendCond();
700 g_skipCloseOnIFDown = false;
702 // Free adapter mutex
705 oc_mutex_free(g_mutexAdapter);
706 g_mutexAdapter = NULL;
710 void CATCPSendDataThread(void *threadData)
712 CATCPData *tcpData = (CATCPData *) threadData;
715 OIC_LOG(DEBUG, TAG, "Invalid TCP data!");
719 if (caglobals.tcp.terminate)
721 OIC_LOG(DEBUG, TAG, "Adapter is not enabled");
722 CATCPErrorHandler(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen,
727 if (tcpData->isMulticast)
729 //Processing for sending multicast
730 OIC_LOG(DEBUG, TAG, "Send Multicast Data is called, not supported");
736 if (tcpData->remoteEndpoint && tcpData->remoteEndpoint->flags & CA_SECURE)
738 CAResult_t result = CA_STATUS_OK;
739 OIC_LOG(DEBUG, TAG, "CAencryptSsl called!");
740 result = CAencryptSsl(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen);
742 if (CA_STATUS_OK != result)
744 OIC_LOG(ERROR, TAG, "CAAdapterNetDtlsEncrypt failed!");
745 CASearchAndDeleteTCPSession(tcpData->remoteEndpoint);
746 CATCPErrorHandler(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen,
749 OIC_LOG_V(DEBUG, TAG,
750 "CAAdapterNetDtlsEncrypt returned with result[%d]", result);
754 //Processing for sending unicast
755 ssize_t dlen = CATCPSendData(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen);
758 OIC_LOG(ERROR, TAG, "CATCPSendData failed");
759 CASearchAndDeleteTCPSession(tcpData->remoteEndpoint);
760 CATCPErrorHandler(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen,
766 CATCPData *CACreateTCPData(const CAEndpoint_t *remoteEndpoint, const void *data,
767 size_t dataLength, bool isMulticast)
769 VERIFY_NON_NULL_RET(remoteEndpoint, TAG, "remoteEndpoint is NULL", NULL);
770 VERIFY_NON_NULL_RET(data, TAG, "data is NULL", NULL);
772 CATCPData *tcpData = (CATCPData *) OICCalloc(1, sizeof(*tcpData));
775 OIC_LOG(ERROR, TAG, "Memory allocation failed!");
779 tcpData->remoteEndpoint = CACloneEndpoint(remoteEndpoint);
780 tcpData->data = (void *) OICMalloc(dataLength);
783 OIC_LOG(ERROR, TAG, "Memory allocation failed!");
784 CAFreeTCPData(tcpData);
788 memcpy(tcpData->data, data, dataLength);
789 tcpData->dataLen = dataLength;
791 tcpData->isMulticast = isMulticast;
796 void CAFreeTCPData(CATCPData *tcpData)
798 VERIFY_NON_NULL_VOID(tcpData, TAG, "tcpData is NULL");
800 CAFreeEndpoint(tcpData->remoteEndpoint);
801 OICFree(tcpData->data);
805 void CADataDestroyer(void *data, uint32_t size)
807 if (size < sizeof(CATCPData))
810 OIC_LOG_V(ERROR, TAG, "Destroy data too small %p %" PRIu32, data, size);
813 CATCPData *TCPData = (CATCPData *) data;
815 CAFreeTCPData(TCPData);
819 size_t CAGetTotalLengthFromPacketHeader(const unsigned char *recvBuffer, size_t size)
821 OIC_LOG(DEBUG, TAG, "IN - CAGetTotalLengthFromHeader");
823 if (NULL == recvBuffer || !size)
825 OIC_LOG(ERROR, TAG, "recvBuffer is NULL");
829 coap_transport_t transport = coap_get_tcp_header_type_from_initbyte(
830 ((unsigned char *)recvBuffer)[0] >> 4);
831 size_t optPaylaodLen = coap_get_length_from_header((unsigned char *)recvBuffer,
833 size_t headerLen = coap_get_tcp_header_length((unsigned char *)recvBuffer);
835 OIC_LOG_V(DEBUG, TAG, "option/paylaod length [%d]", optPaylaodLen);
836 OIC_LOG_V(DEBUG, TAG, "header length [%d]", headerLen);
837 OIC_LOG_V(DEBUG, TAG, "total data length [%d]", headerLen + optPaylaodLen);
839 OIC_LOG(DEBUG, TAG, "OUT - CAGetTotalLengthFromHeader");
840 return headerLen + optPaylaodLen;
843 void CAGetTCPHeaderDetails(unsigned char* recvBuffer, coap_transport_t *transport,
846 if (NULL == recvBuffer)
848 OIC_LOG(ERROR, TAG, "recvBuffer is NULL");
852 if (NULL == transport)
854 OIC_LOG(ERROR, TAG, "transport is NULL");
858 if (NULL == headerlen)
860 OIC_LOG(ERROR, TAG, "headerlen is NULL");
864 *transport = coap_get_tcp_header_type_from_initbyte(
865 ((unsigned char *)recvBuffer)[0] >> 4);
866 *headerlen = coap_get_tcp_header_length_for_transport(*transport);