X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fconnectivity%2Fsrc%2Fcamessagehandler.c;h=d9be889b218ec002a4d700376e86f4e85ea6df8b;hb=03c42f9b68da8054f76ee2e2a1a9318dcffb5fde;hp=bf496ed6708b3c1035a2d5c9f23030a9ab9a8291;hpb=cc68c51711ac0211b3c29da57ef6f794dd2f6120;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/connectivity/src/camessagehandler.c b/resource/csdk/connectivity/src/camessagehandler.c old mode 100644 new mode 100755 index bf496ed..d9be889 --- a/resource/csdk/connectivity/src/camessagehandler.c +++ b/resource/csdk/connectivity/src/camessagehandler.c @@ -28,12 +28,16 @@ #include "caremotehandler.h" #include "caprotocolmessage.h" #include "logger.h" -#include "config.h" /* for coap protocol */ +#include "trace.h" +#ifndef WITH_UPSTREAM_LIBCOAP +#include "coap/config.h" +#endif #include "oic_malloc.h" #include "canetworkconfigurator.h" #include "caadapterutils.h" #include "cainterfacecontroller.h" #include "caretransmission.h" +#include "oic_string.h" #ifdef WITH_BWT #include "cablockwisetransfer.h" @@ -56,9 +60,9 @@ static CAQueueingThread_t g_receiveThread; #else #define CA_MAX_RT_ARRAY_SIZE 3 -#endif /* SINGLE_THREAD */ +#endif // SINGLE_THREAD -#define TAG "CA_MSG_HNDLR" +#define TAG "OIC_CA_MSG_HANDLE" static CARetransmission_t g_retransmissionContext; @@ -66,6 +70,7 @@ static CARetransmission_t g_retransmissionContext; static CARequestCallback g_requestHandler = NULL; static CAResponseCallback g_responseHandler = NULL; static CAErrorCallback g_errorHandler = NULL; +static CANetworkMonitorCallback g_nwMonitorHandler = NULL; static void CAErrorHandler(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen, @@ -86,27 +91,34 @@ static void CALogPayloadInfo(CAInfo_t *info); static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *endpoint, uint16_t id, CAToken_t token, uint8_t tokenLength); +/** + * print send / receive message of CoAP. + * @param[in] data CA information which has send/receive message and endpoint. + * @param[in] pdu CoAP pdu low data. + */ +static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu); + +#ifndef ARDUINO +static char g_headerBuffer[MAX_LOG_BUFFER_SIZE] = {0}; +static size_t g_headerIndex = 0; +static void CASamsungLogMessage(const CAData_t *data, const coap_pdu_t *pdu); +#endif + #ifdef WITH_BWT void CAAddDataToSendThread(CAData_t *data) { - OIC_LOG(DEBUG, TAG, "IN"); VERIFY_NON_NULL_VOID(data, TAG, "data"); // add thread CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); - - OIC_LOG(DEBUG, TAG, "OUT"); } void CAAddDataToReceiveThread(CAData_t *data) { - OIC_LOG(DEBUG, TAG, "IN - CAAddDataToReceiveThread"); VERIFY_NON_NULL_VOID(data, TAG, "data"); // add thread CAQueueingThreadAddData(&g_receiveThread, data, sizeof(CAData_t)); - - OIC_LOG(DEBUG, TAG, "OUT - CAAddDataToReceiveThread"); } #endif @@ -134,37 +146,34 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, OIC_LOG(ERROR, TAG, "memory allocation failed"); return NULL; } - +#ifdef SINGLE_THREAD + CAEndpoint_t* ep = endpoint; +#else CAEndpoint_t* ep = CACloneEndpoint(endpoint); if (!ep) { OIC_LOG(ERROR, TAG, "endpoint clone failed"); - OICFree(cadata); - return NULL; + goto exit; } +#endif OIC_LOG_V(DEBUG, TAG, "address : %s", ep->addr); - CAResult_t result; - if(CA_RESPONSE_DATA == dataType) + if (CA_RESPONSE_DATA == dataType) { CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t)); if (!resInfo) { OIC_LOG(ERROR, TAG, "memory allocation failed"); - OICFree(cadata); - CAFreeEndpoint(ep); - return NULL; + goto exit; } - result = CAGetResponseInfoFromPDU(data, resInfo, endpoint); + CAResult_t result = CAGetResponseInfoFromPDU(data, resInfo, endpoint); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TAG, "CAGetResponseInfoFromPDU Failed"); - CAFreeEndpoint(ep); CADestroyResponseInfoInternal(resInfo); - OICFree(cadata); - return NULL; + goto exit; } cadata->responseInfo = resInfo; info = &resInfo->info; @@ -181,29 +190,24 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, if (!reqInfo) { OIC_LOG(ERROR, TAG, "memory allocation failed"); - OICFree(cadata); - CAFreeEndpoint(ep); - return NULL; + goto exit; } - result = CAGetRequestInfoFromPDU(data, endpoint, reqInfo); + CAResult_t result = CAGetRequestInfoFromPDU(data, endpoint, reqInfo); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TAG, "CAGetRequestInfoFromPDU failed"); - CAFreeEndpoint(ep); CADestroyRequestInfoInternal(reqInfo); - OICFree(cadata); - return NULL; + goto exit; } - if (CADropSecondMessage(&caglobals.ca.requestHistory, endpoint, reqInfo->info.messageId, + if ((reqInfo->info.type != CA_MSG_CONFIRM) && + CADropSecondMessage(&caglobals.ca.requestHistory, endpoint, reqInfo->info.messageId, reqInfo->info.token, reqInfo->info.tokenLength)) { - OIC_LOG(ERROR, TAG, "Second Request with same Token, Drop it"); - CAFreeEndpoint(ep); + OIC_LOG(INFO, TAG, "Second Request with same Token, Drop it"); CADestroyRequestInfoInternal(reqInfo); - OICFree(cadata); - return NULL; + goto exit; } cadata->requestInfo = reqInfo; @@ -221,19 +225,15 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, if (!errorInfo) { OIC_LOG(ERROR, TAG, "Memory allocation failed!"); - OICFree(cadata); - CAFreeEndpoint(ep); - return NULL; + goto exit; } CAResult_t result = CAGetErrorInfoFromPDU(data, endpoint, errorInfo); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TAG, "CAGetErrorInfoFromPDU failed"); - CAFreeEndpoint(ep); OICFree(errorInfo); - OICFree(cadata); - return NULL; + goto exit; } cadata->errorInfo = errorInfo; @@ -249,30 +249,40 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint, cadata->remoteEndpoint = ep; cadata->dataType = dataType; + OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData OUT"); return cadata; - OIC_LOG(DEBUG, TAG, "CAGenerateHandlerData OUT"); +exit: + OICFree(cadata); +#ifndef SINGLE_THREAD + CAFreeEndpoint(ep); +#endif + return NULL; } static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uint32_t size) { - OIC_LOG(DEBUG, TAG, "IN"); VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint"); VERIFY_NON_NULL_VOID(pdu, TAG, "pdu"); - +#ifdef SINGLE_THREAD + CAEndpoint_t* ep = endpoint; +#else CAEndpoint_t* ep = CACloneEndpoint(endpoint); if (!ep) { OIC_LOG(ERROR, TAG, "clone failed"); return; } +#endif CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(CAResponseInfo_t)); if (!resInfo) { OIC_LOG(ERROR, TAG, "calloc failed"); +#ifndef SINGLE_THREAD CAFreeEndpoint(ep); +#endif return; } @@ -280,13 +290,15 @@ 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_transport_t *) pdu, &(resInfo->info), endpoint); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list"); CADestroyResponseInfoInternal(resInfo); +#ifndef SINGLE_THREAD CAFreeEndpoint(ep); +#endif return; } @@ -294,7 +306,9 @@ static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uin if (NULL == cadata) { OIC_LOG(ERROR, TAG, "memory allocation failed !"); +#ifndef SINGLE_THREAD CAFreeEndpoint(ep); +#endif CADestroyResponseInfoInternal(resInfo); return; } @@ -304,13 +318,23 @@ static void CATimeoutCallback(const CAEndpoint_t *endpoint, const void *pdu, uin cadata->requestInfo = NULL; cadata->responseInfo = resInfo; +#ifdef WITH_BWT + if (CAIsSupportedBlockwiseTransfer(endpoint->adapter)) + { + res = CARemoveBlockDataFromListWithSeed(resInfo->info.token, resInfo->info.tokenLength, + endpoint->port); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CARemoveBlockDataFromListWithSeed failed"); + } + } +#endif // WITH_BWT + #ifdef SINGLE_THREAD CAProcessReceivedData(cadata); #else CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t)); #endif - - OIC_LOG(DEBUG, TAG, "OUT"); } static void CADestroyData(void *data, uint32_t size) @@ -327,11 +351,12 @@ static void CADestroyData(void *data, uint32_t size) OIC_LOG(ERROR, TAG, "cadata is NULL"); return; } - +#ifndef SINGLE_THREAD if (NULL != cadata->remoteEndpoint) { CAFreeEndpoint(cadata->remoteEndpoint); } +#endif if (NULL != cadata->requestInfo) { @@ -385,45 +410,133 @@ static void CAProcessReceivedData(CAData_t *data) g_errorHandler(rep, data->errorInfo); } -#ifdef SINGLE_THREAD CADestroyData(data, sizeof(CAData_t)); -#endif OIC_LOG(DEBUG, TAG, "CAProcessReceivedData OUT"); } #endif #ifndef SINGLE_THREAD - static void CAReceiveThreadProcess(void *threadData) { - OIC_LOG(DEBUG, TAG, "IN"); #ifndef SINGLE_HANDLE CAData_t *data = (CAData_t *) threadData; + OIC_TRACE_BEGIN(%s:CAProcessReceivedData, TAG); CAProcessReceivedData(data); + OIC_TRACE_END(); #else (void)threadData; #endif - OIC_LOG(DEBUG, TAG, "OUT"); } -#endif +#endif // SINGLE_THREAD + +static CAResult_t CAProcessMulticastData(const CAData_t *data) +{ + VERIFY_NON_NULL(data, TAG, "data"); + VERIFY_NON_NULL(data->remoteEndpoint, TAG, "remoteEndpoint"); + + coap_pdu_t *pdu = NULL; + CAInfo_t *info = NULL; + coap_list_t *options = NULL; + coap_transport_t transport = COAP_UDP; + CAResult_t res = CA_SEND_FAILED; + + if (!data->requestInfo && !data->responseInfo) + { + OIC_LOG(ERROR, TAG, "request or response info is empty"); + return res; + } + + if (data->requestInfo) + { + OIC_LOG(DEBUG, TAG, "requestInfo is available.."); + + info = &data->requestInfo->info; + pdu = CAGeneratePDU(CA_GET, info, data->remoteEndpoint, &options, &transport); + } + else if (data->responseInfo) + { + OIC_LOG(DEBUG, TAG, "responseInfo is available.."); + + info = &data->responseInfo->info; + pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint, + &options, &transport); + } + + if (!pdu) + { + OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU"); + CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED); + coap_delete_list(options); + return res; + } + +#ifdef WITH_BWT + if (CAIsSupportedBlockwiseTransfer(data->remoteEndpoint->adapter)) + { + // Blockwise transfer + res = CAAddBlockOption(&pdu, info, data->remoteEndpoint, &options); + if (CA_STATUS_OK != res) + { + OIC_LOG(DEBUG, TAG, "CAAddBlockOption has failed"); + goto exit; + } + } +#endif // WITH_BWT + + CALogPDUInfo(data, pdu); + + res = CASendMulticastData(data->remoteEndpoint, pdu->transport_hdr, pdu->length, data->dataType); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(ERROR, TAG, "send failed:%d", res); + goto exit; + } + + coap_delete_list(options); + coap_delete_pdu(pdu); + return res; + +exit: + CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res); + coap_delete_list(options); + coap_delete_pdu(pdu); + return res; +} static CAResult_t CAProcessSendData(const CAData_t *data) { - OIC_LOG(DEBUG, TAG, "IN"); VERIFY_NON_NULL(data, TAG, "data"); VERIFY_NON_NULL(data->remoteEndpoint, TAG, "remoteEndpoint"); CAResult_t res = CA_STATUS_FAILED; + if (CA_NETWORK_COMMAND == data->dataType) + { + if (CA_REQ_DISCONNECT == data->eventInfo) + { +#ifdef TCP_ADAPTER + // request TCP disconnect + if (CA_ADAPTER_TCP == data->remoteEndpoint->adapter) + { + OIC_LOG(INFO, TAG, "request TCP disconnect"); + return CADisconnectSession(data->remoteEndpoint); + } +#endif + } + } + CASendDataType_t type = data->type; coap_pdu_t *pdu = NULL; CAInfo_t *info = NULL; + coap_list_t *options = NULL; + coap_transport_t transport = COAP_UDP; 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 @@ -440,7 +553,8 @@ static CAResult_t CAProcessSendData(const CAData_t *data) #ifdef ROUTING_GATEWAY skipRetransmission = data->requestInfo->info.skipRetransmission; #endif - pdu = CAGeneratePDU(data->requestInfo->method, info, data->remoteEndpoint); + pdu = CAGeneratePDU(data->requestInfo->method, info, data->remoteEndpoint, + &options, &transport); } else if (NULL != data->responseInfo) { @@ -450,7 +564,8 @@ static CAResult_t CAProcessSendData(const CAData_t *data) #ifdef ROUTING_GATEWAY skipRetransmission = data->responseInfo->info.skipRetransmission; #endif - pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint); + pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint, + &options, &transport); } else { @@ -462,61 +577,65 @@ static CAResult_t CAProcessSendData(const CAData_t *data) if (NULL != pdu) { #ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter -#ifdef TCP_ADAPTER - && CA_ADAPTER_TCP != data->remoteEndpoint->adapter -#endif - ) + if (CAIsSupportedBlockwiseTransfer(data->remoteEndpoint->adapter)) { // Blockwise transfer if (NULL != info) { CAResult_t res = CAAddBlockOption(&pdu, info, - data->remoteEndpoint); + data->remoteEndpoint, + &options); if (CA_STATUS_OK != res) { OIC_LOG(INFO, TAG, "to write block option has failed"); - CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res); + CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res); + coap_delete_list(options); coap_delete_pdu(pdu); return res; } } } -#endif - CALogPDUInfo(pdu, data->remoteEndpoint); +#endif // WITH_BWT + CALogPDUInfo(data, pdu); - res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length); + OIC_LOG_V(INFO, TAG, "CASendUnicastData type : %d", data->dataType); + res = CASendUnicastData(data->remoteEndpoint, pdu->transport_hdr, pdu->length, data->dataType); if (CA_STATUS_OK != res) { OIC_LOG_V(ERROR, TAG, "send failed:%d", res); - CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res); + CAErrorHandler(data->remoteEndpoint, pdu->transport_hdr, pdu->length, res); + coap_delete_list(options); coap_delete_pdu(pdu); return res; } -#ifdef TCP_ADAPTER - if (CA_ADAPTER_TCP == data->remoteEndpoint->adapter) +#ifdef WITH_TCP + if (CAIsSupportedCoAPOverTCP(data->remoteEndpoint->adapter)) { OIC_LOG(INFO, TAG, "retransmission will be not worked"); } else #endif #ifdef ROUTING_GATEWAY - if(!skipRetransmission) + if (!skipRetransmission) #endif { // for retransmission - res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, - pdu->hdr, pdu->length); + res = CARetransmissionSentData(&g_retransmissionContext, + data->remoteEndpoint, + data->dataType, + pdu->transport_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_list(options); coap_delete_pdu(pdu); return res; } } + coap_delete_list(options); coap_delete_pdu(pdu); } else @@ -529,103 +648,37 @@ static CAResult_t CAProcessSendData(const CAData_t *data) else if (SEND_TYPE_MULTICAST == type) { OIC_LOG(DEBUG,TAG,"Multicast message"); - if (NULL != data->requestInfo) +#ifdef WITH_TCP + /* + * If CoAP over TCP is enabled, the CoAP pdu wont be same for IP and other adapters. + * That's why we need to generate two pdu's, one for IP and second for other transports. + * Two possible cases we might have to split: a) when adapter is CA_DEFAULT_ADAPTER + * b) when one of the adapter is IP adapter(ex: CA_ADAPTER_IP | CA_ADAPTER_GATT_BTLE) + */ + if (data->remoteEndpoint->adapter == CA_DEFAULT_ADAPTER || + (CA_ADAPTER_IP & data->remoteEndpoint->adapter && + CA_ADAPTER_IP != data->remoteEndpoint->adapter)) { - OIC_LOG(DEBUG, TAG, "requestInfo is available.."); - - info = &data->requestInfo->info; - pdu = CAGeneratePDU(CA_GET, info, data->remoteEndpoint); - if (NULL != pdu) + if (data->remoteEndpoint->adapter == CA_DEFAULT_ADAPTER) { -#ifdef WITH_BWT - 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, - data->remoteEndpoint); - if (CA_STATUS_OK != res) - { - OIC_LOG(DEBUG, TAG, "CAAddBlockOption has failed"); - CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res); - coap_delete_pdu(pdu); - return res; - } - } -#endif + data->remoteEndpoint->adapter = CA_ALL_ADAPTERS ^ CA_ADAPTER_IP; } 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.."); - - 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 - ) - { - // 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; - } - } - } -#endif - } - else - { - OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU"); - CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED); - return CA_SEND_FAILED; + data->remoteEndpoint->adapter = data->remoteEndpoint->adapter ^ CA_ADAPTER_IP; } + CAProcessMulticastData(data); + data->remoteEndpoint->adapter = CA_ADAPTER_IP; + CAProcessMulticastData(data); } else { - OIC_LOG(ERROR, TAG, "request or response info is empty"); - return CA_SEND_FAILED; + CAProcessMulticastData(data); } - - 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); +#else + CAProcessMulticastData(data); +#endif } - return CA_STATUS_OK; } @@ -633,9 +686,10 @@ static CAResult_t CAProcessSendData(const CAData_t *data) static void CASendThreadProcess(void *threadData) { CAData_t *data = (CAData_t *) threadData; + OIC_TRACE_BEGIN(%s:CAProcessSendData, TAG); CAProcessSendData(data); + OIC_TRACE_END(); } - #endif /* @@ -679,7 +733,7 @@ static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, ui if ((familyFlags ^ item->flags) == CA_IPFAMILY_MASK) { OIC_LOG_V(INFO, TAG, "IPv%c duplicate message ignored", - familyFlags & CA_IPV6 ? '6' : '4'); + familyFlags & CA_IPV6 ? '6' : '4'); ret = true; break; } @@ -702,16 +756,33 @@ static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, ui return ret; } -static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, - const void *data, uint32_t dataLen) +static CAResult_t CAReceivedPacketCallback(const CASecureEndpoint_t *sep, + const void *data, uint32_t dataLen) { - OIC_LOG(DEBUG, TAG, "IN"); - VERIFY_NON_NULL_VOID(sep, TAG, "remoteEndpoint"); - VERIFY_NON_NULL_VOID(data, TAG, "data"); + VERIFY_NON_NULL(sep, TAG, "remoteEndpoint"); + VERIFY_NON_NULL(data, TAG, "data"); + OIC_TRACE_BEGIN(%s:CAReceivedPacketCallback, TAG); + if (0 == dataLen) + { + OIC_LOG(ERROR, TAG, "dataLen is zero"); + OIC_TRACE_END(); + + return CA_STATUS_FAILED; + } + + // samsung log OIC_LOG(DEBUG, TAG, "received pdu data :"); - OIC_LOG_BUFFER(DEBUG, TAG, data, dataLen); + if (dataLen < 32) + { + OIC_LOG_BUFFER(DEBUG, TAG, data, dataLen); + } + else + { + OIC_LOG_BUFFER(DEBUG, TAG, data, 32); + } + CAResult_t res = CA_STATUS_OK; uint32_t code = CA_NOT_FOUND; CAData_t *cadata = NULL; @@ -720,7 +791,8 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, if (NULL == pdu) { OIC_LOG(ERROR, TAG, "Parse PDU failed"); - return; + res = CA_STATUS_FAILED; + goto exit; } OIC_LOG_V(DEBUG, TAG, "code = %d", code); @@ -731,7 +803,7 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, { OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!"); coap_delete_pdu(pdu); - return; + goto exit; } } else @@ -741,11 +813,11 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, { OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!"); coap_delete_pdu(pdu); - return; + goto exit; } -#ifdef TCP_ADAPTER - if (CA_ADAPTER_TCP == sep->endpoint.adapter) +#ifdef WITH_TCP + if (CAIsSupportedCoAPOverTCP(sep->endpoint.adapter)) { OIC_LOG(INFO, TAG, "retransmission is not supported"); } @@ -754,7 +826,7 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, { // for retransmission void *retransmissionPdu = NULL; - CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->hdr, + CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->transport_hdr, pdu->length, &retransmissionPdu); // get token from saved data in retransmission list @@ -763,7 +835,7 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, if (cadata->responseInfo) { CAInfo_t *info = &cadata->responseInfo->info; - CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu, + CAResult_t res = CAGetTokenFromPDU((const coap_hdr_transport_t *)retransmissionPdu, info, &(sep->endpoint)); if (CA_STATUS_OK != res) { @@ -779,20 +851,18 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, cadata->type = SEND_TYPE_UNICAST; + CALogPDUInfo(cadata, pdu); + #ifdef SINGLE_THREAD CAProcessReceivedData(cadata); #else #ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != sep->endpoint.adapter -#ifdef TCP_ADAPTER - && CA_ADAPTER_TCP != sep->endpoint.adapter -#endif - ) + if (CAIsSupportedBlockwiseTransfer(sep->endpoint.adapter)) { CAResult_t res = CAReceiveBlockWiseData(pdu, &(sep->endpoint), cadata, dataLen); - if (CA_NOT_SUPPORTED == res) + if (CA_NOT_SUPPORTED == res || CA_REQUEST_TIMEOUT == res) { - OIC_LOG(ERROR, TAG, "this message does not have block option"); + OIC_LOG(DEBUG, TAG, "this message does not have block option"); CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t)); } else @@ -805,20 +875,60 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, { CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t)); } -#endif +#endif // SINGLE_THREAD coap_delete_pdu(pdu); - OIC_LOG(DEBUG, TAG, "OUT"); +exit: + OIC_LOG(DEBUG, TAG, "OUT - Recv Thread"); + OIC_TRACE_END(); + return res; +} + +static void CAAdapterStateChangedCallback(CATransportAdapter_t transportType, bool enabled) +{ + if (!enabled) + { + CAClearMessageHandler(transportType); + } } -static void CANetworkChangedCallback(const CAEndpoint_t *info, CANetworkStatus_t status) +static bool CAClearQueueEndpointDataContext(void *data, uint32_t size, void *ctx) { - (void)info; - (void)status; - OIC_LOG(DEBUG, TAG, "IN"); + (void)size; + + if (NULL == data || NULL == ctx) + { + return false; + } + + CAData_t *caData = (CAData_t *)data; + const CAEndpoint_t *endpoint = (const CAEndpoint_t *)ctx; + + if (NULL != caData && NULL != caData->remoteEndpoint) + { + if (strcmp(caData->remoteEndpoint->addr, endpoint->addr) == 0 + && caData->remoteEndpoint->port == endpoint->port + && caData->remoteEndpoint->adapter == endpoint->adapter) + { + return true; + } + } + return false; +} - OIC_LOG(DEBUG, TAG, "OUT"); +static void CAConnectionStateChangedCallback(const CAEndpoint_t *info, bool isConnected) +{ + if (!isConnected) + { + CAResult_t res = CAQueueingThreadClearContextData(&g_sendThread, + CAClearQueueEndpointDataContext, + (void *)info); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "Could not clear the send queue"); + } + } } void CAHandleRequestResponseCallbacks() @@ -832,27 +942,19 @@ void CAHandleRequestResponseCallbacks() // #1 parse the data // #2 get endpoint - ca_mutex_lock(g_receiveThread.threadMutex); + oc_mutex_lock(g_receiveThread.threadMutex); u_queue_message_t *item = u_queue_get_element(g_receiveThread.dataQueue); - ca_mutex_unlock(g_receiveThread.threadMutex); - - if (NULL == item) - { - return; - } - - // get values - void *msg = item->msg; + oc_mutex_unlock(g_receiveThread.threadMutex); - if (NULL == msg) + if (NULL == item || NULL == item->msg) { return; } // get endpoint - CAData_t *td = (CAData_t *) msg; + CAData_t *td = (CAData_t *) item->msg; if (td->requestInfo && g_requestHandler) { @@ -870,11 +972,11 @@ void CAHandleRequestResponseCallbacks() g_errorHandler(td->remoteEndpoint, td->errorInfo); } - CADestroyData(msg, sizeof(CAData_t)); + CADestroyData(item->msg, sizeof(CAData_t)); OICFree(item); -#endif /* SINGLE_HANDLE */ -#endif +#endif // SINGLE_HANDLE +#endif // SINGLE_THREAD } static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sendData, @@ -889,165 +991,152 @@ static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sen return NULL; } - if(CA_REQUEST_DATA == dataType) + if (CA_REQUEST_DATA == dataType) { +#ifdef SINGLE_THREAD + CARequestInfo_t *request = (CARequestInfo_t *)sendData; +#else // clone request info CARequestInfo_t *request = CACloneRequestInfo((CARequestInfo_t *)sendData); - - if(!request) + if (!request) { OIC_LOG(ERROR, TAG, "CACloneRequestInfo failed"); - OICFree(cadata); - return NULL; + goto exit; } - +#endif cadata->type = request->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST; cadata->requestInfo = request; } - else if(CA_RESPONSE_DATA == dataType) + else if (CA_RESPONSE_DATA == dataType || CA_RESPONSE_FOR_RES == dataType) { +#ifdef SINGLE_THREAD + CAResponseInfo_t *response = (CAResponseInfo_t *)sendData; +#else // clone response info CAResponseInfo_t *response = CACloneResponseInfo((CAResponseInfo_t *)sendData); - - if(!response) + if (!response) { OIC_LOG(ERROR, TAG, "CACloneResponseInfo failed"); - OICFree(cadata); - return NULL; + goto exit; } - +#endif cadata->type = response->isMulticast ? SEND_TYPE_MULTICAST : SEND_TYPE_UNICAST; cadata->responseInfo = response; } else { OIC_LOG(ERROR, TAG, "CAPrepareSendData unknown data type"); - OICFree(cadata); - return NULL; + goto exit; } +#ifdef SINGLE_THREAD + CAEndpoint_t* ep = endpoint; +#else CAEndpoint_t* ep = CACloneEndpoint(endpoint); if (!ep) { OIC_LOG(ERROR, TAG, "endpoint clone failed"); - CADestroyData(cadata, sizeof(CAData_t)); - return NULL; + goto exit; } - +#endif cadata->remoteEndpoint = ep; cadata->dataType = dataType; return cadata; + +exit: +#ifndef SINGLE_THREAD + CADestroyData(cadata, sizeof(CAData_t)); +#else + OICFree(cadata); +#endif + return NULL; } -CAResult_t CADetachRequestMessage(const CAEndpoint_t *object, const CARequestInfo_t *request) +CAResult_t CADetachSendNetworkReqMessage(const CAEndpoint_t *endpoint, + CAConnectEvent_t event, + CADataType_t dataType) { - OIC_LOG(DEBUG, TAG, "IN"); - - VERIFY_NON_NULL(object, TAG, "object"); - VERIFY_NON_NULL(request, TAG, "request"); + VERIFY_NON_NULL(endpoint, TAG, "endpoint"); if (false == CAIsSelectedNetworkAvailable()) { return CA_STATUS_FAILED; } -#ifdef ARDUINO - // If max retransmission queue is reached, then don't handle new request - if (CA_MAX_RT_ARRAY_SIZE == u_arraylist_length(g_retransmissionContext.dataList)) +#ifndef SINGLE_THREAD + CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); + if (!cadata) { - OIC_LOG(ERROR, TAG, "max RT queue size reached!"); - return CA_SEND_FAILED; + OIC_LOG(ERROR, TAG, "cadata memory allocation failed"); + return CA_STATUS_FAILED; } -#endif /* ARDUINO */ - CAData_t *data = CAPrepareSendData(object, request, CA_REQUEST_DATA); - if(!data) + CAEndpoint_t* ep = CACloneEndpoint(endpoint); + if (!ep) { - OIC_LOG(ERROR, TAG, "CAPrepareSendData failed"); - return CA_MEMORY_ALLOC_FAILED; + OIC_LOG(ERROR, TAG, "endpoint clone failed"); + OICFree(cadata); + return CA_STATUS_FAILED; } -#ifdef SINGLE_THREAD - CAResult_t result = CAProcessSendData(data); - if(CA_STATUS_OK != result) - { - OIC_LOG(ERROR, TAG, "CAProcessSendData failed"); - return result; - } + cadata->remoteEndpoint = ep; + cadata->eventInfo = event; + cadata->dataType = dataType; - CADestroyData(data, sizeof(CAData_t)); -#else -#ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != object->adapter -#ifdef TCP_ADAPTER - && CA_ADAPTER_TCP != object->adapter -#endif - ) - { - // send block data - CAResult_t res = CASendBlockWiseData(data); - if(CA_NOT_SUPPORTED == res) - { - OIC_LOG(DEBUG, TAG, "normal msg will be sent"); - CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); - return CA_STATUS_OK; - } - else - { - CADestroyData(data, sizeof(CAData_t)); - } - return res; - } - else -#endif - { - CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); - } + CAQueueingThreadAddData(&g_sendThread, cadata, sizeof(CAData_t)); #endif - OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } -CAResult_t CADetachResponseMessage(const CAEndpoint_t *object, - const CAResponseInfo_t *response) +CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint, const void *sendMsg, + CADataType_t dataType) { - OIC_LOG(DEBUG, TAG, "IN"); - VERIFY_NON_NULL(object, TAG, "object"); - VERIFY_NON_NULL(response, TAG, "response"); + VERIFY_NON_NULL(endpoint, TAG, "endpoint"); + VERIFY_NON_NULL(sendMsg, TAG, "sendMsg"); if (false == CAIsSelectedNetworkAvailable()) { return CA_STATUS_FAILED; } - CAData_t *data = CAPrepareSendData(object, response, CA_RESPONSE_DATA); +#ifdef ARDUINO + // If max retransmission queue is reached, then don't handle new request + if (CA_MAX_RT_ARRAY_SIZE == u_arraylist_length(g_retransmissionContext.dataList)) + { + OIC_LOG(ERROR, TAG, "max RT queue size reached!"); + return CA_SEND_FAILED; + } +#endif // ARDUINO + + CAData_t *data = CAPrepareSendData(endpoint, sendMsg, dataType); if(!data) { OIC_LOG(ERROR, TAG, "CAPrepareSendData failed"); return CA_MEMORY_ALLOC_FAILED; } + OIC_LOG_V(INFO_PRIVATE, TAG, "DID of endpoint of this message is %s", endpoint->remoteId); + #ifdef SINGLE_THREAD CAResult_t result = CAProcessSendData(data); - if(result != CA_STATUS_OK) + if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TAG, "CAProcessSendData failed"); + OICFree(data); return result; } - CADestroyData(data, sizeof(CAData_t)); + OICFree(data); + #else #ifdef WITH_BWT - if (CA_ADAPTER_GATT_BTLE != object->adapter -#ifdef TCP_ADAPTER - && CA_ADAPTER_TCP != object->adapter -#endif - ) + if (CAIsSupportedBlockwiseTransfer(endpoint->adapter)) { + CACheckAndDeleteTimedOutBlockData(); // send block data CAResult_t res = CASendBlockWiseData(data); - if(CA_NOT_SUPPORTED == res) + if (CA_NOT_SUPPORTED == res) { OIC_LOG(DEBUG, TAG, "normal msg will be sent"); CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); @@ -1057,53 +1146,40 @@ CAResult_t CADetachResponseMessage(const CAEndpoint_t *object, { CADestroyData(data, sizeof(CAData_t)); } + return res; } else -#endif +#endif // WITH_BWT { CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); } -#endif +#endif // SINGLE_THREAD - OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } -CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token, - uint8_t tokenLength, const CAHeaderOption_t *options, - uint8_t numOptions) -{ - (void)resourceUri; - (void)token; - (void)tokenLength; - (void)options; - (void)numOptions; - return CA_NOT_SUPPORTED; -} - void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler, CAErrorCallback errorHandler) { - OIC_LOG(DEBUG, TAG, "IN"); g_requestHandler = ReqHandler; g_responseHandler = RespHandler; g_errorHandler = errorHandler; - OIC_LOG(DEBUG, TAG, "OUT"); } -CAResult_t CAInitializeMessageHandler() +void CASetNetworkMonitorCallback(CANetworkMonitorCallback nwMonitorHandler) { - OIC_LOG(DEBUG, TAG, "IN"); - CASetPacketReceivedCallback(CAReceivedPacketCallback); + g_nwMonitorHandler = nwMonitorHandler; +} - CASetNetworkChangeCallback(CANetworkChangedCallback); +CAResult_t CAInitializeMessageHandler(CATransportAdapter_t transportType) +{ + CASetPacketReceivedCallback(CAReceivedPacketCallback); CASetErrorHandleCallback(CAErrorHandler); #ifndef SINGLE_THREAD // create thread pool CAResult_t res = ca_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle); - if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "thread pool initialize error."); @@ -1111,55 +1187,66 @@ CAResult_t CAInitializeMessageHandler() } // send thread initialize - if (CA_STATUS_OK != CAQueueingThreadInitialize(&g_sendThread, g_threadPoolHandle, - CASendThreadProcess, CADestroyData)) + res = CAQueueingThreadInitialize(&g_sendThread, g_threadPoolHandle, + CASendThreadProcess, CADestroyData); + if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread"); - return CA_STATUS_FAILED; + return res; } // start send thread +#ifndef __TIZENRT__ res = CAQueueingThreadStart(&g_sendThread); - +#else + res = CAQueueingThreadStart(&g_sendThread, "IoT_MessageHandlerQueue"); +#endif if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "thread start error(send thread)."); - ca_thread_pool_free(g_threadPoolHandle); - g_threadPoolHandle = NULL; return res; } // receive thread initialize - if (CA_STATUS_OK != CAQueueingThreadInitialize(&g_receiveThread, g_threadPoolHandle, - CAReceiveThreadProcess, CADestroyData)) + res = CAQueueingThreadInitialize(&g_receiveThread, g_threadPoolHandle, + CAReceiveThreadProcess, CADestroyData); + if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "Failed to Initialize receive queue thread"); - return CA_STATUS_FAILED; + return res; } #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading // start receive thread - res = CAQueueingThreadStart(&gReceiveThread); - - if (res != CA_STATUS_OK) + res = CAQueueingThreadStart(&g_receiveThread); + if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "thread start error(receive thread)."); return res; } -#endif /* SINGLE_HANDLE */ +#endif // SINGLE_HANDLE // retransmission initialize - CARetransmissionInitialize(&g_retransmissionContext, g_threadPoolHandle, CASendUnicastData, - CATimeoutCallback, NULL); + res = CARetransmissionInitialize(&g_retransmissionContext, g_threadPoolHandle, + CASendUnicastData, CATimeoutCallback, NULL); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "Failed to Initialize Retransmission."); + return res; + } #ifdef WITH_BWT // block-wise transfer initialize - CAInitializeBlockWiseTransfer(CAAddDataToSendThread, CAAddDataToReceiveThread); + res = CAInitializeBlockWiseTransfer(CAAddDataToSendThread, CAAddDataToReceiveThread); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "Failed to Initialize BlockWiseTransfer."); + return res; + } #endif // start retransmission res = CARetransmissionStart(&g_retransmissionContext); - if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "thread start error(retransmission thread)."); @@ -1167,21 +1254,69 @@ CAResult_t CAInitializeMessageHandler() } // initialize interface adapters by controller - CAInitializeAdapters(g_threadPoolHandle); + CAInitializeAdapters(g_threadPoolHandle, transportType); + CASetNetworkMonitorCallbacks(CAAdapterStateChangedCallback, CAConnectionStateChangedCallback); #else // retransmission initialize - CARetransmissionInitialize(&g_retransmissionContext, NULL, CASendUnicastData, - CATimeoutCallback, NULL); + CAResult_t res = CARetransmissionInitialize(&g_retransmissionContext, NULL, CASendUnicastData, + CATimeoutCallback, NULL); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "Failed to Initialize Retransmission."); + return res; + } + CAInitializeAdapters(); -#endif +#endif // SINGLE_THREAD - OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } +static bool CAClearQueueAdapterDataContext(void *data, uint32_t size, void *ctx) +{ + (void)size; + + if (NULL == data || NULL == ctx) + { + return false; + } + + CAData_t *caData = (CAData_t *)data; + CATransportAdapter_t *type = (CATransportAdapter_t *)ctx; + + if (NULL != caData && NULL != caData->remoteEndpoint + && caData->remoteEndpoint->adapter == *type) + { + return true; + } + return false; +} + +void CAClearMessageHandler(CATransportAdapter_t transportType) +{ + CATransportAdapter_t *typeCtx = &transportType; + + CAResult_t res = CAQueueingThreadClearContextData(&g_sendThread, + CAClearQueueAdapterDataContext, + typeCtx); + + if (res != CA_STATUS_OK) + { + OIC_LOG_V(ERROR, TAG, "Clear send data failed[%d]", res); + } + + if (transportType & DEFAULT_RETRANSMISSION_TYPE) + { + res = CARetransmissionClearAdapterData(&g_retransmissionContext, transportType); + if (res != CA_STATUS_OK) + { + OIC_LOG_V(ERROR, TAG, "Clear retransmission data failed[%d]", res); + } + } +} + void CATerminateMessageHandler() { - OIC_LOG(DEBUG, TAG, "IN"); #ifndef SINGLE_THREAD CATransportAdapter_t connType; u_arraylist_t *list = CAGetSelectedNetworkList(); @@ -1219,8 +1354,8 @@ void CATerminateMessageHandler() if (NULL != g_receiveThread.threadMutex) { #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading - CAQueueingThreadStop(&gReceiveThread); -#endif /* SINGLE_HANDLE */ + CAQueueingThreadStop(&g_receiveThread); +#endif } // destroy thread pool @@ -1246,46 +1381,18 @@ void CATerminateMessageHandler() // stop retransmission CARetransmissionStop(&g_retransmissionContext); CARetransmissionDestroy(&g_retransmissionContext); -#endif - - OIC_LOG(DEBUG, TAG, "OUT"); -} - -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); - -#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->coap_hdr_udp_t.code); - - OIC_LOG(DEBUG, TAG, "PDU Maker - token :"); - - OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->coap_hdr_udp_t.token, - pdu->hdr->coap_hdr_udp_t.token_length); - } +#endif // SINGLE_THREAD } static void CALogPayloadInfo(CAInfo_t *info) { - if(info) + if (info) { if (info->options) { for (uint32_t i = 0; i < info->numOptions; i++) { - OIC_LOG_V(DEBUG, TAG, "optionID: %d", info->options[i].optionID); + OIC_LOG_V(DEBUG, TAG, "optionID: %u", info->options[i].optionID); OIC_LOG_V(DEBUG, TAG, "list: %s", info->options[i].optionData); } @@ -1293,7 +1400,7 @@ static void CALogPayloadInfo(CAInfo_t *info) if (info->payload) { - OIC_LOG_V(DEBUG, TAG, "payload: %p(%u)", info->payload, + OIC_LOG_V(DEBUG, TAG, "payload: %p(%zu)", info->payload, info->payloadSize); } @@ -1303,7 +1410,7 @@ static void CALogPayloadInfo(CAInfo_t *info) OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) info->token, info->tokenLength); } - OIC_LOG_V(DEBUG, TAG, "msgID: %d", info->messageId); + OIC_LOG_V(DEBUG, TAG, "msgID: %u", info->messageId); } else { @@ -1316,12 +1423,16 @@ void CAErrorHandler(const CAEndpoint_t *endpoint, CAResult_t result) { OIC_LOG(DEBUG, TAG, "CAErrorHandler IN"); - -#ifndef SINGLE_THREAD - VERIFY_NON_NULL_VOID(endpoint, TAG, "remoteEndpoint"); VERIFY_NON_NULL_VOID(data, TAG, "data"); + if (0 == dataLen) + { + OIC_LOG(ERROR, TAG, "dataLen is zero"); + return; + } + +#ifndef SINGLE_THREAD uint32_t code = CA_NOT_FOUND; //Do not free remoteEndpoint and data. Currently they will be freed in data thread //Get PDU data @@ -1333,7 +1444,7 @@ void CAErrorHandler(const CAEndpoint_t *endpoint, } CAData_t *cadata = CAGenerateHandlerData(endpoint, NULL, pdu, CA_ERROR_DATA); - if(!cadata) + if (!cadata) { OIC_LOG(ERROR, TAG, "CAErrorHandler, CAGenerateHandlerData failed!"); coap_delete_pdu(pdu); @@ -1344,6 +1455,8 @@ void CAErrorHandler(const CAEndpoint_t *endpoint, CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t)); coap_delete_pdu(pdu); +#else + (void)result; #endif OIC_LOG(DEBUG, TAG, "CAErrorHandler OUT"); @@ -1357,7 +1470,7 @@ static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info, CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); if (!cadata) { - OIC_LOG(ERROR, TAG, "memory allocation failed"); + OIC_LOG(ERROR, TAG, "cadata memory allocation failed"); return; } @@ -1372,6 +1485,7 @@ static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info, CAErrorInfo_t *errorInfo = (CAErrorInfo_t *)OICCalloc(1, sizeof (CAErrorInfo_t)); if (!errorInfo) { + OIC_LOG(ERROR, TAG, "errorInfo memory allocation failed"); OICFree(cadata); CAFreeEndpoint(ep); return; @@ -1380,6 +1494,7 @@ static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info, CAResult_t res = CACloneInfo(info, &errorInfo->info); if (CA_STATUS_OK != res) { + OIC_LOG(ERROR, TAG, "info clone failed"); OICFree(cadata); OICFree(errorInfo); CAFreeEndpoint(ep); @@ -1395,3 +1510,311 @@ static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info, #endif OIC_LOG(DEBUG, TAG, "CASendErrorInfo OUT"); } + + + +#ifndef ARDUINO +#ifdef __TIZENRT__ +static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu) +{ + + if(data == NULL || pdu == NULL) + { + printf("INVALID INPUT, CALogPDUInfo FAIL\n"); + } + + char type[30] = ""; + + switch(data->dataType) + { + case CA_REQUEST_DATA: + strncpy(type, "\e[32mREQUEST <<<<\e[m", 30); + break; + case CA_RESPONSE_DATA: + strncpy(type, "\e[36mRESPONSE >>>>\e[m", 30); + break; + case CA_ERROR_DATA: + strncpy(type, "ERROR", 30); + break; + case CA_RESPONSE_FOR_RES: + strncpy(type, "RESP_RES >>>>", 30); + break; + default: + snprintf(type, 30, "Type : %d", data->dataType); + break; + } + + + char method[20] = ""; + const CAInfo_t *info = NULL; + if (NULL != data->requestInfo) + { + switch(data->requestInfo->method) + { + case CA_GET: + strncpy(method, "GET", 20); + break; + case CA_POST: + strncpy(method, "POST", 20); + break; + case CA_PUT: + strncpy(method, "PUT", 20); + break; + case CA_DELETE: + strncpy(method, "DEL", 20); + break; + default: + sprintf(method, "Method : %d", data->requestInfo->method); + break; + } + info = &data->requestInfo->info; + } + + if(NULL != data->responseInfo) + { + + sprintf(method, "result : %d", data->responseInfo->result); + info = &data->responseInfo->info; + } + + + char log_buffer[1024] = ""; + sprintf(log_buffer, "CA_LOG [%5d] | %-13s | %-12s | msg size : %4d | %s", pdu->transport_hdr->udp.id , type, method, pdu->length, info->resourceUri); + + puts(log_buffer); +} + + +#else + +static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu) +{ + OIC_LOG(DEBUG, TAG, "CALogPDUInfo"); + + VERIFY_NON_NULL_VOID(data, TAG, "data"); + VERIFY_NON_NULL_VOID(pdu, TAG, "pdu"); + OIC_TRACE_BEGIN(%s:CALogPDUInfo, TAG); + + OIC_LOG(INFO, ANALYZER_TAG, "================================================="); + if(SEND_TYPE_MULTICAST == data->type) + { + OIC_LOG(INFO, ANALYZER_TAG, "Is Multicast = true"); + } + else + { + OIC_LOG(INFO, ANALYZER_TAG, "Is Multicast = false"); + } + + if (NULL != data->remoteEndpoint) + { + CALogAdapterTypeInfo(data->remoteEndpoint->adapter); + OIC_LOG_V(INFO, ANALYZER_TAG, "Address = [%s]:[%d]", data->remoteEndpoint->addr, + data->remoteEndpoint->port); + } + + switch(data->dataType) + { + case CA_REQUEST_DATA: + OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_REQUEST_DATA]"); + break; + case CA_RESPONSE_DATA: + OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_RESPONSE_DATA]"); + break; + case CA_ERROR_DATA: + OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_ERROR_DATA]"); + break; + case CA_RESPONSE_FOR_RES: + OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_RESPONSE_FOR_RES]"); + break; + default: + OIC_LOG_V(INFO, ANALYZER_TAG, "Data Type = [%d]", data->dataType); + break; + } + + const CAInfo_t *info = NULL; + if (NULL != data->requestInfo) + { + switch(data->requestInfo->method) + { + case CA_GET: + OIC_LOG(INFO, ANALYZER_TAG, "Method = [GET]"); + break; + case CA_POST: + OIC_LOG(INFO, ANALYZER_TAG, "Method = [POST]"); + break; + case CA_PUT: + OIC_LOG(INFO, ANALYZER_TAG, "Method = [PUT]"); + break; + case CA_DELETE: + OIC_LOG(INFO, ANALYZER_TAG, "Method = [DELETE]"); + break; + default: + OIC_LOG_V(INFO, ANALYZER_TAG, "Method = [%d]", data->requestInfo->method); + break; + } + info = &data->requestInfo->info; + } + + if (NULL != data->responseInfo) + { + OIC_LOG_V(INFO, ANALYZER_TAG, "result code = [%d]", data->responseInfo->result); + info = &data->responseInfo->info; + } + + if (pdu->transport_hdr) + { + OIC_LOG_V(INFO, ANALYZER_TAG, "Msg ID = [%d]", pdu->transport_hdr->udp.id); + } + + if (info) + { + OIC_LOG(INFO, ANALYZER_TAG, "Coap Token"); + OIC_LOG_BUFFER(INFO, ANALYZER_TAG, (const uint8_t *) info->token, info->tokenLength); + OIC_TRACE_BUFFER("OIC_CA_MSG_HANDLE:CALogPDUInfo:token", + (const uint8_t *) info->token, info->tokenLength); + OIC_LOG_V(INFO, ANALYZER_TAG, "Res URI = [%s]", info->resourceUri); + OIC_TRACE_MARK(%s:CALogPDUInfo:uri:%s, TAG, info->resourceUri); + + if (CA_FORMAT_APPLICATION_CBOR == info->payloadFormat) + { + OIC_LOG(INFO, ANALYZER_TAG, "Payload Format = [CA_FORMAT_APPLICATION_CBOR]"); + } + else + { + OIC_LOG_V(INFO, ANALYZER_TAG, "Payload Format = [%d]", info->payloadFormat); + } + } + + size_t payloadLen = (pdu->data) ? (unsigned char *) pdu->hdr + pdu->length - pdu->data : 0; + OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Message Full Size = [%u]", pdu->length); + OIC_LOG(INFO, ANALYZER_TAG, "CoAP Header (+ 0xFF)"); + OIC_LOG_BUFFER(INFO, ANALYZER_TAG, (const uint8_t *) pdu->transport_hdr, + pdu->length - payloadLen); + OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Header size = [%" PRIuPTR "]", (size_t) pdu->length - payloadLen); + + OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload"); + OIC_LOG_BUFFER(INFO_PRIVATE, ANALYZER_TAG, pdu->data, payloadLen); + OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload Size = [%" PRIuPTR "]", payloadLen); + OIC_LOG(INFO, ANALYZER_TAG, "================================================="); + + // samsung log + CASamsungLogMessage(data, pdu); + OIC_TRACE_END(); +} + +static void CASamsungLogMessage(const CAData_t *data, const coap_pdu_t *pdu) +{ + OIC_LOG(INFO, TAG, "CASamsungLogMessage"); + VERIFY_NON_NULL_VOID(data, TAG, "data"); + VERIFY_NON_NULL_VOID(pdu, TAG, "pdu"); + VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "data->remoteEndpoint"); + + const CAInfo_t *info = NULL; + if (NULL != data->requestInfo) + { + info = &data->requestInfo->info; + } + + if (NULL != data->responseInfo) + { + info = &data->responseInfo->info; + } + + VERIFY_NON_NULL_VOID(info, TAG, "info"); + + memset(g_headerBuffer, 0, MAX_LOG_BUFFER_SIZE); + g_headerIndex = 0; + + g_headerBuffer[g_headerIndex++] = data->dataType; + g_headerBuffer[g_headerIndex++] = '|'; + g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->adapter; + g_headerBuffer[g_headerIndex++] = '|'; + g_headerBuffer[g_headerIndex++] = data->type; + g_headerBuffer[g_headerIndex++] = '|'; + + if (NULL != data->remoteEndpoint) + { + int i = 0; + while (data->remoteEndpoint->addr[i]) + { + g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->addr[i]; + i++; + } + g_headerBuffer[g_headerIndex++] = ':'; + g_headerBuffer[g_headerIndex++] = (data->remoteEndpoint->port >> 8) & 0x0000ff; + g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->port & 0x000000ff; + } + + g_headerBuffer[g_headerIndex++] = '|'; + if (data->requestInfo) + { + g_headerBuffer[g_headerIndex++] = data->requestInfo->method; + } + else + { + g_headerBuffer[g_headerIndex++] = 0; + } + + g_headerBuffer[g_headerIndex++] = '|'; + if (data->responseInfo) + { + g_headerBuffer[g_headerIndex++] = data->responseInfo->result; + } + else + { + g_headerBuffer[g_headerIndex++] = 0; + } + g_headerBuffer[g_headerIndex++] = '|'; + + if (pdu->transport_hdr) + { + g_headerBuffer[g_headerIndex++] = (pdu->transport_hdr->udp.id >> 8) & 0x0000ff; + g_headerBuffer[g_headerIndex++] = pdu->transport_hdr->udp.id & 0x000000ff; + } + else + { + g_headerBuffer[g_headerIndex++] = 0; + g_headerBuffer[g_headerIndex++] = 0; + } + g_headerBuffer[g_headerIndex++] = '|'; + + if (info->token && info->tokenLength > 0) + { + for (size_t i = 0; i < info->tokenLength; i++) + { + g_headerBuffer[g_headerIndex++] = info->token[i]; + } + g_headerBuffer[g_headerIndex++] = '|'; + } + + if (info->resourceUri) + { + size_t i = 0; + while (info->resourceUri[i]) + { + g_headerBuffer[g_headerIndex++] = info->resourceUri[i]; + i++; + } + g_headerBuffer[g_headerIndex++] = '|'; + } + + OIC_LOG_CA_BUFFER(INFO, TAG, (uint8_t *) g_headerBuffer, g_headerIndex, 1); + size_t payloadLen = (unsigned char *) pdu->hdr + pdu->length - pdu->data; + OIC_LOG_CA_BUFFER(INFO_PRIVATE, TAG, pdu->data, payloadLen, 0); +} +#endif + +#else +static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu) +{ + VERIFY_NON_NULL_VOID(pdu, TAG, "pdu"); + (void)data; + + OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data); + OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->transport_hdr->udp.type); + OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->transport_hdr->udp.code); + OIC_LOG(DEBUG, TAG, "PDU Maker - token :"); + OIC_LOG_BUFFER(DEBUG, TAG, pdu->transport_hdr->udp.token, + pdu->transport_hdr->udp.token_length); +} +#endif