From 872fe72e79577cd52e9a220433aebaf1d1fb11e0 Mon Sep 17 00:00:00 2001 From: "jihwan.seo" Date: Fri, 27 Mar 2015 18:18:12 +0900 Subject: [PATCH] RESET/ACK code review update. updating review comment changes Re factored PDU creation API for better usage Changed debug to error logs during critical conditions. https://gerrit.iotivity.org/gerrit/#/c/303/ Signed-off-by: jihwan.seo Change-Id: I5d5b82ab7368fb7c30bf1055dda6331613240051 Signed-off-by: jihwan.seo Reviewed-on: https://gerrit.iotivity.org/gerrit/589 Tested-by: jenkins-iotivity Reviewed-by: Erich Keane --- resource/csdk/connectivity/api/cacommon.h | 18 +- resource/csdk/connectivity/inc/camessagehandler.h | 64 ++- .../inc/camessagehandler_singlethread.h | 81 ++-- resource/csdk/connectivity/inc/caprotocolmessage.h | 145 +++--- resource/csdk/connectivity/inc/caretransmission.h | 69 +-- .../inc/caretransmission_singlethread.h | 38 +- resource/csdk/connectivity/src/camessagehandler.c | 501 ++++++++++---------- .../src/camessagehandler_singlethread.c | 285 +++++++----- resource/csdk/connectivity/src/caprotocolmessage.c | 507 ++++++++++++++------- resource/csdk/connectivity/src/caretransmission.c | 155 ++++--- .../src/caretransmission_singlethread.c | 158 ++++--- 11 files changed, 1235 insertions(+), 786 deletions(-) diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index 33e6fb4..b8fad26 100644 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -247,14 +247,16 @@ typedef enum */ typedef enum { - /* Success status code - START HERE */ - CA_SUCCESS = 200, /**< Success */ - CA_CREATED = 201, /**< Created */ - CA_DELETED = 202, /**< Deleted */ - CA_BAD_REQ = 400, /**< Bad Request */ - CA_BAD_OPT = 402, /**< Bad Option */ - CA_NOT_FOUND = 404, /**< Not found */ - CA_RETRANSMIT_TIMEOUT = 500 /**< Retransmit timeout */ + /* Response status code - START HERE */ + CA_EMPTY = 0, /**< Empty */ + CA_SUCCESS = 200, /**< Success */ + CA_CREATED = 201, /**< Created */ + CA_DELETED = 202, /**< Deleted */ + CA_BAD_REQ = 400, /**< Bad Request */ + CA_BAD_OPT = 402, /**< Bad Option */ + CA_NOT_FOUND = 404, /**< Not found */ + CA_INTERNAL_SERVER_ERROR = 500, /**< Internal Server Error */ + CA_RETRANSMIT_TIMEOUT = 504 /**< Retransmit timeout */ /* Response status code - END HERE */ } CAResponseResult_t; diff --git a/resource/csdk/connectivity/inc/camessagehandler.h b/resource/csdk/connectivity/inc/camessagehandler.h index 8e9553e..93c2e60 100644 --- a/resource/csdk/connectivity/inc/camessagehandler.h +++ b/resource/csdk/connectivity/inc/camessagehandler.h @@ -1,4 +1,4 @@ -/* **************************************************************** +/****************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,16 +19,38 @@ ******************************************************************/ /** - * @file - * + * @file camessagehandler.h * @brief This file contains message functionality. */ #ifndef __CA_MESSAGE_HANDLER_H_ #define __CA_MESSAGE_HANDLER_H_ -#include #include "cacommon.h" +#include "coap.h" + +/** + * @def VERIFY_NON_NULL + * @brief Macro to verify the validity of input argument. + */ +#define VERIFY_NON_NULL(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return CA_STATUS_INVALID_PARAM; \ + } \ + +/** + * @def VERIFY_NON_NULL_VOID + * @brief Macro to verify the validity of input argument. + */ +#define VERIFY_NON_NULL_VOID(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return; \ + } \ + +#define CA_MEMORY_ALLOC_CHECK(arg) { if (NULL == arg) {OIC_LOG(ERROR, TAG, "Out of memory"); \ +goto memory_error_exit;} } #ifdef __cplusplus extern "C" @@ -39,16 +61,16 @@ extern "C" * @brief Detaches control from the caller for sending unicast request * @param endpoint [IN] endpoint information where the data has to be sent * @param request [IN] request that needs to be sent - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint, const CARequestInfo_t *request); /** * @brief Detaches control from the caller for sending multicast request - * @param endpoint [IN] endpoint information where the data has to be sent + * @param object [IN] Group endpoint information where the data has to be sent * @param request [IN] request that needs to be sent - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, const CARequestInfo_t *request); @@ -56,15 +78,15 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, /** * @brief Detaches control from the caller for sending response * @param endpoint [IN] endpoint information where the data has to be sent - * @param response [IN] request that needs to be sent - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param response [IN] response that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint, const CAResponseInfo_t *response); /** * @brief Detaches control from the caller for sending request - * @param resourceUri [IN] resource uri that needs to be sent in the request + * @param resourceUri [IN] resource uri that needs to be sent in the request * @param token [IN] token information of the request * @param tokenLength [IN] length of the token * @param options [IN] header options that need to be append in the request @@ -79,28 +101,34 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t * @brief Setting the request and response callbacks for network packets * @param ReqHandler [IN] callback for receiving the requests * @param RespHandler [IN] callback for receiving the response - * @return void + * @return NONE */ -void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, - CAResponseCallback RespHandler); +void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler); /** - * @brief Initialize the message handler by starting thread pool and initializing the send and reive queue - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Initialize the message handler by starting thread pool and initializing the + * send and receive queue + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAInitializeMessageHandler(); /** - * @brief Terminate the message handler by stopping the thread pool and destroying the queues - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Terminate the message handler by stopping the thread pool and destroying the queues + * @return NONE */ void CATerminateMessageHandler(); /** - * @brief Handler for receiving request and response callback in singled thread model + * @brief Handler for receiving request and response callback in single thread model */ void CAHandleRequestResponseCallbacks(); +/** + * @brief To log the PDU data + * @param pdu [IN] pdu data + */ +void CALogPDUInfo(coap_pdu_t *pdu); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/resource/csdk/connectivity/inc/camessagehandler_singlethread.h b/resource/csdk/connectivity/inc/camessagehandler_singlethread.h index f2833a1..0c68faa 100644 --- a/resource/csdk/connectivity/inc/camessagehandler_singlethread.h +++ b/resource/csdk/connectivity/inc/camessagehandler_singlethread.h @@ -1,4 +1,4 @@ -/* **************************************************************** +/****************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,18 +19,38 @@ ******************************************************************/ /** - * @file - * - * This file contains message functionality. + * @file camessagehandler_singlethread.h + * @brief This file contains message functionality. */ #ifndef __CA_MESSAGE_HANDLER_SINGLETHREAD_H_ #define __CA_MESSAGE_HANDLER_SINGLETHREAD_H_ -#include #include "cacommon.h" -#include "cainterface.h" -#include "caretransmission_singlethread.h" +#include "coap.h" + +/** + * @def VERIFY_NON_NULL + * @brief Macro to verify the validity of input argument. + */ +#define VERIFY_NON_NULL(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return CA_STATUS_INVALID_PARAM; \ + } \ + +/** + * @def VERIFY_NON_NULL_VOID + * @brief Macro to verify the validity of input argument. + */ +#define VERIFY_NON_NULL_VOID(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return; \ + } \ + +#define CA_MEMORY_ALLOC_CHECK(arg) { if (NULL == arg) {OIC_LOG(ERROR, TAG, "Out of memory"); \ +goto memory_error_exit;} } #ifdef __cplusplus extern "C" @@ -39,29 +59,29 @@ extern "C" /** * @brief Detaches control from the caller for sending unicast request - * @param endpoint [IN] endpoint information where the data has to be sent - * @param request [IN] request that needs to be sent - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param endpoint [IN] endpoint information where the data has to be sent + * @param request [IN] request that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint, const CARequestInfo_t *request); /** * @brief Detaches control from the caller for sending multicast request - * @param object [IN] Group endpoint information where the data has to be sent - * @param request [IN] request that needs to be sent - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param object [IN] Group endpoint information where the data has to be sent + * @param request [IN] request that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, const CARequestInfo_t *request); /** * @brief Detaches control from the caller for sending response - * @param object [IN] endpoint information where the data has to be sent - * @param response [IN] request that needs to be sent - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param endpoint [IN] endpoint information where the data has to be sent + * @param response [IN] response that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ -CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object, +CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint, const CAResponseInfo_t *response); /** @@ -79,31 +99,36 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t /** * @brief Setting the request and response callbacks for network packets - * @param ReqHandler [IN] callback for receiving the requests - * @param RespHandler [IN] callback for receiving the response - * @return void + * @param ReqHandler [IN] callback for receiving the requests + * @param RespHandler [IN] callback for receiving the response + * @return NONE */ -void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, - CAResponseCallback RespHandler); +void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler); /** - * @brief Initialize the message handler by starting thread pool and initializing the - * send and receive queue - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Initialize the message handler by starting thread pool and initializing the + * send and receive queue + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAInitializeMessageHandler(); /** - * @brief Terminate the message handler by stopping the thread pool and destroying the queues - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Terminate the message handler by stopping the thread pool and destroying the queues + * @return NONE */ void CATerminateMessageHandler(); /** - * @brief Handler for receiving request and response callback in singled thread model + * @brief Handler for receiving request and response callback in single thread model */ void CAHandleRequestResponseCallbacks(); +/** + * @brief To log the PDU data + * @param pdu [IN] pdu data + */ +void CALogPDUInfo(coap_pdu_t *pdu); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/resource/csdk/connectivity/inc/caprotocolmessage.h b/resource/csdk/connectivity/inc/caprotocolmessage.h index e0e9b94..d47a9ec 100644 --- a/resource/csdk/connectivity/inc/caprotocolmessage.h +++ b/resource/csdk/connectivity/inc/caprotocolmessage.h @@ -1,4 +1,4 @@ -/* **************************************************************** +/****************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -17,11 +17,9 @@ * limitations under the License. * ******************************************************************/ - /** - * @file - * - * This file contains common function for handling protocol messages. + * @file caprotocolmessage.h + * @brief This file contains common function for handling protocol messages. */ #ifndef __CA_PROTOCOL_MESSAGE_H_ @@ -38,17 +36,18 @@ extern "C" #endif typedef uint32_t code_t; + #define CA_RESPONSE_CLASS(C) (((C) >> 5)*100) #define CA_RESPONSE_CODE(C) (CA_RESPONSE_CLASS(C) + (C - COAP_RESPONSE_CODE(CA_RESPONSE_CLASS(C)))) /** * @brief generates pdu structure from the given information. - * @param uri [IN] uri information of the pdu - * @param code [IN] code of the pdu packet - * @param info [IN] pdu information such as request code, response code and payload - * @return coap_pdu_t created pdu + * @param uri [IN] uri information of the pdu + * @param code [IN] code of the pdu packet + * @param info [IN] pdu information + * @return generated pdu */ -coap_pdu_t *CAGeneratePdu(const char *uri, uint32_t code, const CAInfo_t info); +coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info); /** * function for generating @@ -60,10 +59,10 @@ coap_pdu_t *CAGeneratePdu(const char *uri, uint32_t code, const CAInfo_t info); * @param outReqInfo [OUT] request info structure made from received pdu * @param outUri [OUT] uri received in the received pdu * @param buflen [IN] Buffer Length for outUri parameter - * @return None + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -void CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, - char *outUri, uint32_t buflen); +CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, char *outUri, + uint32_t buflen); /** * @brief extracts response information from received pdu. @@ -71,62 +70,74 @@ void CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, * @param outResInfo [OUT] response info structure made from received pdu * @param outUri [OUT] uri received in the received pdu * @param buflen [IN] Buffer Length for outUri parameter - * @return None + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -void CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, - char *outUri, uint32_t buflen); +CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, + char *outUri, uint32_t buflen); /** * @brief creates pdu from the request information - * @param code [IN] request or response code - * @param options [OUT] options for the request and response - * @param info [IN] information to create pdu - * @param payload [IN] payload for the request or response consumed - * @return coap_pdu_t + * @param code [IN] request or response code + * @param options [OUT] options for the request and response + * @param info [IN] information to create pdu + * @param payload [IN] payload for the request or response consumed + * @return generated pdu */ -coap_pdu_t *CAGeneratePduImpl(const code_t code, coap_list_t *options, - const CAInfo_t info, const char *payload); +coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t info, + const char *payload); /** * @brief parse the URI and creates the options - * @param uriInfo [IN] uri information - * @param options [OUT] options information - * @return None + * @param uriInfo [IN] uri information + * @param options [OUT] options information + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAParseURI(const char *uriInfo, coap_list_t **options); + +/** + * @brief Helper that uses libcoap to parse either the path or the parameters of a URI + * and populate the supplied options list. + * + * @param str [IN] the input partial URI string (either path or query) + * @param length [IN] the length of the supplied partial URI + * @param target [IN] the part of the URI to parse (either COAP_OPTION_URI_PATH + * or COAP_OPTION_URI_QUERY) + * @param optlist [OUT] options information + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -void CAParseURI(const char *uriInfo, coap_list_t **options); +CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target, + coap_list_t **optlist); /** * @brief create option list from header information in the info - * @param code [IN] uri information - * @param info [IN] options information - * @param optlist [OUT] options information - * @return None + * @param code [IN] uri information + * @param info [IN] information of the request/response + * @param optlist [OUT] options information + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -void CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **optlist); +CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **optlist); /** - * Creates option node from key length and data. - * Need to replace queue head if new node has to be added before the existing - * queue head - * @param key [IN] key for the that needs to be sent - * @param length [IN] length of the data that needs to be sent - * @param data [IN] data that needs to be sent + * @brief creates option node from key length and data + * @param key [IN] key for the that needs to be sent + * @param length [IN] length of the data that needs to be sent + * @param data [IN] data that needs to be sent * @return created list */ -coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, - const uint8_t *data); +coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, const uint8_t *data); /** * @brief order the inserted options - * @param a [IN] option 1 for insertion - * @param b [IN] option 2 for insertion + * need to replace queue head if new node has to be added before the existing queue head + * @param a [IN] option 1 for insertion + * @param b [IN] option 2 for insertion * @return 0 or 1 */ int CAOrderOpts(void *a, void *b); /** * @brief number of options count - * @param opt_iter [IN] option iteration for count + * @param opt_iter [IN] option iteration for count * @return number of options */ uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter); @@ -148,21 +159,29 @@ uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *option, uin * @param outInfo [OUT] request info structure made from received pdu * @param outUri [OUT] uri received in the received pdu * @param buflen [IN] Buffer Length for outUri parameter - * @return None + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -void CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, - char *outUri, uint32_t buflen); +CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, + char *outUri, uint32_t buflen); /** * @brief create pdu from received data - * @param data [IN] received data - * @param length [IN] length of the data received - * @param outCode [OUT] code received - * @return None + * @param data [IN] received data + * @param length [IN] length of the data received + * @param outCode [OUT] code received + * @return coap_pdu_t value */ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode); /** + * @brief get Token fromn received data(pdu) + * @param pdu_hdr [IN] header of received pdu + * @param outInfo [OUT] information with token received + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo); + +/** * @brief generates the token * @param token [OUT] generated token * @param tokenLength [IN] length of the token @@ -171,35 +190,43 @@ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode); CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength); /** - * @brief destroys the token - * @param token [IN] generated token - * @return none + * @brief destroys the token + * @param token [IN] generated token + * @return None */ void CADestroyTokenInternal(CAToken_t token); /** * @brief destroy the ca info structure - * @param info [IN] info structure created from received packet - * @return none + * @param info [IN] info structure created from received packet + * @return None */ void CADestroyInfo(CAInfo_t *info); /** * @brief gets message type from PDU binary data - * @param pdu [IN] pdu data - * @param size [IN] size of pdu data + * @param pdu [IN] pdu data + * @param size [IN] size of pdu data * @return message type */ CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void *pdu, uint32_t size); /** * @brief gets message ID PDU binary data - * @param pdu [IN] pdu data - * @param size [IN] size of pdu data + * @param pdu [IN] pdu data + * @param size [IN] size of pdu data * @return message ID */ uint16_t CAGetMessageIdFromPduBinaryData(const void *pdu, uint32_t size); +/** + * @brief gets code PDU binary data + * @param pdu [IN] pdu data + * @param size [IN] size of pdu data + * @return code + */ +CAResponseResult_t CAGetCodeFromPduBinaryData(const void *pdu, uint32_t size); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/resource/csdk/connectivity/inc/caretransmission.h b/resource/csdk/connectivity/inc/caretransmission.h index 85901ca..dc45463 100644 --- a/resource/csdk/connectivity/inc/caretransmission.h +++ b/resource/csdk/connectivity/inc/caretransmission.h @@ -1,4 +1,4 @@ -/* **************************************************************** +/****************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,9 +19,8 @@ ******************************************************************/ /** - * @file - * - * + * @file caretransmission.h + * @brief This file contains common function for retransmission messages. */ #ifndef __CA_RETRANSMISSION_H_ @@ -48,15 +47,17 @@ /** retransmission data send method type**/ typedef CAResult_t (*CADataSendMethod_t)(const CARemoteEndpoint_t *endpoint, const void *pdu, - uint32_t size); + uint32_t size); /** retransmission timeout callback type**/ -typedef void (*CATimeoutCallback_t)(const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size); +typedef void (*CATimeoutCallback_t)(const CARemoteEndpoint_t *endpoint, const void *pdu, + uint32_t size); typedef struct { /** retransmission support connectivity type **/ CAConnectivityType_t supportType; + /** retransmission trying count **/ uint8_t tryingCount; @@ -66,20 +67,28 @@ typedef struct { /** Thread pool of the thread started **/ u_thread_pool_t threadPool; - /** mutex for synchrnoization **/ + + /** mutex for synchronization **/ u_mutex threadMutex; - /** conditional mutex for synchrnoization **/ + + /** conditional mutex for synchronization **/ u_cond threadCond; + /** send method for retransmission data **/ CADataSendMethod_t dataSendMethod; + /** callback function for retransmit timeout **/ CATimeoutCallback_t timeoutCallback; + /** retransmission configure data **/ CARetransmissionConfig_t config; + /** Variable to inform the thread to stop **/ bool isStop; + /** array list on which the thread is operating. **/ u_arraylist_t *dataList; + } CARetransmission_t; #ifdef __cplusplus @@ -89,63 +98,64 @@ extern "C" /** * @brief Initializes the retransmission context - * @param context [IN] context for retransmission - * @param handle [IN] thread pool handle + * @param context [IN] context for retransmission + * @param handle [IN] thread pool handle * @param retransmissionSendMethod [IN] function to be called for retransmission - * @param timeoutCallback [IN] callback for retransmit timeout - * @param config [IN] configuration for retransmission. - * if NULL is coming, it will set default values. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param timeoutCallback [IN] callback for retransmit timeout + * @param config [IN] configuration for retransmission. + * if NULL is coming, it will set default values. + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, u_thread_pool_t handle, - CADataSendMethod_t retransmissionSendMethod, - CATimeoutCallback_t timeoutCallback, - CARetransmissionConfig_t* config); + CADataSendMethod_t retransmissionSendMethod, + CATimeoutCallback_t timeoutCallback, + CARetransmissionConfig_t* config); /** * @brief Starting the retransmission context * @param context [IN] context for retransmission - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionStart(CARetransmission_t *context); /** * @brief Pass the sent pdu data. if retransmission process need, internal thread will wake up and - * process the retransmission data. + * process the retransmission data * @param context [IN] context for retransmission * @param endpoint [IN] endpoint information * @param pdu [IN] sent pdu binary data * @param size [IN] sent pdu binary data size - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionSentData(CARetransmission_t* context, - const CARemoteEndpoint_t* endpoint,const void* pdu, + const CARemoteEndpoint_t* endpoint, const void* pdu, uint32_t size); /** * @brief Pass the received pdu data. if received pdu is ACK data for the retransmission CON data, * the specified CON data will remove on retransmission list. - * @param context [IN] context for retransmission - * @param endpoint [IN] endpoint information - * @param pdu [IN] received pdu binary data - * @param size [IN] received pdu binary data size - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param context [IN] context for retransmission + * @param endpoint [IN] endpoint information + * @param pdu [IN] received pdu binary data + * @param size [IN] received pdu binary data size + * @param retransmissionPdu [OUT] pdu data of the request for reset and ack + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, const CARemoteEndpoint_t *endpoint, const void *pdu, - uint32_t size); + uint32_t size, void **retransmissionPdu); /** * @brief Stopping the retransmission context * @param context [IN] context for retransmission - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionStop(CARetransmission_t *context); /** * @brief Terminating the retransmission context * @param context [IN] context for retransmission - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionDestroy(CARetransmission_t *context); @@ -154,4 +164,3 @@ CAResult_t CARetransmissionDestroy(CARetransmission_t *context); #endif #endif // __CA_RETRANSMISSION_H_ - diff --git a/resource/csdk/connectivity/inc/caretransmission_singlethread.h b/resource/csdk/connectivity/inc/caretransmission_singlethread.h index 685f441..b10c410 100644 --- a/resource/csdk/connectivity/inc/caretransmission_singlethread.h +++ b/resource/csdk/connectivity/inc/caretransmission_singlethread.h @@ -1,4 +1,4 @@ -/* **************************************************************** +/****************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,9 +19,8 @@ ******************************************************************/ /** - * @file - * - * + * @file caretransmission_singlethread.h + * @brief This file contains common function for retransmission messages. */ #ifndef __CA_RETRANSMISSION_SINGLETHREAD_H_ @@ -33,7 +32,7 @@ #include "cacommon.h" /** CA_ETHERNET, CA_WIFI, CA_LE **/ -#define DEFAULT_RETRANSMISSION_TYPE ((1<<0)|(1<<1)|(1<<3)) +#define DEFAULT_RETRANSMISSION_TYPE (CA_ETHERNET | CA_WIFI | CA_LE) /** default retransmission trying count is 4. **/ #define DEFAULT_RETRANSMISSION_COUNT 4 @@ -89,7 +88,7 @@ extern "C" * @param retransmissionSendMethod [IN] function to be called for retransmission * @param timeoutCallback [IN] callback for retransmit timeout * @param config [IN] configuration for retransmission. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, CADataSendMethod_t retransmissionSendMethod, @@ -103,7 +102,7 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, * @param endpoint [IN] endpoint information * @param pdu [IN] sent pdu binary data * @param size [IN] sent pdu binary data size - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionSentData(CARetransmission_t *context, const CARemoteEndpoint_t *endpoint, @@ -112,27 +111,28 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context, /** * @brief Paas the received pdu data. if received pdu is ACK data for the retransmission CON data, * the specified CON data will remove on retransmission list. - * @param context [IN] context for retransmission - * @param endpoint [IN] endpoint information - * @param pdu [IN] received pdu binary data - * @param size [IN] received pdu binary data size - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param context [IN] context for retransmission + * @param endpoint [IN] endpoint information + * @param pdu [IN] received pdu binary data + * @param size [IN] received pdu binary data size + * @param retransmissionPdu [OUT] pdu data of the request for reset and ack + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, const CARemoteEndpoint_t *endpoint, const void *pdu, - uint32_t size); + uint32_t size, void **retransmissionPdu); /** * @brief Stopping the retransmission context - * @param context [IN] context for retransmission - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param context [IN] context for retransmission + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionStop(CARetransmission_t *context); /** * @brief Terminating the retransmission context - * @param context [IN] context for retransmission - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param context [IN] context for retransmission + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CARetransmissionDestroy(CARetransmission_t *context); @@ -142,8 +142,8 @@ CAResult_t CARetransmissionDestroy(CARetransmission_t *context); void CACheckRetransmissionList(); /** - * @brief Invoke Retranmission according to TimedAction Response - * @param context [IN] context for retransmission + * @brief Invoke Retransmission according to TimedAction Response + * @param threadValue [IN] context for retransmission */ void CARetransmissionBaseRoutine(void *threadValue); diff --git a/resource/csdk/connectivity/src/camessagehandler.c b/resource/csdk/connectivity/src/camessagehandler.c index cdeae05..fe473a1 100644 --- a/resource/csdk/connectivity/src/camessagehandler.c +++ b/resource/csdk/connectivity/src/camessagehandler.c @@ -28,24 +28,19 @@ #include "caremotehandler.h" #include "cainterfacecontroller.h" #include "caprotocolmessage.h" +#include "caretransmission.h" #include "uqueue.h" #include "logger.h" #include "config.h" /* for coap protocol */ -#include "coap.h" #include "uthreadpool.h" /* for thread pool */ #include "caqueueingthread.h" -#include "caretransmission.h" #include "umutex.h" #include "oic_malloc.h" -#include "caadapterutils.h" #include "canetworkconfigurator.h" #define TAG PCF("CA") #define SINGLE_HANDLE -#define CA_MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG(ERROR, TAG, "Out of memory"); \ -goto memory_error_exit;} } - #define MAX_THREAD_POOL_SIZE 20 typedef enum @@ -78,33 +73,41 @@ static CAResponseCallback g_responseHandler = NULL; static void CATimeoutCallback(const CARemoteEndpoint_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"); + CARemoteEndpoint_t* ep = CACloneRemoteEndpoint(endpoint); - if (ep == NULL) + if (NULL == ep) { - OIC_LOG(DEBUG, TAG, "memory allocation failed !"); + OIC_LOG(ERROR, TAG, "clone failed"); return; } CAResponseInfo_t* resInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t)); - if (resInfo == NULL) + if (NULL == resInfo) { - OIC_LOG(DEBUG, TAG, "memory allocation failed !"); + OIC_LOG(ERROR, TAG, "calloc failed"); CADestroyRemoteEndpointInternal(ep); return; } - CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size); - uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size); - resInfo->result = CA_RETRANSMIT_TIMEOUT; - resInfo->info.type = type; - resInfo->info.messageId = messageId; + resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size); + resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size); + CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *) pdu, &(resInfo->info)); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list"); + OICFree(resInfo->info.token); + return; + } CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); - if (cadata == NULL) + if (NULL == cadata) { - OIC_LOG(DEBUG, TAG, "memory allocation failed !"); + OIC_LOG(ERROR, TAG, "memory allocation failed !"); CADestroyRemoteEndpointInternal(ep); OICFree(resInfo); return; @@ -116,48 +119,49 @@ static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pd cadata->responseInfo = resInfo; CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t)); + OIC_LOG(DEBUG, TAG, "OUT"); } static void CADataDestroyer(void *data, uint32_t size) { + OIC_LOG(DEBUG, TAG, "IN"); CAData_t *cadata = (CAData_t *) data; - if (cadata == NULL) + if (NULL == cadata) { + OIC_LOG(ERROR, TAG, "cadata is NULL"); return; } - if (cadata->remoteEndpoint != NULL) + if (NULL != cadata->remoteEndpoint) { - CADestroyRemoteEndpointInternal((CARemoteEndpoint_t *)cadata->remoteEndpoint); + CADestroyRemoteEndpointInternal((CARemoteEndpoint_t *) cadata->remoteEndpoint); } - if (cadata->requestInfo != NULL) + if (NULL != cadata->requestInfo) { - CADestroyRequestInfoInternal((CARequestInfo_t *)cadata->requestInfo); + CADestroyRequestInfoInternal((CARequestInfo_t *) cadata->requestInfo); } - if (cadata->responseInfo != NULL) + if (NULL != cadata->responseInfo) { - CADestroyResponseInfoInternal((CAResponseInfo_t *)cadata->responseInfo); - } - - if (cadata->options != NULL) - { - OICFree(cadata->options); + CADestroyResponseInfoInternal((CAResponseInfo_t *) cadata->responseInfo); } + OICFree(cadata->options); OICFree(cadata); + OIC_LOG(DEBUG, TAG, "OUT"); } static void CAReceiveThreadProcess(void *threadData) { + OIC_LOG(DEBUG, TAG, "IN"); // Currently not supported // This will be enabled when RI supports multi threading #ifndef SINGLE_HANDLE CAData_t *data = (CAData_t *) threadData; - if (data == NULL) + if (NULL == data) { OIC_LOG(ERROR, TAG, "thread data error!!"); return; @@ -168,10 +172,13 @@ static void CAReceiveThreadProcess(void *threadData) // #2 get endpoint CARemoteEndpoint_t *rep = (CARemoteEndpoint_t *)(data->remoteEndpoint); - if (rep == NULL) + if (NULL == rep) + { + OIC_LOG(ERROR, TAG, "remoteEndpoint error!!"); return; + } - if (data->requestInfo != NULL) + if (NULL != data->requestInfo) { if (g_requestHandler) { @@ -179,7 +186,7 @@ static void CAReceiveThreadProcess(void *threadData) } } - if (data->responseInfo != NULL) + if (NULL != data->responseInfo) { if (g_responseHandler) { @@ -187,45 +194,38 @@ static void CAReceiveThreadProcess(void *threadData) } } #endif + OIC_LOG(DEBUG, TAG, "OUT"); } static void CASendThreadProcess(void *threadData) { + OIC_LOG(DEBUG, TAG, "IN"); CAData_t *data = (CAData_t *) threadData; - if (data == NULL) - { - OIC_LOG(ERROR, TAG, "thread data error!!"); - return; - } - - if (NULL == data->remoteEndpoint) - { - OIC_LOG(DEBUG, TAG, "remoteEndpoint is null"); - return; - } + VERIFY_NON_NULL_VOID(data, TAG, "data"); + VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "remoteEndpoint"); CAResult_t res = CA_STATUS_FAILED; CASendDataType_t type = data->type; - if (type == SEND_TYPE_UNICAST) + if (SEND_TYPE_UNICAST == type) { coap_pdu_t *pdu = NULL; - if (data->requestInfo != NULL) + if (NULL != data->requestInfo) { OIC_LOG(DEBUG, TAG, "requestInfo is available.."); - pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, + pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, data->requestInfo->method, data->requestInfo->info); } - else if (data->responseInfo != NULL) + else if (NULL != data->responseInfo) { OIC_LOG(DEBUG, TAG, "responseInfo is available.."); - pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, + pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, data->responseInfo->result, data->responseInfo->info); } @@ -237,101 +237,104 @@ static void CASendThreadProcess(void *threadData) // interface controller function call. if (NULL != pdu) { - OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data); - - OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type); - - OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code); - - OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id)); - - OIC_LOG(DEBUG, TAG, "PDU Maker - token :"); - - OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length); + CALogPDUInfo(pdu); res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length); - + if (CA_STATUS_OK != res) + { + OIC_LOG_V(ERROR, TAG, "send failed:%d", res); + coap_delete_pdu(pdu); + return; + } // for retransmission - CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr, - pdu->length); + res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr, + pdu->length); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(INFO, TAG, "retransmission will be not working: %d", res); + coap_delete_pdu(pdu); + return; + } coap_delete_pdu(pdu); } } - else if (type == SEND_TYPE_MULTICAST) + else if (SEND_TYPE_MULTICAST == type) { - coap_pdu_t *pdu = NULL; - CAInfo_t info = {}; + OIC_LOG(DEBUG, TAG, "both requestInfo & responseInfo is not available"); + + CAInfo_t info = { }; info.options = data->options; info.numOptions = data->numOptions; info.token = data->requestInfo->info.token; info.tokenLength = data->requestInfo->info.tokenLength; info.type = data->requestInfo->info.type; + info.messageId = data->requestInfo->info.messageId; + info.payload = data->requestInfo->info.payload; - pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, CA_GET, info); + coap_pdu_t *pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, CA_GET, + info); if (NULL != pdu) { - OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data); - - OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type); - - OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code); - - OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id)); - - OIC_LOG(DEBUG, TAG, "PDU Maker - token"); - - OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length); + CALogPDUInfo(pdu); res = CASendMulticastData(pdu->hdr, pdu->length); + if(CA_STATUS_OK != res) + { + OIC_LOG_V(ERROR, TAG, "send failed:%d", res); + coap_delete_pdu(pdu); + return; + } + coap_delete_pdu(pdu); } } - OIC_LOG_V(DEBUG, TAG, " Result :%d", res); + OIC_LOG(DEBUG, TAG, "OUT"); } -static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, - uint32_t dataLen) +static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen) { - OIC_LOG(DEBUG, TAG, "receivedPacketCallback in message handler!!"); - - if (NULL == data) - { - OIC_LOG(DEBUG, TAG, "received data is null"); - return; - } + OIC_LOG(DEBUG, TAG, "IN"); + VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint"); + VERIFY_NON_NULL_VOID(data, TAG, "data"); - coap_pdu_t *pdu; uint32_t code = CA_NOT_FOUND; - - OIC_LOG_V(DEBUG, TAG, "data : %s", data); - pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code); + coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code); OICFree(data); - if(NULL == pdu) + if (NULL == pdu) { - OIC_LOG(DEBUG, TAG, "pdu is null"); + OIC_LOG(ERROR, TAG, "Parse PDU failed"); + CAAdapterFreeRemoteEndpoint(endpoint); return; } char uri[CA_MAX_URI_LENGTH] = { 0, }; - uint32_t bufLen = CA_MAX_URI_LENGTH; + uint32_t bufLen = sizeof(uri); - if (code == CA_GET || code == CA_POST || code == CA_PUT || code == CA_DELETE) + if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code) { - CARequestInfo_t *ReqInfo; - ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t)); - if (ReqInfo == NULL) + CARequestInfo_t *ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t)); + if (NULL == ReqInfo) + { + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); + coap_delete_pdu(pdu); + CAAdapterFreeRemoteEndpoint(endpoint); + return; + } + + CAResult_t res = CAGetRequestInfoFromPDU(pdu, ReqInfo, uri, bufLen); + if (CA_STATUS_OK != res) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); + OIC_LOG_V(ERROR, TAG, "CAGetRequestInfoFromPDU failed : %d", res); + OICFree(ReqInfo); coap_delete_pdu(pdu); CAAdapterFreeRemoteEndpoint(endpoint); return; } - CAGetRequestInfoFromPdu(pdu, ReqInfo, uri, bufLen); if (NULL != ReqInfo->info.options) { @@ -356,28 +359,36 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, ReqInfo->info.tokenLength); } + OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method); + OIC_LOG(DEBUG, TAG, "Request- token"); + OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ReqInfo->info.token, CA_MAX_TOKEN_LEN); + OIC_LOG_V(DEBUG, TAG, "Request- msgID : %d", ReqInfo->info.messageId); if (NULL != endpoint) { - endpoint->resourceUri = (char *) OICCalloc(bufLen + 1, sizeof(char)); - if (endpoint->resourceUri == NULL) + endpoint->resourceUri = (char *) OICMalloc(bufLen + 1); + if (NULL == endpoint->resourceUri) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); OICFree(ReqInfo); coap_delete_pdu(pdu); CAAdapterFreeRemoteEndpoint(endpoint); return; } memcpy(endpoint->resourceUri, uri, bufLen); - OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri); + endpoint->resourceUri[bufLen] = '\0'; + OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri); } // store the data at queue. CAData_t *cadata = NULL; cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); - if (cadata == NULL) + if (NULL == cadata) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); - if (endpoint != NULL && endpoint->resourceUri != NULL) + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); + if (NULL != endpoint && NULL != endpoint->resourceUri) + { OICFree(endpoint->resourceUri); + } + OICFree(ReqInfo); coap_delete_pdu(pdu); CAAdapterFreeRemoteEndpoint(endpoint); @@ -392,16 +403,24 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, } else { - CAResponseInfo_t *ResInfo; - ResInfo = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t)); - if (ResInfo == NULL) + CAResponseInfo_t *ResInfo = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t)); + if (NULL == ResInfo) + { + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); + coap_delete_pdu(pdu); + CAAdapterFreeRemoteEndpoint(endpoint); + return; + } + + CAResult_t res = CAGetResponseInfoFromPDU(pdu, ResInfo, uri, bufLen); + if (CA_STATUS_OK != res) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); + OIC_LOG_V(ERROR, TAG, "CAGetResponseInfoFromPDU failed : %d", res); + OICFree(ResInfo); coap_delete_pdu(pdu); CAAdapterFreeRemoteEndpoint(endpoint); return; } - CAGetResponseInfoFromPdu(pdu, ResInfo, uri, bufLen); if (NULL != ResInfo->info.options) { @@ -412,36 +431,41 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, OIC_LOG_V(DEBUG, TAG, "Response- list: %s", ResInfo->info.options[i].optionData); } - if (NULL != ResInfo->info.payload) - { - OIC_LOG_V(DEBUG, TAG, "Response- payload: %s", ResInfo->info.payload); - } - OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result); } + if (NULL != ResInfo->info.payload) + { + OIC_LOG_V(DEBUG, TAG, "Response- payload: %s", ResInfo->info.payload); + } + OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result); + OIC_LOG_V(DEBUG, TAG, "Response- token : %s", ResInfo->info.token); + OIC_LOG_V(DEBUG, TAG, "Response- msgID: %d", ResInfo->info.messageId); + if (NULL != endpoint) { - endpoint->resourceUri = (char *) OICCalloc(bufLen + 1, sizeof(char)); - if (endpoint->resourceUri == NULL) + endpoint->resourceUri = (char *) OICMalloc(bufLen + 1); + if (NULL == endpoint->resourceUri) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); OICFree(ResInfo); coap_delete_pdu(pdu); CAAdapterFreeRemoteEndpoint(endpoint); return; } memcpy(endpoint->resourceUri, uri, bufLen); - OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri); + endpoint->resourceUri[bufLen] = '\0'; + OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri); } // store the data at queue. - CAData_t *cadata = NULL; - cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); - if (cadata == NULL) + CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); + if (NULL == cadata) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); - if (endpoint != NULL && endpoint->resourceUri != NULL) + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); + if (NULL != endpoint && NULL != endpoint->resourceUri) + { OICFree(endpoint->resourceUri); + } OICFree(ResInfo); coap_delete_pdu(pdu); CAAdapterFreeRemoteEndpoint(endpoint); @@ -451,31 +475,48 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, cadata->type = SEND_TYPE_UNICAST; cadata->remoteEndpoint = endpoint; cadata->requestInfo = NULL; + + // for retransmission + void *retransmissionPdu = NULL; + CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, pdu->length, + &retransmissionPdu); + + // get token from saved data in retransmission list + if (retransmissionPdu && CA_EMPTY == code) + { + CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu, + &(ResInfo->info)); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list"); + OICFree(ResInfo->info.token); + } + } + OICFree(retransmissionPdu); cadata->responseInfo = ResInfo; CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t)); - - // for retransmission - CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, pdu->length); } - if(pdu) + if (pdu) { coap_delete_pdu(pdu); } + OIC_LOG(DEBUG, TAG, "OUT"); } static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status) { - OIC_LOG(DEBUG, TAG, "networkChangeCallback in message handler!!"); + OIC_LOG(DEBUG, TAG, "IN"); - OIC_LOG_V(DEBUG, TAG, "Changed Network Status: %d", status); + OIC_LOG(DEBUG, TAG, "OUT"); } void CAHandleRequestResponseCallbacks() { OIC_LOG(DEBUG, TAG, "CAHandleRequestResponseCallbacks IN"); +#ifdef SINGLE_HANDLE // parse the data and call the callbacks. // #1 parse the data // #2 get endpoint @@ -486,75 +527,64 @@ void CAHandleRequestResponseCallbacks() u_mutex_unlock(g_receiveThread.threadMutex); - if (item == NULL) + if (NULL == item) + { return; + } // get values void *msg = item->msg; - if (msg == NULL) + if (NULL == msg) + { return; + } // get endpoint CAData_t *td = (CAData_t *) msg; CARemoteEndpoint_t *rep = td->remoteEndpoint; - if (rep == NULL) + if (NULL == rep) + { return; + } - if (td->requestInfo != NULL) + if (NULL != td->requestInfo) { if (g_requestHandler) { + OIC_LOG_V(DEBUG, TAG, "callback will be sent : %d", td->requestInfo->info.numOptions); g_requestHandler(rep, td->requestInfo); } - - OICFree(td->requestInfo->info.options); - OICFree(td->requestInfo->info.payload); - OICFree(td->requestInfo->info.token); - OICFree(td->requestInfo); } - if (td->responseInfo != NULL) + if (NULL != td->responseInfo) { if (g_responseHandler) { g_responseHandler(rep, td->responseInfo); } - OICFree(td->responseInfo->info.options); - OICFree(td->responseInfo->info.payload); - OICFree(td->responseInfo->info.token); - OICFree(td->responseInfo); } + CADataDestroyer(msg, sizeof(CAData_t)); - if (NULL != rep->resourceUri) - { - OICFree(rep->resourceUri); - } - - OICFree(rep); +#endif OIC_LOG(DEBUG, TAG, "CAHandleRequestResponseCallbacks OUT"); } -CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, - const CARequestInfo_t *request) +CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request) { - OIC_LOG(DEBUG, TAG, "CADetachRequestMessage"); + OIC_LOG(DEBUG, TAG, "IN"); - if (object == NULL || request == NULL) - { - return CA_STATUS_FAILED; - } + VERIFY_NON_NULL(object, TAG, "object"); + VERIFY_NON_NULL(request, TAG, "request"); CARemoteEndpoint_t *remoteEndpoint = NULL; CARequestInfo_t *requestInfo = NULL; - CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); CA_MEMORY_ALLOC_CHECK(data); // clone remote endpoint - remoteEndpoint = CACloneRemoteEndpoint(object); CA_MEMORY_ALLOC_CHECK(remoteEndpoint); @@ -570,46 +600,46 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, // add thread CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); - + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; - // memory error label. +// memory error label. memory_error_exit: - CADestroyRemoteEndpointInternal(remoteEndpoint); - CADestroyRequestInfoInternal(requestInfo); - if (data != NULL) - { - OICFree(data); - } - + OICFree(data); + OIC_LOG(DEBUG, TAG, "OUT"); return CA_MEMORY_ALLOC_FAILED; } CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, const CARequestInfo_t *request) { - // ToDo - OIC_LOG(DEBUG, TAG, "CADetachRequestToAllMessage"); + OIC_LOG(DEBUG, TAG, "IN"); + if (NULL == object || NULL == request || NULL == object->resourceUri) + { + return CA_STATUS_INVALID_PARAM; + } - if (object == NULL || request == NULL) + if ((request->method < CA_GET) || (request->method > CA_DELETE)) { - return CA_STATUS_FAILED; + OIC_LOG(ERROR, TAG, "Invalid method type!"); + + return CA_STATUS_INVALID_PARAM; } CARemoteEndpoint_t *remoteEndpoint = NULL; CARequestInfo_t *requestInfo = NULL; + // allocate & initialize CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); CA_MEMORY_ALLOC_CHECK(data); - CAAddress_t addr; - memset(&addr, 0, sizeof(CAAddress_t)); + CAAddress_t addr = {}; remoteEndpoint = CACreateRemoteEndpointInternal(object->resourceUri, addr, - object->connectivityType); + object->connectivityType); // clone request info requestInfo = CACloneRequestInfo(request); @@ -624,36 +654,30 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, // add thread CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; - // memory error label. +// memory error label. memory_error_exit: - CADestroyRemoteEndpointInternal(remoteEndpoint); - CADestroyRequestInfoInternal(requestInfo); - - if (data != NULL) - { - OICFree(data); - } - + CADestroyRemoteEndpointInternal(remoteEndpoint); + OICFree(data); + OIC_LOG(DEBUG, TAG, "OUT"); return CA_MEMORY_ALLOC_FAILED; } CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object, const CAResponseInfo_t *response) { - OIC_LOG(DEBUG, TAG, "CADetachResponseMessage"); - - if (object == NULL || response == NULL) - { - return CA_STATUS_FAILED; - } + OIC_LOG(DEBUG, TAG, "IN"); + VERIFY_NON_NULL(object, TAG, "object"); + VERIFY_NON_NULL(response, TAG, "response"); CARemoteEndpoint_t *remoteEndpoint = NULL; CAResponseInfo_t *responseInfo = NULL; + // allocate & initialize CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); CA_MEMORY_ALLOC_CHECK(data); @@ -674,19 +698,15 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object, // add thread CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; - // memory error label. +// memory error label. memory_error_exit: - CADestroyRemoteEndpointInternal(remoteEndpoint); - CADestroyResponseInfoInternal(responseInfo); - - if (data != NULL) - { - OICFree(data); - } + OICFree(data); + OIC_LOG(DEBUG, TAG, "OUT"); return CA_MEMORY_ALLOC_FAILED; } @@ -738,26 +758,26 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t data->responseInfo = NULL; data->options = NULL; data->numOptions = 0; - - if (options != NULL && numOptions > 0) + if (NULL != options && 0 < numOptions) { // copy data - CAHeaderOption_t *temp = (CAHeaderOption_t *) OICCalloc(numOptions, - sizeof(CAHeaderOption_t)); - CA_MEMORY_ALLOC_CHECK(temp); + CAHeaderOption_t *headerOption = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) + * numOptions); + CA_MEMORY_ALLOC_CHECK(headerOption); - memcpy(temp, options, sizeof(CAHeaderOption_t) * numOptions); + memcpy(headerOption, options, sizeof(CAHeaderOption_t) * numOptions); - data->options = temp; + data->options = headerOption; data->numOptions = numOptions; } // add thread CAQueueingThreadAddData(&g_sendThread, data, sizeof(CAData_t)); + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; - // memory error label. +// memory error label. memory_error_exit: CADestroyRemoteEndpointInternal(remoteEndpoint); @@ -769,25 +789,23 @@ memory_error_exit: return CA_MEMORY_ALLOC_FAILED; } -void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, - CAResponseCallback RespHandler) +void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler) { - OIC_LOG(DEBUG, TAG, "set request, response handler callback."); - + OIC_LOG(DEBUG, TAG, "IN"); g_requestHandler = ReqHandler; g_responseHandler = RespHandler; + OIC_LOG(DEBUG, TAG, "OUT"); } CAResult_t CAInitializeMessageHandler() { - OIC_LOG(DEBUG, TAG, "CAInitializeMessageHandler - Entry"); + OIC_LOG(DEBUG, TAG, "IN"); CASetPacketReceivedCallback(CAReceivedPacketCallback); CASetNetworkChangeCallback(CANetworkChangedCallback); // create thread pool - CAResult_t res; - res = u_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle); + CAResult_t res = u_thread_pool_init(MAX_THREAD_POOL_SIZE, &g_threadPoolHandle); if (res != CA_STATUS_OK) { @@ -796,8 +814,12 @@ CAResult_t CAInitializeMessageHandler() } // send thread initialize - CAQueueingThreadInitialize(&g_sendThread, g_threadPoolHandle, CASendThreadProcess, - CADataDestroyer); + if (CA_STATUS_OK != CAQueueingThreadInitialize(&g_sendThread, g_threadPoolHandle, + CASendThreadProcess, CADataDestroyer)) + { + OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread"); + return CA_STATUS_FAILED; + } // start send thread res = CAQueueingThreadStart(&g_sendThread); @@ -811,8 +833,12 @@ CAResult_t CAInitializeMessageHandler() } // receive thread initialize - CAQueueingThreadInitialize(&g_receiveThread, g_threadPoolHandle, CAReceiveThreadProcess, - CADataDestroyer); + if (CA_STATUS_OK != CAQueueingThreadInitialize(&g_receiveThread, g_threadPoolHandle, + CAReceiveThreadProcess, CADataDestroyer)) + { + OIC_LOG(ERROR, TAG, "Failed to Initialize receive queue thread"); + return CA_STATUS_FAILED; + } #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading // start receive thread @@ -827,7 +853,7 @@ CAResult_t CAInitializeMessageHandler() // retransmission initialize CARetransmissionInitialize(&g_retransmissionContext, g_threadPoolHandle, CASendUnicastData, - CATimeoutCallback, NULL); + CATimeoutCallback, NULL); // start retransmission res = CARetransmissionStart(&g_retransmissionContext); @@ -840,22 +866,23 @@ CAResult_t CAInitializeMessageHandler() // initialize interface adapters by controller CAInitializeAdapters(g_threadPoolHandle); - + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } void CATerminateMessageHandler() { - uint8_t i = 0; + OIC_LOG(DEBUG, TAG, "IN"); CAConnectivityType_t connType; u_arraylist_t *list = CAGetSelectedNetworkList(); uint32_t length = u_arraylist_length(list); + uint32_t i = 0; for (i = 0; i < length; i++) { void* ptrType = u_arraylist_get(list, i); - if (ptrType == NULL) + if (NULL == ptrType) { continue; } @@ -865,21 +892,21 @@ void CATerminateMessageHandler() } // stop retransmission - if (g_retransmissionContext.threadMutex != NULL) + if (NULL != g_retransmissionContext.threadMutex) { CARetransmissionStop(&g_retransmissionContext); } // stop thread // delete thread data - if (g_sendThread.threadMutex != NULL) + if (NULL != g_sendThread.threadMutex) { CAQueueingThreadStop(&g_sendThread); } // stop thread // delete thread data - if (g_receiveThread.threadMutex != NULL) + if (NULL != g_receiveThread.threadMutex) { #ifndef SINGLE_HANDLE // This will be enabled when RI supports multi threading CAQueueingThreadStop(&gReceiveThread); @@ -887,7 +914,7 @@ void CATerminateMessageHandler() } // destroy thread pool - if (g_threadPoolHandle != NULL) + if (NULL != g_threadPoolHandle) { u_thread_pool_free(g_threadPoolHandle); g_threadPoolHandle = NULL; @@ -900,6 +927,22 @@ void CATerminateMessageHandler() // terminate interface adapters by controller CATerminateAdapters(); - OIC_LOG(DEBUG, TAG, "message handler termination is complete!"); + OIC_LOG(DEBUG, TAG, "OUT"); } +void CALogPDUInfo(coap_pdu_t *pdu) +{ + 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); + + OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code); + + OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id)); + + OIC_LOG(DEBUG, TAG, "PDU Maker - token :"); + + OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length); +} diff --git a/resource/csdk/connectivity/src/camessagehandler_singlethread.c b/resource/csdk/connectivity/src/camessagehandler_singlethread.c index 8fe6eb7..3c59f42 100644 --- a/resource/csdk/connectivity/src/camessagehandler_singlethread.c +++ b/resource/csdk/connectivity/src/camessagehandler_singlethread.c @@ -18,28 +18,23 @@ * ******************************************************************/ -#include "camessagehandler_singlethread.h" - #include #include #include #include #include "cainterface.h" +#include "camessagehandler_singlethread.h" #include "caremotehandler.h" #include "cainterfacecontroller_singlethread.h" #include "caprotocolmessage.h" +#include "caretransmission_singlethread.h" #include "logger.h" #include "config.h" /* for coap protocol */ -#include "coap.h" #include "oic_malloc.h" -#include "caadapterutils.h" #define TAG "CAMH_ST" -#define CA_MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG(ERROR, TAG, "Out of memory");\ - goto memory_error_exit;} } - #define CA_MAX_RT_ARRAY_SIZE 3 typedef enum @@ -64,32 +59,66 @@ static CARetransmission_t g_retransmissionContext; static CARequestCallback g_requestHandler = NULL; static CAResponseCallback g_responseHandler = NULL; -static void CAProcessData(CAData_t *data) +static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size) +{ + OIC_LOG(DEBUG, TAG, "IN"); + CARemoteEndpoint_t* ep = CACloneRemoteEndpoint(endpoint); + if (NULL == ep) + { + OIC_LOG(ERROR, TAG, "clone failed"); + return; + } + + CAResponseInfo_t* resInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t)); + + if (NULL == resInfo) + { + OIC_LOG(ERROR, TAG, "calloc failed"); + CADestroyRemoteEndpointInternal(ep); + return; + } + + resInfo->result = CA_RETRANSMIT_TIMEOUT; + resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size); + resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size); + + if (g_responseHandler) + { + g_responseHandler(ep, resInfo); + } + + CADestroyRemoteEndpointInternal(ep); + OICFree(resInfo); + + OIC_LOG(DEBUG, TAG, "OUT"); +} +static void CAProcessData(const CAData_t *data) { OIC_LOG(DEBUG, TAG, "IN"); VERIFY_NON_NULL_VOID(data, TAG, "data"); - VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "remoteendpoint"); + VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "remoteEndpoint"); CAResult_t res = CA_STATUS_FAILED; CASendDataType_t type = data->type; - if (type == SEND_TYPE_UNICAST) + if (SEND_TYPE_UNICAST == type) { coap_pdu_t *pdu = NULL; - if (data->requestInfo != NULL) + if (NULL != data->requestInfo) { OIC_LOG(DEBUG, TAG, "reqInfo avlbl"); - pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, - data->requestInfo->method, data->requestInfo->info); + pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, + data->requestInfo->method, + data->requestInfo->info); } - else if (data->responseInfo != NULL) + else if (NULL != data->responseInfo) { OIC_LOG(DEBUG, TAG, "resInfo avlbl"); - pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, + pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, data->responseInfo->result, data->responseInfo->info); } @@ -101,26 +130,32 @@ static void CAProcessData(CAData_t *data) // interface controller function call. if (NULL != pdu) { - CALogPDUData(pdu); + CALogPDUInfo(pdu); res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length); - if(CA_STATUS_OK != res) + if (CA_STATUS_OK != res) { OIC_LOG_V(ERROR, TAG, "send failed:%d", res); coap_delete_pdu(pdu); return; } // for retransmission - CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr, - pdu->length); + res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint, pdu->hdr, + pdu->length); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(INFO, TAG, "retransmissions will not be working: %d", res); + coap_delete_pdu(pdu); + return; + } + + coap_delete_pdu(pdu); } - coap_delete_pdu(pdu); } - else if (type == SEND_TYPE_MULTICAST) + else if (SEND_TYPE_MULTICAST == type) { OIC_LOG(DEBUG, TAG, "both requestInfo & responseInfo is not available"); - coap_pdu_t *pdu = NULL; CAInfo_t info = { 0 }; info.options = data->options; @@ -128,12 +163,15 @@ static void CAProcessData(CAData_t *data) info.token = data->requestInfo->info.token; info.tokenLength = data->requestInfo->info.tokenLength; info.type = data->requestInfo->info.type; + info.messageId = data->requestInfo->info.messageId; + info.payload = data->requestInfo->info.payload; - pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri, CA_GET, info); + coap_pdu_t *pdu = (coap_pdu_t *) CAGeneratePDU(data->remoteEndpoint->resourceUri, CA_GET, + info); if (NULL != pdu) { - CALogPDUData(pdu); + CALogPDUInfo(pdu); res = CASendMulticastData(pdu->hdr, pdu->length); if(CA_STATUS_OK != res) { @@ -141,83 +179,57 @@ static void CAProcessData(CAData_t *data) coap_delete_pdu(pdu); return; } - } - coap_delete_pdu(pdu); - } - - OIC_LOG(DEBUG, TAG, "OUT"); -} -static void CATimeoutCallback(const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size) -{ - OIC_LOG(DEBUG, TAG, "IN"); - CARemoteEndpoint_t* ep = CACloneRemoteEndpoint(endpoint); - if (ep == NULL) - { - OIC_LOG(ERROR, TAG, "clone failed"); - return; - } - - CAResponseInfo_t* resInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t)); - - if (resInfo == NULL) - { - OIC_LOG(ERROR, TAG, "calloc failed"); - CADestroyRemoteEndpointInternal(ep); - return; - } - - resInfo->result = CA_RETRANSMIT_TIMEOUT; - resInfo->info.type = CAGetMessageTypeFromPduBinaryData(pdu, size);; - resInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu, size);; - - if (g_responseHandler) - { - g_responseHandler(ep, resInfo); + coap_delete_pdu(pdu); + } } - CADestroyRemoteEndpointInternal(ep); - OICFree(resInfo); OIC_LOG(DEBUG, TAG, "OUT"); } -static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, - uint32_t dataLen) +static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen) { OIC_LOG(DEBUG, TAG, "IN"); VERIFY_NON_NULL_VOID(data, TAG, "data"); uint32_t code = CA_NOT_FOUND; coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code); + if (NULL == pdu) { OIC_LOG(ERROR, TAG, "Parse PDU failed"); return; } - //OICFree(data); char uri[CA_MAX_URI_LENGTH] = { 0, }; uint32_t bufLen = sizeof(uri); - if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code ) + if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code) { CARequestInfo_t *ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t)); - if (ReqInfo == NULL) + if (NULL == ReqInfo) + { + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); + coap_delete_pdu(pdu); + return; + } + + CAResult_t res = CAGetRequestInfoFromPDU(pdu, ReqInfo, uri, bufLen); + if (CA_STATUS_OK != res) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); + OIC_LOG_V(ERROR, TAG, "CAGetRequestInfoFromPDU failed : %d", res); + OICFree(ReqInfo); coap_delete_pdu(pdu); return; } - CAGetRequestInfoFromPdu(pdu, ReqInfo, uri, bufLen); if (NULL != ReqInfo->info.options) { - uint32_t i; - for (i = 0; i < ReqInfo->info.numOptions; i++) + for (uint32_t i = 0; i < ReqInfo->info.numOptions; i++) { - OIC_LOG_V(DEBUG, TAG, "Request- optionID: %d", ReqInfo->info.options[i].optionID); + OIC_LOG_V(DEBUG, TAG, "optionID: %d", ReqInfo->info.options[i].optionID); - OIC_LOG_V(DEBUG, TAG, "Request- list: %s", ReqInfo->info.options[i].optionData); + OIC_LOG_V(DEBUG, TAG, "list: %s", ReqInfo->info.options[i].optionData); } } @@ -226,21 +238,21 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload); } - OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method); - OIC_LOG(DEBUG, TAG, "Request- token:"); + OIC_LOG_V(DEBUG, TAG, "code: %d", ReqInfo->method); + OIC_LOG(DEBUG, TAG, "token:"); OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ReqInfo->info.token, CA_MAX_TOKEN_LEN); - if (NULL != endpoint) { - endpoint->resourceUri = (char *) OICCalloc(bufLen + 1, sizeof(char)); - if (endpoint->resourceUri == NULL) + endpoint->resourceUri = (char *) OICMalloc(bufLen + 1); + if (NULL == endpoint->resourceUri) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); - coap_delete_pdu(pdu); + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); OICFree(ReqInfo); + coap_delete_pdu(pdu); return; } memcpy(endpoint->resourceUri, uri, bufLen); + endpoint->resourceUri[bufLen] = '\0'; OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri); } @@ -257,56 +269,76 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, else { CAResponseInfo_t *ResInfo = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t)); - if (ResInfo == NULL) + if (NULL == ResInfo) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); coap_delete_pdu(pdu); return; } - CAGetResponseInfoFromPdu(pdu, ResInfo, uri, bufLen); + CAResult_t res = CAGetResponseInfoFromPDU(pdu, ResInfo, uri, bufLen); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(ERROR, TAG, "CAGetResponseInfoFromPDU failed : %d", res); + OICFree(ResInfo); + coap_delete_pdu(pdu); + return; + } if (NULL != ResInfo->info.options) { - uint32_t i; - for (i = 0; i < ResInfo->info.numOptions; i++) + for (uint32_t i = 0; i < ResInfo->info.numOptions; i++) { OIC_LOG_V(DEBUG, TAG, "optionID: %d", ResInfo->info.options[i].optionID); OIC_LOG_V(DEBUG, TAG, "list: %s", ResInfo->info.options[i].optionData); } + } - if (NULL != ResInfo->info.payload) - { - OIC_LOG_V(DEBUG, TAG, "payload: %s", ResInfo->info.payload); - } - - OIC_LOG_V(DEBUG, TAG, "code: %d", ResInfo->result); + if (NULL != ResInfo->info.payload) + { + OIC_LOG_V(DEBUG, TAG, "payload: %s", ResInfo->info.payload); } + OIC_LOG_V(DEBUG, TAG, "code: %d", ResInfo->result); if (NULL != endpoint) { - endpoint->resourceUri = (char *) OICCalloc(bufLen + 1, sizeof(char)); - if (endpoint->resourceUri == NULL) + endpoint->resourceUri = (char *) OICMalloc(bufLen + 1); + if (NULL == endpoint->resourceUri) { - OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed!"); - coap_delete_pdu(pdu); + OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed !"); OICFree(ResInfo); + coap_delete_pdu(pdu); return; } memcpy(endpoint->resourceUri, uri, bufLen); + endpoint->resourceUri[bufLen] = '\0'; OIC_LOG_V(DEBUG, TAG, "URI : %s", endpoint->resourceUri); } - if (ResInfo != NULL) + // for retransmission + void *retransmissionPdu = NULL; + CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, pdu->length, + &retransmissionPdu); + + // get token from saved data in retransmission list + if (retransmissionPdu && CA_EMPTY == code) + { + CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu, + &(ResInfo->info)); + if(res != CA_STATUS_OK) + { + OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list"); + OICFree(ResInfo->info.token); + } + } + OICFree(retransmissionPdu); + + if (NULL != ResInfo) { if (g_responseHandler) { g_responseHandler(endpoint, ResInfo); - - // for retransmission - CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, - pdu->length); } CADestroyResponseInfoInternal(ResInfo); } @@ -317,13 +349,17 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, OICFree(endpoint->resourceUri); endpoint->resourceUri = NULL; } - coap_delete_pdu(pdu); + if (pdu) + { + coap_delete_pdu(pdu); + } OIC_LOG(DEBUG, TAG, "OUT"); } static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status) { OIC_LOG(DEBUG, TAG, "IN"); + OIC_LOG(DEBUG, TAG, "OUT"); } @@ -333,8 +369,7 @@ void CAHandleRequestResponseCallbacks() CARetransmissionBaseRoutine((void *)&g_retransmissionContext); } -CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, - const CARequestInfo_t *request) +CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request) { OIC_LOG(DEBUG, TAG, "IN"); @@ -363,8 +398,9 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; - // memory error label. +// memory error label. memory_error_exit: + OICFree(data); OIC_LOG(DEBUG, TAG, "OUT"); return CA_MEMORY_ALLOC_FAILED; } @@ -374,9 +410,16 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, { OIC_LOG(DEBUG, TAG, "IN"); - if (object == NULL || request == NULL) + if (NULL == object || NULL == request || NULL == object->resourceUri) + { + return CA_STATUS_INVALID_PARAM; + } + + if ((request->method < CA_GET) || (request->method > CA_DELETE)) { - return CA_STATUS_FAILED; + OIC_LOG(ERROR, TAG, "Invalid method type!"); + + return CA_STATUS_INVALID_PARAM; } // allocate & initialize @@ -394,14 +437,16 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, data->responseInfo = NULL; CAProcessData(data); - CADestroyRemoteEndpoint(remoteEndpoint); + CADestroyRemoteEndpointInternal(remoteEndpoint); + OICFree(data); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; - // memory error label. +// memory error label. memory_error_exit: + OICFree(data); OIC_LOG(DEBUG, TAG, "OUT"); return CA_MEMORY_ALLOC_FAILED; } @@ -424,13 +469,16 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object, data->responseInfo = response; CAProcessData(data); + OICFree(data); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; - // memory error label. +// memory error label. memory_error_exit: + OICFree(data); OIC_LOG(DEBUG, TAG, "OUT"); + return CA_MEMORY_ALLOC_FAILED; } @@ -491,18 +539,18 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; - // memory error label. +// memory error label. memory_error_exit: CADestroyRemoteEndpointInternal(remoteEndpoint); + OICFree(reqInfo); OICFree(data); OIC_LOG(DEBUG, TAG, "OUT"); return CA_MEMORY_ALLOC_FAILED; } -void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, - CAResponseCallback RespHandler) +void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler) { OIC_LOG(DEBUG, TAG, "IN"); g_requestHandler = ReqHandler; @@ -517,10 +565,9 @@ CAResult_t CAInitializeMessageHandler() CASetNetworkChangeCallback(CANetworkChangedCallback); - CAResult_t res; - // retransmission initialize - CARetransmissionInitialize(&g_retransmissionContext, CASendUnicastData, CATimeoutCallback, NULL); + CARetransmissionInitialize(&g_retransmissionContext, CASendUnicastData, + CATimeoutCallback, NULL); CAInitializeAdapters(); OIC_LOG(DEBUG, TAG, "OUT"); @@ -540,4 +587,20 @@ void CATerminateMessageHandler() OIC_LOG(DEBUG, TAG, "OUT"); } +void CALogPDUInfo(coap_pdu_t *pdu) +{ + 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); + + OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code); + + OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id)); + + OIC_LOG(DEBUG, TAG, "PDU Maker - token :"); + + OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length); +} diff --git a/resource/csdk/connectivity/src/caprotocolmessage.c b/resource/csdk/connectivity/src/caprotocolmessage.c index 69da34b..bea0bc7 100644 --- a/resource/csdk/connectivity/src/caprotocolmessage.c +++ b/resource/csdk/connectivity/src/caprotocolmessage.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef HAVE_TIME_H #include #endif @@ -56,105 +57,132 @@ #define TAG "CA" -#define CA_BUFSIZE 128 -#define CA_PDU_MIN_SIZE 4 +#define CA_BUFSIZE (128) +#define CA_PDU_MIN_SIZE (4) +#define CA_PORT_BUFFER_SIZE (2) -static const char COAP_HEADER[] = "coap://[::]/"; +static const char COAP_URI_HEADER[] = "coap://[::]/"; static uint32_t SEED = 0; -/** - * Helper that uses libcoap to parse either the path or the parameters of a URI - * and populate the supplied options list. - * - * @param str the input partial URI string (either path or query). - * @param length the length of the supplied partial URI. - * @param target the part of the URI to parse (either COAP_OPTION_URI_PATH - * or COAP_OPTION_URI_QUERY). - * @param optlist options information. - */ -static void CAParseUriPartial(const unsigned char *str, size_t length, - int target, coap_list_t **optlist); - -void CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, - char *outUri, uint32_t buflen) +CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, + char *outUri, uint32_t buflen) { OIC_LOG(DEBUG, TAG, "IN"); - if (NULL == pdu) + if (NULL == pdu || NULL == outReqInfo || NULL == outUri) { - OIC_LOG(ERROR, TAG, "pdu NULL"); - return; + OIC_LOG(ERROR, TAG, "parameter is null"); + return CA_STATUS_INVALID_PARAM; } uint32_t code = CA_NOT_FOUND; - CAGetInfoFromPDU(pdu, &code, &(outReqInfo->info), outUri, buflen); + + OIC_LOG_V(DEBUG, TAG, "buffer length : %d", buflen); + CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outReqInfo->info), outUri, buflen); outReqInfo->method = code; OIC_LOG(DEBUG, TAG, "OUT"); + return ret; } -void CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, - char *outUri, uint32_t buflen) +CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, + char *outUri, uint32_t buflen) { OIC_LOG(DEBUG, TAG, "IN"); - if (NULL == pdu) + + if (NULL == pdu || NULL == outResInfo || NULL == outUri) { - OIC_LOG(ERROR, TAG, "pdu NULL"); - return; + OIC_LOG(ERROR, TAG, "parameter is null"); + return CA_STATUS_INVALID_PARAM; } uint32_t code = CA_NOT_FOUND; - CAGetInfoFromPDU(pdu, &code, &(outResInfo->info), outUri, buflen); + CAResult_t ret = CAGetInfoFromPDU(pdu, &code, &(outResInfo->info), outUri, buflen); outResInfo->result = code; OIC_LOG(DEBUG, TAG, "OUT"); + return ret; } -coap_pdu_t *CAGeneratePdu(const char *uri, uint32_t code, const CAInfo_t info) +coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info) { OIC_LOG(DEBUG, TAG, "IN"); - if (NULL == uri) - { - OIC_LOG(ERROR, TAG, "uri NULL"); - return NULL; - } + coap_pdu_t *pdu = NULL; - uint32_t length = strlen(uri); - if (CA_MAX_URI_LENGTH < length) + // RESET have to use only 4byte (empty message) + // and ACKNOWLEDGE can use empty message when code is empty. + if (CA_MSG_RESET == info.type || (CA_EMPTY == code && CA_MSG_ACKNOWLEDGE == info.type)) { - OIC_LOG(ERROR, TAG, "URI len err"); - return NULL; + OIC_LOG(DEBUG, TAG, "code is empty"); + if (!(pdu = CAGeneratePDUImpl((code_t) code, NULL, info, NULL))) + { + OIC_LOG(ERROR, TAG, "pdu NULL"); + return NULL; + } } - - uint32_t uriLength = length + sizeof(COAP_HEADER); - char *coapUri = (char *) OICCalloc(1, uriLength * sizeof(char)); - if (NULL == coapUri) + else { - OIC_LOG(ERROR, TAG, "error"); - return NULL; - } + coap_list_t *optlist = NULL; - strcat(coapUri, COAP_HEADER); - strcat(coapUri, uri); + if (CA_MSG_ACKNOWLEDGE != info.type) + { + if (NULL == uri) + { + OIC_LOG(ERROR, TAG, "uri NULL"); + return NULL; + } - // parsing options in URI - coap_list_t *optlist = NULL; - CAParseURI(coapUri, &optlist); - OICFree(coapUri); - coapUri = NULL; + uint32_t length = strlen(uri); + if (CA_MAX_URI_LENGTH < length) + { + OIC_LOG(ERROR, TAG, "URI len err"); + return NULL; + } - // parsing options in HeadOption - CAParseHeadOption(code, info, &optlist); + uint32_t uriLength = length + sizeof(COAP_URI_HEADER); + char *coapUri = (char *) OICCalloc(1, uriLength); + if (NULL == coapUri) + { + OIC_LOG(ERROR, TAG, "out of memory"); + return NULL; + } - coap_pdu_t *pdu = CAGeneratePduImpl((code_t) code, optlist, info, info.payload); - if (NULL == pdu) - { - OIC_LOG(ERROR, TAG, "pdu NULL"); - return NULL; - } + strcat(coapUri, COAP_URI_HEADER); + strcat(coapUri, uri); - // free option list - coap_delete_list(optlist); + // parsing options in URI + CAResult_t res = CAParseURI(coapUri, &optlist); + if (CA_STATUS_OK != res) + { + if (optlist) + { + coap_delete_list(optlist); + } + OICFree(coapUri); + return NULL; + } + + OICFree(coapUri); + } + // parsing options in HeadOption + CAResult_t ret = CAParseHeadOption(code, info, &optlist); + if (CA_STATUS_OK != ret) + { + coap_delete_list(optlist); + return NULL; + } + + pdu = CAGeneratePDUImpl((code_t) code, optlist, info, info.payload); + if (NULL == pdu) + { + OIC_LOG(ERROR, TAG, "pdu NULL"); + coap_delete_list(optlist); + return NULL; + } + + // free option list + coap_delete_list(optlist); + } // pdu print method : coap_show_pdu(pdu); OIC_LOG(DEBUG, TAG, "OUT"); @@ -164,7 +192,19 @@ coap_pdu_t *CAGeneratePdu(const char *uri, uint32_t code, const CAInfo_t info) coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode) { OIC_LOG(DEBUG, TAG, "IN"); + + if (NULL == data) + { + OIC_LOG(ERROR, TAG, "data is null"); + return NULL; + } + coap_pdu_t *outpdu = coap_new_pdu(); + if (NULL == outpdu) + { + OIC_LOG(ERROR, TAG, "outpdu is null"); + return NULL; + } if (0 >= coap_pdu_parse((unsigned char *) data, length, outpdu)) { @@ -175,64 +215,63 @@ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode) if (outCode) { - (*outCode) = (uint32_t) outpdu->hdr->code; + (*outCode) = (uint32_t) CA_RESPONSE_CODE(outpdu->hdr->code); } + OIC_LOG(DEBUG, TAG, "OUT"); return outpdu; } -coap_pdu_t *CAGeneratePduImpl(code_t code, coap_list_t *options, - const CAInfo_t info, const char *payload) +coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t info, + const char *payload) { OIC_LOG(DEBUG, TAG, "IN"); coap_pdu_t *pdu = coap_new_pdu(); - if (!pdu) + + if (NULL == pdu) { - OIC_LOG(ERROR, TAG, "Out of memory"); + OIC_LOG(ERROR, TAG, "malloc failed"); return NULL; } - OIC_LOG_V(DEBUG, TAG, "msgId: %d", info.messageId); - if (CA_MSG_ACKNOWLEDGE == info.type || CA_MSG_RESET == info.type) + OIC_LOG_V(DEBUG, TAG, "msgID is %d", info.messageId); + uint16_t message_id; + if (0 == info.messageId) { - pdu->hdr->id = htons(info.messageId); + /* initialize message id */ + prng((uint8_t * ) &message_id, sizeof(message_id)); + + OIC_LOG_V(DEBUG, TAG, "gen msg id=%d", message_id); } else { - uint16_t message_id; - if (info.messageId == 0) - { - /* initialize message id */ - prng((unsigned char *)&message_id, sizeof(message_id)); - OIC_LOG_V(DEBUG, TAG, "gen msg id=%d", message_id); - } - else - { - /* use saved message id */ - message_id = info.messageId; - } - pdu->hdr->id = htons(message_id); + /* use saved message id */ + message_id = info.messageId; } + pdu->hdr->id = message_id; + OIC_LOG_V(DEBUG, TAG, "messageId in pdu is %d, %d", message_id, pdu->hdr->id); + pdu->hdr->type = info.type; pdu->hdr->code = COAP_RESPONSE_CODE(code); - if (info.token) + if (info.token && CA_EMPTY != code) { uint32_t tokenLength = info.tokenLength; OIC_LOG_V(DEBUG, TAG, "token info token length: %d, token :", tokenLength); OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *)info.token, tokenLength); - int32_t ret = coap_add_token(pdu, tokenLength, (const unsigned char *) info.token); + int32_t ret = coap_add_token(pdu, tokenLength, (unsigned char *) info.token); if (0 == ret) { - OIC_LOG(DEBUG, TAG, "can't add token"); + OIC_LOG(ERROR, TAG, "can't add token"); } } if (options) { - for (coap_list_t *opt = options; opt; opt = opt->next) + coap_list_t *opt; + for (opt = options; opt; opt = opt->next) { OIC_LOG_V(DEBUG, TAG, "[%s] opt will be added.", COAP_OPTION_DATA(*(coap_option *) opt->data)); @@ -253,59 +292,104 @@ coap_pdu_t *CAGeneratePduImpl(code_t code, coap_list_t *options, return pdu; } -void CAParseURI(const char *uriInfo, coap_list_t **optlist) +CAResult_t CAParseURI(const char *uriInfo, coap_list_t **optlist) { OIC_LOG(DEBUG, TAG, "IN"); + if (NULL == uriInfo) + { + OIC_LOG(ERROR, TAG, "uriInfo is null"); + return CA_STATUS_INVALID_PARAM; + } + OIC_LOG_V(DEBUG, TAG, "url : %s", uriInfo); + if (NULL == optlist) + { + OIC_LOG(ERROR, TAG, "optlist is null"); + return CA_STATUS_INVALID_PARAM; + } + /* split arg into Uri-* options */ coap_uri_t uri; coap_split_uri((unsigned char *) uriInfo, strlen(uriInfo), &uri); if (uri.port != COAP_DEFAULT_PORT) { - unsigned char portbuf[2] = {0}; - coap_insert(optlist, - CACreateNewOptionNode(COAP_OPTION_URI_PORT, - coap_encode_var_bytes(portbuf, uri.port), portbuf), - CAOrderOpts); + unsigned char portbuf[CA_PORT_BUFFER_SIZE] = { 0 }; + int ret = coap_insert(optlist, + CACreateNewOptionNode(COAP_OPTION_URI_PORT, + coap_encode_var_bytes(portbuf, uri.port), + portbuf), + CAOrderOpts); + if (ret <= 0) + { + return CA_STATUS_INVALID_PARAM; + } } + if (uri.path.s && uri.path.length) + { + CAResult_t ret = CAParseUriPartial(uri.path.s, uri.path.length, COAP_OPTION_URI_PATH, + optlist); + if (CA_STATUS_OK != ret) + { + OIC_LOG(ERROR, TAG, "CAParseUriPartial failed(uri path)"); + return ret; + } + } - CAParseUriPartial(uri.path.s, uri.path.length, COAP_OPTION_URI_PATH, optlist); - - CAParseUriPartial(uri.query.s, uri.query.length, COAP_OPTION_URI_QUERY, optlist); + if (uri.query.s && uri.query.length) + { + CAResult_t ret = CAParseUriPartial(uri.query.s, uri.query.length, COAP_OPTION_URI_QUERY, + optlist); + if (CA_STATUS_OK != ret) + { + OIC_LOG(ERROR, TAG, "CAParseUriPartial failed(uri query)"); + return ret; + } + } OIC_LOG(DEBUG, TAG, "OUT"); + return CA_STATUS_OK; } -void CAParseUriPartial(const unsigned char *str, size_t length, - int target, coap_list_t **optlist) +CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target, + coap_list_t **optlist) { + if (!optlist) + { + OIC_LOG(ERROR, TAG, "optlist is null"); + return CA_STATUS_INVALID_PARAM; + } + if ((target != COAP_OPTION_URI_PATH) && (target != COAP_OPTION_URI_QUERY)) { // should never occur. Log just in case. OIC_LOG(DEBUG, TAG, "Unexpected URI component."); + return CA_NOT_SUPPORTED; } else if (str && length) { unsigned char uriBuffer[CA_BUFSIZE] = { 0 }; unsigned char *pBuf = uriBuffer; size_t buflen = sizeof(uriBuffer); - int res = (target == COAP_OPTION_URI_PATH) ? - coap_split_path(str, length, pBuf, &buflen) : - coap_split_query(str, length, pBuf, &buflen); + int res = (target == COAP_OPTION_URI_PATH) ? coap_split_path(str, length, pBuf, &buflen) : + coap_split_query(str, length, pBuf, &buflen); if (res > 0) { size_t prevIdx = 0; while (res--) { - coap_insert(optlist, - CACreateNewOptionNode(target, COAP_OPT_LENGTH(pBuf), - COAP_OPT_VALUE(pBuf)), - CAOrderOpts); + int ret = coap_insert(optlist, + CACreateNewOptionNode(target, COAP_OPT_LENGTH(pBuf), + COAP_OPT_VALUE(pBuf)), + CAOrderOpts); + if (ret <= 0) + { + return CA_STATUS_INVALID_PARAM; + } size_t optSize = COAP_OPT_SIZE(pBuf); if ((prevIdx + optSize) < buflen) @@ -317,42 +401,69 @@ void CAParseUriPartial(const unsigned char *str, size_t length, } else { - OIC_LOG_V(DEBUG, TAG, "Problem parsing URI : %d for %d", res, target); + OIC_LOG_V(ERROR, TAG, "Problem parsing URI : %d for %d", res, target); + return CA_STATUS_FAILED; } } + else + { + OIC_LOG(ERROR, TAG, "str or length is not available"); + return CA_STATUS_FAILED; + } + + return CA_STATUS_OK; } -void CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **optlist) +CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **optlist) { OIC_LOG(DEBUG, TAG, "IN"); OIC_LOG_V(DEBUG, TAG, "parse Head Opt: %d", info.numOptions); - for (uint32_t i = 0; i < info.numOptions; i++) + if (!optlist) + { + OIC_LOG(ERROR, TAG, "optlist is null"); + return CA_STATUS_INVALID_PARAM; + } + + uint32_t i; + for (i = 0; i < info.numOptions; i++) { - uint32_t id = info.options[i].optionID; + if(!(info.options + i)) + { + OIC_LOG(ERROR, TAG, "options is not available"); + return CA_STATUS_FAILED; + } + + uint32_t id = (info.options + i)->optionID; if (COAP_OPTION_URI_PATH == id || COAP_OPTION_URI_QUERY == id) { OIC_LOG_V(DEBUG, TAG, "not Header Opt: %d", id); } else { - OIC_LOG_V(DEBUG, TAG, "Head Opt ID: %d", info.options[i].optionID); - OIC_LOG_V(DEBUG, TAG, "Head Opt data: %s", info.options[i].optionData); - OIC_LOG_V(DEBUG, TAG, "Head Opt len: %d", info.options[i].optionLength); - - coap_insert(optlist, - CACreateNewOptionNode(info.options[i].optionID, - info.options[i].optionLength, - info.options[i].optionData), CAOrderOpts); + if ((info.options + i)->optionData && (info.options + i)->optionLength > 0) + { + OIC_LOG_V(DEBUG, TAG, "Head opt ID: %d", id); + OIC_LOG_V(DEBUG, TAG, "Head opt data: %s", (info.options + i)->optionData); + OIC_LOG_V(DEBUG, TAG, "Head opt length: %d", (info.options + i)->optionLength); + int ret = coap_insert(optlist, + CACreateNewOptionNode(id, (info.options + i)->optionLength, + (info.options + i)->optionData), + CAOrderOpts); + if (ret <= 0) + { + return CA_STATUS_INVALID_PARAM; + } + } } } OIC_LOG(DEBUG, TAG, "OUT"); + return CA_STATUS_OK; } -coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, - const uint8_t *data) +coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, const uint8_t *data) { OIC_LOG(DEBUG, TAG, "IN"); @@ -379,11 +490,11 @@ coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, if (!node) { - OIC_LOG(DEBUG, TAG, "new_listnode rets NULL"); + OIC_LOG(ERROR, TAG, "node is NULL"); coap_free(option); return NULL; } - //coap_free(option); + OIC_LOG(DEBUG, TAG, "OUT"); return node; } @@ -396,13 +507,13 @@ int CAOrderOpts(void *a, void *b) return a < b ? -1 : 1; } - if (COAP_OPTION_KEY(*(coap_option *)a) < COAP_OPTION_KEY(*(coap_option * )b)) + if (COAP_OPTION_KEY(*(coap_option *) a) < COAP_OPTION_KEY(*(coap_option * ) b)) { return -1; } OIC_LOG(DEBUG, TAG, "OUT"); - return COAP_OPTION_KEY(*(coap_option *)a) == COAP_OPTION_KEY(*(coap_option * )b); + return COAP_OPTION_KEY(*(coap_option *) a) == COAP_OPTION_KEY(*(coap_option * ) b); } uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter) @@ -423,21 +534,20 @@ uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter) return count; } -void CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, - char *outUri, uint32_t buflen) +CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, + char *outUri, uint32_t buflen) { OIC_LOG(DEBUG, TAG, "IN"); if (!pdu || !outCode || !outInfo || !outUri) { OIC_LOG(ERROR, TAG, "NULL pointer param"); - return; + return CA_STATUS_INVALID_PARAM; } coap_opt_iterator_t opt_iter; coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL); - // set code if (outCode) { (*outCode) = (uint32_t) CA_RESPONSE_CODE(pdu->hdr->code); @@ -445,23 +555,23 @@ void CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInf // init HeaderOption list uint32_t count = CAGetOptionCount(opt_iter); - memset(outInfo, 0, sizeof(*outInfo)); + outInfo->numOptions = count; // set type outInfo->type = pdu->hdr->type; // set message id - outInfo->messageId = ntohs(pdu->hdr->id); + outInfo->messageId = pdu->hdr->id; if (count > 0) { outInfo->options = (CAHeaderOption_t *) OICCalloc(count, sizeof(CAHeaderOption_t)); - if (outInfo->options == NULL) + if (NULL == outInfo->options) { OIC_LOG(ERROR, TAG, "Out of memory"); - return; + return CA_MEMORY_ALLOC_FAILED; } } @@ -515,7 +625,7 @@ void CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInf } else if (COAP_OPTION_URI_QUERY == opt_iter.type) { - if(false == isQueryBeingProcessed) + if (false == isQueryBeingProcessed) { // Make sure there is enough room in the optionResult buffer if (optionLength < sizeof(optionResult)) @@ -581,9 +691,9 @@ void CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInf outInfo->token = (char *) OICMalloc(pdu->hdr->token_length); if (NULL == outInfo->token) { - OIC_LOG(ERROR, TAG, "memory allocation failed"); + OIC_LOG(ERROR, TAG, "Out of memory"); OICFree(outInfo->options); - return; + return CA_MEMORY_ALLOC_FAILED; } memcpy(outInfo->token, pdu->hdr->token, pdu->hdr->token_length); } @@ -593,22 +703,22 @@ void CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInf // set payload data if (NULL != pdu->data) { - uint32_t payloadLength = strlen((const char *) pdu->data) + 1; + uint32_t payloadLength = strlen((char*) pdu->data); OIC_LOG(DEBUG, TAG, "inside pdu->data"); outInfo->payload = (char *) OICMalloc(payloadLength + 1); - if (outInfo->payload == NULL) + if (NULL == outInfo->payload) { OIC_LOG(ERROR, TAG, "Out of memory"); OICFree(outInfo->options); OICFree(outInfo->token); - return; + return CA_MEMORY_ALLOC_FAILED; } memcpy(outInfo->payload, pdu->data, payloadLength); outInfo->payload[payloadLength] = '\0'; } uint32_t length = strlen(optionResult); - OIC_LOG_V(DEBUG, TAG, "made URL length: %d, %d, %d...\n", length, buflen, strlen(outUri)); + OIC_LOG_V(DEBUG, TAG, "URL length:%d,%d,%d", length, buflen, strlen(outUri)); if (buflen >= length) { memcpy(outUri, optionResult, length); @@ -616,28 +726,64 @@ void CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInf #ifdef ARDUINO OIC_LOG_V(DEBUG, TAG, "made URL:%s\n", optionResult); #else - OIC_LOG_V(DEBUG, TAG, "made URL : %s, %s\n", optionResult, outUri); + OIC_LOG_V(DEBUG, TAG, "made URL : %s, %s", optionResult, outUri); #endif } OIC_LOG(DEBUG, TAG, "OUT"); - return; + return CA_STATUS_OK; exit: OIC_LOG(ERROR, TAG, "buffer too small"); OICFree(outInfo->options); + return CA_STATUS_FAILED; +} + +CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo) +{ + OIC_LOG(DEBUG, TAG, "IN"); + if (NULL == pdu_hdr) + { + OIC_LOG(ERROR, TAG, "pdu_hdr is null"); + return CA_STATUS_INVALID_PARAM; + } + + if (NULL == outInfo) + { + OIC_LOG(ERROR, TAG, "outInfo is null"); + return CA_STATUS_INVALID_PARAM; + } + + // set token data + if (pdu_hdr->token_length > 0) + { + OIC_LOG_V(DEBUG, TAG, "token len:%d", pdu_hdr->token_length); + outInfo->token = (char *) OICMalloc(pdu_hdr->token_length); + if (NULL == outInfo->token) + { + OIC_LOG(ERROR, TAG, "out of memory"); + return CA_MEMORY_ALLOC_FAILED; + } + memcpy(outInfo->token, pdu_hdr->token, pdu_hdr->token_length); + } + + outInfo->tokenLength = pdu_hdr->token_length; + + OIC_LOG(DEBUG, TAG, "OUT"); + + return CA_STATUS_OK; } CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength) { OIC_LOG(DEBUG, TAG, "IN"); - if(!token) + if (!token) { OIC_LOG(ERROR, TAG, "invalid token pointer"); return CA_STATUS_INVALID_PARAM; } - if((tokenLength > CA_MAX_TOKEN_LEN) || (0 == tokenLength)) + if ((tokenLength > CA_MAX_TOKEN_LEN) || (0 == tokenLength)) { OIC_LOG(ERROR, TAG, "invalid token length"); return CA_STATUS_INVALID_PARAM; @@ -652,7 +798,7 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength) #endif if (SEED == -1) { - OIC_LOG(DEBUG, TAG, "Failed to Create Seed!"); + OIC_LOG(ERROR, TAG, "seed is not made"); SEED = 0; return CA_STATUS_FAILED; } @@ -667,12 +813,13 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength) char *temp = (char *) OICCalloc(tokenLength, sizeof(char)); if (NULL == temp) { - OIC_LOG(ERROR, TAG, "CAGenerateTokenInternal, Memory allocation failed !"); + OIC_LOG(ERROR, TAG, "Out of memory"); return CA_MEMORY_ALLOC_FAILED; } // set random byte - for (uint8_t index = 0; index < tokenLength; index++) + uint8_t index; + for (index = 0; index < tokenLength; index++) { // use valid characters #ifdef ARDUINO @@ -685,8 +832,8 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength) // save token *token = temp; - OIC_LOG_V(DEBUG, TAG, "token info token length: %d, token :", tokenLength); - OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *)token, tokenLength); + OIC_LOG_V(DEBUG, TAG, "token len:%d, token:", tokenLength); + OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *)(*token), tokenLength); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; @@ -705,23 +852,14 @@ void CADestroyInfo(CAInfo_t *info) if (NULL != info) { - if (NULL != info->options) - { - OIC_LOG(DEBUG, TAG, "free opt"); - OICFree(info->options); - } + OIC_LOG(DEBUG, TAG, "free options"); + OICFree(info->options); - if (NULL != info->token) - { - OIC_LOG(DEBUG, TAG, "free tok"); - OICFree(info->token); - } + OIC_LOG(DEBUG, TAG, "free token"); + OICFree(info->token); - if (NULL != info->payload) - { - OIC_LOG(DEBUG, TAG, "free payld"); - OICFree(info->payload); - } + OIC_LOG(DEBUG, TAG, "free payload"); + OICFree(info->payload); } OIC_LOG(DEBUG, TAG, "OUT"); @@ -729,8 +867,6 @@ void CADestroyInfo(CAInfo_t *info) uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *option, uint32_t buflen) { - assert(data || 0 == len); - if (0 == buflen || 0 == len) { OIC_LOG(ERROR, TAG, "len 0"); @@ -757,10 +893,16 @@ uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *option, uin CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void *pdu, uint32_t size) { + if (NULL == pdu) + { + OIC_LOG(ERROR, TAG, "pdu is null"); + return CA_MSG_NONCONFIRM; + } + // pdu minimum size is 4 byte. if (size < CA_PDU_MIN_SIZE) { - OIC_LOG(DEBUG, TAG, "min size"); + OIC_LOG(ERROR, TAG, "min size"); return CA_MSG_NONCONFIRM; } @@ -775,10 +917,16 @@ CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void *pdu, uint32_t size uint16_t CAGetMessageIdFromPduBinaryData(const void *pdu, uint32_t size) { + if (NULL == pdu) + { + OIC_LOG(ERROR, TAG, "pdu is null"); + return 0; + } + // pdu minimum size is 4 byte. if (size < CA_PDU_MIN_SIZE) { - OIC_LOG(DEBUG, TAG, "min size"); + OIC_LOG(ERROR, TAG, "min size"); return 0; } @@ -788,5 +936,30 @@ uint16_t CAGetMessageIdFromPduBinaryData(const void *pdu, uint32_t size) return 0; } - return ntohs(hdr->id); + return hdr->id; +} + +CAResponseResult_t CAGetCodeFromPduBinaryData(const void *pdu, uint32_t size) +{ + if (NULL == pdu) + { + OIC_LOG(ERROR, TAG, "pdu is null"); + return CA_NOT_FOUND; + } + + // pdu minimum size is 4 byte. + if (size < CA_PDU_MIN_SIZE) + { + OIC_LOG(ERROR, TAG, "min size"); + return CA_NOT_FOUND; + } + + coap_hdr_t *hdr = (coap_hdr_t *) pdu; + if (NULL == hdr) + { + OIC_LOG(ERROR, TAG, "hdr is null"); + return CA_NOT_FOUND; + } + + return (CAResponseResult_t) CA_RESPONSE_CODE(hdr->code); } diff --git a/resource/csdk/connectivity/src/caretransmission.c b/resource/csdk/connectivity/src/caretransmission.c index e222d08..a80812a 100644 --- a/resource/csdk/connectivity/src/caretransmission.c +++ b/resource/csdk/connectivity/src/caretransmission.c @@ -46,7 +46,7 @@ #include "oic_malloc.h" #include "logger.h" -#define TAG PCF("RET") +#define TAG PCF("CA") typedef struct { @@ -70,11 +70,11 @@ uint64_t getCurrentTimeInMicroSeconds(); * @param currentTime [IN]microseconds * @param timeStamp [IN]microseconds * @param timeoutValue [IN]microseconds - * @param triedCount [IN] + * @param triedCount [IN]Number of retransmission tried * @return true if the timeout period has elapsed, false otherwise */ static bool CACheckTimeout(uint64_t currentTime, uint64_t timeStamp, uint64_t timeoutValue, - uint8_t triedCount) + uint8_t triedCount) { // #1. calculate timeout uint32_t milliTimeoutValue = timeoutValue * 0.001; @@ -104,17 +104,23 @@ static uint64_t CAGetTimeoutValue() static void CACheckRetransmissionList(CARetransmission_t *context) { + if (NULL == context) + { + OIC_LOG(ERROR, TAG, "context is null.."); + return; + } + // mutex lock u_mutex_lock(context->threadMutex); - int32_t i = 0; + uint32_t i = 0; uint32_t len = u_arraylist_length(context->dataList); for (i = 0; i < len; i++) { CARetransmissionData_t *retData = u_arraylist_get(context->dataList, i); - if (retData == NULL) + if (NULL == retData) { continue; } @@ -144,13 +150,13 @@ static void CACheckRetransmissionList(CARetransmission_t *context) if (removedData != NULL) { OIC_LOG_V(DEBUG, TAG, "max trying count, remove retransmission CON data!!,\ - message id(%d)", removedData->messageId); + message id(%d)", removedData->messageId); // callback for retransmit timeout if (context->timeoutCallback != NULL) { context->timeoutCallback(removedData->endpoint, removedData->pdu, - removedData->size); + removedData->size); } CADestroyRemoteEndpointInternal(removedData->endpoint); @@ -181,7 +187,7 @@ static void CARetransmissionBaseRoutine(void *threadValue) CARetransmission_t *context = (CARetransmission_t *) threadValue; - if (context == NULL) + if (NULL == context) { OIC_LOG(ERROR, TAG, "thread data passing error!!"); @@ -207,7 +213,7 @@ static void CARetransmissionBaseRoutine(void *threadValue) { // check each RETRANSMISSION_CHECK_PERIOD_SEC time. OIC_LOG_V(DEBUG, TAG, "wait..(%d)microseconds", - RETRANSMISSION_CHECK_PERIOD_SEC * (uint64_t) 1000000); + RETRANSMISSION_CHECK_PERIOD_SEC * (uint64_t) 1000000); // wait u_cond_wait_until(context->threadCond, context->threadMutex, @@ -233,19 +239,20 @@ static void CARetransmissionBaseRoutine(void *threadValue) } CAResult_t CARetransmissionInitialize(CARetransmission_t *context, u_thread_pool_t handle, - CADataSendMethod_t retransmissionSendMethod, CATimeoutCallback_t timeoutCallback, - CARetransmissionConfig_t* config) + CADataSendMethod_t retransmissionSendMethod, + CATimeoutCallback_t timeoutCallback, + CARetransmissionConfig_t* config) { - if (context == NULL) + if (NULL == context) { OIC_LOG(ERROR, TAG, "thread instance is empty.."); - return CA_STATUS_FAILED; + return CA_STATUS_INVALID_PARAM; } - if (handle == NULL) + if (NULL == handle) { OIC_LOG(ERROR, TAG, "thread pool handle is empty.."); - return CA_STATUS_FAILED; + return CA_STATUS_INVALID_PARAM; } OIC_LOG(DEBUG, TAG, "thread initialize.."); @@ -254,7 +261,7 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, u_thread_pool CARetransmissionConfig_t cfg = { 0 }; - if (config == NULL) + if (NULL == config) { // setDefault cfg.supportType = DEFAULT_RETRANSMISSION_TYPE; @@ -280,16 +287,16 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, u_thread_pool CAResult_t CARetransmissionStart(CARetransmission_t *context) { - if (context == NULL) + if (NULL == context) { OIC_LOG(ERROR, TAG, "context is empty.."); - return CA_STATUS_FAILED; + return CA_STATUS_INVALID_PARAM; } - if (context->threadPool == NULL) + if (NULL == context->threadPool) { OIC_LOG(ERROR, TAG, "thread pool handle is empty.."); - return CA_STATUS_FAILED; + return CA_STATUS_INVALID_PARAM; } CAResult_t res = u_thread_pool_add_task(context->threadPool, CARetransmissionBaseRoutine, @@ -305,9 +312,10 @@ CAResult_t CARetransmissionStart(CARetransmission_t *context) } CAResult_t CARetransmissionSentData(CARetransmission_t *context, - const CARemoteEndpoint_t* endpoint, const void* pdu, uint32_t size) + const CARemoteEndpoint_t* endpoint, const void* pdu, + uint32_t size) { - if (context == NULL || endpoint == NULL || pdu == NULL) + if (NULL == context || NULL == endpoint || NULL == pdu) { OIC_LOG(ERROR, TAG, "invalid parameter.."); return CA_STATUS_INVALID_PARAM; @@ -318,7 +326,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context, { OIC_LOG_V(DEBUG, TAG, "not supported connectivity type for retransmission..(%d)", endpoint->connectivityType); - return CA_STATUS_OK; + return CA_NOT_SUPPORTED; } // #1. check PDU method type and get message id. @@ -329,32 +337,33 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context, if (type != CA_MSG_CONFIRM) { - return CA_STATUS_OK; + OIC_LOG(DEBUG, TAG, "not supported message type for retransmission.."); + return CA_NOT_SUPPORTED; } // create retransmission data CARetransmissionData_t *retData = (CARetransmissionData_t *) OICCalloc( 1, sizeof(CARetransmissionData_t)); - if (retData == NULL) + if (NULL == retData) { OIC_LOG(ERROR, TAG, "memory error!!"); return CA_MEMORY_ALLOC_FAILED; } // copy PDU data - void *pduData = (void *) OICMalloc(sizeof(int8_t) * size); - if (pduData == NULL) + void *pduData = (void *) OICMalloc(size); + if (NULL == pduData) { OICFree(retData); - OIC_LOG(ERROR, TAG, "memory error!!"); + OIC_LOG_V(ERROR, TAG, "memory error!!"); return CA_MEMORY_ALLOC_FAILED; } - memcpy(pduData, pdu, sizeof(int8_t) * size); + memcpy(pduData, pdu, size); // clone remote endpoint CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(endpoint); - if (remoteEndpoint == NULL) + if (NULL == remoteEndpoint) { OICFree(retData); OICFree(pduData); @@ -382,14 +391,14 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context, { CARetransmissionData_t *currData = u_arraylist_get(context->dataList, i); - if (currData == NULL) + if (NULL == currData) { continue; } // found index - if (retData != NULL && (currData->endpoint->connectivityType == endpoint->connectivityType) - && currData->messageId == messageId) + if (NULL != currData->endpoint && currData->messageId == messageId + && (currData->endpoint->connectivityType == endpoint->connectivityType)) { OIC_LOG(ERROR, TAG, "Duplicate message ID"); @@ -405,7 +414,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context, u_arraylist_add(context->dataList, (void *) retData); - // notity the thread + // notify the thread u_cond_signal(context->threadCond); // mutex unlock @@ -416,9 +425,10 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context, CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, const CARemoteEndpoint_t *endpoint, const void *pdu, - uint32_t size) + uint32_t size, void **retransmissionPdu) { - if (context == NULL || endpoint == NULL || pdu == NULL) + OIC_LOG_V(DEBUG, TAG, "IN - CARetransmissionReceivedData"); + if (NULL == context || NULL == endpoint || NULL == pdu || NULL == retransmissionPdu) { OIC_LOG(ERROR, TAG, "invalid parameter.."); return CA_STATUS_INVALID_PARAM; @@ -453,25 +463,68 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, // find index for (i = 0; i < len; i++) { - CARetransmissionData_t *retData = u_arraylist_get(context->dataList, i); + CARetransmissionData_t *retData = (CARetransmissionData_t *) u_arraylist_get( + context->dataList, i); + + if (NULL == retData) + { + continue; + } // found index - if (retData != NULL && (retData->endpoint->connectivityType == endpoint->connectivityType) - && retData->messageId == messageId) + if (NULL != retData->endpoint && retData->messageId == messageId + && (retData->endpoint->connectivityType == endpoint->connectivityType)) { + // get pdu data for getting token when CA_EMPTY(RST/ACK) is received from remote device + // if retransmission was finish..token will be unavailable. + if (CA_EMPTY == CAGetCodeFromPduBinaryData(pdu, size)) + { + OIC_LOG(DEBUG, TAG, "code is CA_EMPTY.."); + + if (NULL == retData->pdu) + { + OIC_LOG(ERROR, TAG, "retData->pdu is null"); + OICFree(retData); + // mutex unlock + u_mutex_unlock(context->threadMutex); + + return CA_STATUS_FAILED; + } + + // copy PDU data + (*retransmissionPdu) = (void *) OICCalloc(1, retData->size); + if ((*retransmissionPdu) == NULL) + { + OICFree(retData); + OIC_LOG(ERROR, TAG, "memory error!!"); + + // mutex unlock + u_mutex_unlock(context->threadMutex); + + return CA_MEMORY_ALLOC_FAILED; + } + memcpy((*retransmissionPdu), retData->pdu, retData->size); + } + // #2. remove data from list CARetransmissionData_t *removedData = u_arraylist_remove(context->dataList, i); - - if (removedData != NULL) + if (NULL == removedData) { - OIC_LOG_V(DEBUG, TAG, "remove retransmission CON data!!, message id(%d)", - messageId); + OIC_LOG(ERROR, TAG, "Removed data is NULL"); - CADestroyRemoteEndpointInternal(removedData->endpoint); - OICFree(removedData->pdu); + // mutex unlock + u_mutex_unlock(context->threadMutex); - OICFree(removedData); + return CA_STATUS_FAILED; } + + OIC_LOG_V(DEBUG, TAG, "remove retransmission CON data!!, message id(%d)", + messageId); + + CADestroyRemoteEndpointInternal(removedData->endpoint); + OICFree(removedData->pdu); + OICFree(removedData); + break; } } @@ -479,15 +532,16 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, // mutex unlock u_mutex_unlock(context->threadMutex); + OIC_LOG(DEBUG, TAG, "OUT - CARetransmissionReceivedData"); return CA_STATUS_OK; } CAResult_t CARetransmissionStop(CARetransmission_t *context) { - if (context == NULL) + if (NULL == context) { OIC_LOG(ERROR, TAG, "context is empty.."); - return CA_STATUS_FAILED; + return CA_STATUS_INVALID_PARAM; } OIC_LOG(DEBUG, TAG, "retransmission stop request!!"); @@ -511,10 +565,10 @@ CAResult_t CARetransmissionStop(CARetransmission_t *context) CAResult_t CARetransmissionDestroy(CARetransmission_t *context) { - if (context == NULL) + if (NULL == context) { OIC_LOG(ERROR, TAG, "context is empty.."); - return CA_STATUS_FAILED; + return CA_STATUS_INVALID_PARAM; } OIC_LOG(DEBUG, TAG, "retransmission context destroy.."); @@ -543,4 +597,3 @@ uint64_t getCurrentTimeInMicroSeconds() #endif return currentTime; } - diff --git a/resource/csdk/connectivity/src/caretransmission_singlethread.c b/resource/csdk/connectivity/src/caretransmission_singlethread.c index 3fd26be..0f44e47 100644 --- a/resource/csdk/connectivity/src/caretransmission_singlethread.c +++ b/resource/csdk/connectivity/src/caretransmission_singlethread.c @@ -86,21 +86,20 @@ static bool CACheckTimeout(uint64_t currentTime, uint64_t timeStamp, uint8_t tri void CACheckRetransmissionList() { - uint64_t currentTime = 0; - - uint32_t i = 0; uint32_t len = u_arraylist_length(g_retransmissionPtr->dataList); OIC_LOG_V(DEBUG, TAG, "len=%d", len); - for (i = 0; i < len; i++) + for (uint32_t i = 0; i < len; i++) { CARetransmissionData_t *retData = - (CARetransmissionData_t *)u_arraylist_get(g_retransmissionPtr->dataList, i); + (CARetransmissionData_t *) u_arraylist_get(g_retransmissionPtr->dataList, i); - if (retData == NULL) + if (NULL == retData) + { continue; + } - currentTime = getCurrentTimeInMicroSeconds(); + uint64_t currentTime = getCurrentTimeInMicroSeconds(); OIC_LOG_V(DEBUG, TAG, "currtime=%lu", currentTime); if (CACheckTimeout(currentTime, retData->timeStamp, retData->triedCount)) @@ -122,14 +121,16 @@ void CACheckRetransmissionList() // #4. if tried count is max, remove the retransmission data from list. if (retData->triedCount >= g_retransmissionPtr->config.tryingCount) { - CARetransmissionData_t *removedData = - (CARetransmissionData_t *)u_arraylist_remove(g_retransmissionPtr->dataList, i); + CARetransmissionData_t *removedData = (CARetransmissionData_t *) u_arraylist_remove( + g_retransmissionPtr->dataList, i); if (NULL == removedData) { - OIC_LOG(DEBUG, TAG, "Removed data is NULL"); + OIC_LOG(ERROR, TAG, "Removed data is NULL"); return; } + OIC_LOG(DEBUG, TAG, "max trycount rchd"); + OIC_LOG_V(DEBUG, TAG, "max trycount, remove retransmission CON data!!, messageid=%d", removedData->messageId); @@ -137,7 +138,7 @@ void CACheckRetransmissionList() if (g_retransmissionPtr->timeoutCallback != NULL) { g_retransmissionPtr->timeoutCallback(removedData->endpoint, removedData->pdu, - removedData->size); + removedData->size); } CADestroyRemoteEndpointInternal(removedData->endpoint); @@ -156,7 +157,7 @@ void CARetransmissionBaseRoutine(void *threadValue) { CARetransmission_t *context = (CARetransmission_t *) threadValue; - if (context == NULL) + if (NULL == context) { OIC_LOG(ERROR, TAG, "cnxt null"); return; @@ -177,10 +178,10 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, CARetransmissionConfig_t *config) { OIC_LOG(DEBUG, TAG, "IN"); - if (context == NULL) + if (NULL == context) { OIC_LOG(ERROR, TAG, "cnxt null"); - return CA_STATUS_FAILED; + return CA_STATUS_INVALID_PARAM; } memset(context, 0, sizeof(CARetransmission_t)); @@ -188,10 +189,10 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, CARetransmissionConfig_t cfg; memset(&cfg, 0, sizeof(CARetransmissionConfig_t)); - if (config == NULL) + if (NULL == config) { // setDefault - cfg.supportType = (CAConnectivityType_t)DEFAULT_RETRANSMISSION_TYPE; + cfg.supportType = (CAConnectivityType_t) DEFAULT_RETRANSMISSION_TYPE; cfg.tryingCount = DEFAULT_RETRANSMISSION_COUNT; } else @@ -212,23 +213,22 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context, return CA_STATUS_OK; } -CAResult_t CARetransmissionSentData(CARetransmission_t *context, - const CARemoteEndpoint_t *endpoint, +CAResult_t CARetransmissionSentData(CARetransmission_t *context, const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size) { OIC_LOG(DEBUG, TAG, "IN"); - if (context == NULL || endpoint == NULL || pdu == NULL) + if (NULL == context || NULL == endpoint || NULL == pdu) { - OIC_LOG(DEBUG, TAG, "error"); + OIC_LOG(ERROR, TAG, "error"); return CA_STATUS_INVALID_PARAM; } // #0. check support connectivity type if (!(context->config.supportType & endpoint->connectivityType)) { - OIC_LOG(DEBUG, TAG, "error"); - OIC_LOG_V(DEBUG, TAG, "not supported conntype=%d", endpoint->connectivityType); - return CA_STATUS_OK; + OIC_LOG(ERROR, TAG, "error"); + OIC_LOG_V(ERROR, TAG, "not supported conntype=%d", endpoint->connectivityType); + return CA_NOT_SUPPORTED; } // #1. check PDU method type and get message id. @@ -239,38 +239,37 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context, if (type != CA_MSG_CONFIRM) { - OIC_LOG(DEBUG, TAG, "error"); - return CA_STATUS_OK; + OIC_LOG(DEBUG, TAG, "not supported message type"); + return CA_NOT_SUPPORTED; } // create retransmission data - CARetransmissionData_t *retData = (CARetransmissionData_t *) OICMalloc( - sizeof(CARetransmissionData_t)); + CARetransmissionData_t *retData = (CARetransmissionData_t *) OICCalloc( + 1, sizeof(CARetransmissionData_t)); - if (retData == NULL) + if (NULL == retData) { - OIC_LOG(DEBUG, TAG, "error"); + OIC_LOG(ERROR, TAG, "error"); return CA_MEMORY_ALLOC_FAILED; } - memset(retData, 0, sizeof(CARetransmissionData_t)); // copy PDU data - void *pduData = (void *) OICMalloc(sizeof(int8_t) * size); - if (pduData == NULL) + void *pduData = (void *) OICMalloc(size); + if (NULL == pduData) { OICFree(retData); - OIC_LOG(DEBUG, TAG, "error"); + OIC_LOG(ERROR, TAG, "error"); return CA_MEMORY_ALLOC_FAILED; } - memcpy(pduData, pdu, sizeof(int8_t) * size); + memcpy(pduData, pdu, size); // clone remote endpoint CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(endpoint); - if (remoteEndpoint == NULL) + if (NULL == remoteEndpoint) { OICFree(retData); OICFree(pduData); - OIC_LOG(DEBUG, TAG, "error"); + OIC_LOG(ERROR, TAG, "error"); return CA_MEMORY_ALLOC_FAILED; } @@ -293,12 +292,13 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context, } CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, - const CARemoteEndpoint_t *endpoint, const void *pdu, uint32_t size) + const CARemoteEndpoint_t *endpoint, const void *pdu, + uint32_t size, void **retransmissionPdu) { OIC_LOG(DEBUG, TAG, "IN"); - if (context == NULL || endpoint == NULL || pdu == NULL) + if (NULL == context || NULL == endpoint || NULL == pdu || NULL == retransmissionPdu) { - OIC_LOG(DEBUG, TAG, "error"); + OIC_LOG(ERROR, TAG, "error"); return CA_STATUS_INVALID_PARAM; } @@ -327,36 +327,62 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, // find index for (i = 0; i < len; i++) { - CARetransmissionData_t *retData = - (CARetransmissionData_t *)u_arraylist_get(context->dataList, i); + CARetransmissionData_t *retData = (CARetransmissionData_t *) u_arraylist_get( + context->dataList, i); - if (retData == NULL) + if (NULL == retData) + { continue; + } // found index - if ((retData->endpoint->connectivityType == endpoint->connectivityType) - && retData->messageId == messageId) - break; - } - - // #2. remove data from list - if (i < len) - { - CARetransmissionData_t *removedData = - (CARetransmissionData_t *)u_arraylist_remove(context->dataList, i); - if (NULL == removedData) + if (NULL != retData->endpoint && retData->messageId == messageId + && (retData->endpoint->connectivityType == endpoint->connectivityType)) { - OIC_LOG(DEBUG, TAG, "Removed data is NULL"); - return CA_STATUS_FAILED; - } + // get pdu data for getting token when CA_EMPTY(RST/ACK) is received from remote device + // if retransmission was finish..token will be unavailable. + if (CA_EMPTY == CAGetCodeFromPduBinaryData(pdu, size)) + { + OIC_LOG(DEBUG, TAG, "CA_EMPTY"); + + if (NULL == retData->pdu) + { + OIC_LOG(ERROR, TAG, "retData->pdu is null"); + OICFree(retData); + return CA_STATUS_FAILED; + } + + // copy PDU data + (*retransmissionPdu) = (void *) OICCalloc(1, retData->size); + if (NULL == (*retransmissionPdu)) + { + OICFree(retData); + OIC_LOG(ERROR, TAG, "error"); + return CA_MEMORY_ALLOC_FAILED; + } + memcpy((*retransmissionPdu), retData->pdu, retData->size); + } - OIC_LOG_V(DEBUG, TAG, "remove RTCON data, msgid=%d", messageId); + // #2. remove data from list + CARetransmissionData_t *removedData = (CARetransmissionData_t *) u_arraylist_remove( + context->dataList, i); + if (NULL == removedData) + { + OIC_LOG(ERROR, TAG, "Removed data is NULL"); + return CA_STATUS_FAILED; + } - CADestroyRemoteEndpointInternal(removedData->endpoint); - OICFree(removedData->pdu); + OIC_LOG_V(DEBUG, TAG, "remove RTCON data, msgid=%d", messageId); - OICFree(removedData); + CADestroyRemoteEndpointInternal(removedData->endpoint); + OICFree(removedData->pdu); + + OICFree(removedData); + + break; + } } + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } @@ -364,10 +390,10 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, CAResult_t CARetransmissionStop(CARetransmission_t *context) { OIC_LOG(DEBUG, TAG, "IN"); - if (context == NULL) + if (NULL == context) { - OIC_LOG(DEBUG, TAG, "error"); - return CA_STATUS_FAILED; + OIC_LOG(ERROR, TAG, "error"); + return CA_STATUS_INVALID_PARAM; } // set stop flag @@ -379,10 +405,10 @@ CAResult_t CARetransmissionStop(CARetransmission_t *context) CAResult_t CARetransmissionDestroy(CARetransmission_t *context) { OIC_LOG(DEBUG, TAG, "IN"); - if (context == NULL) + if (NULL == context) { - OIC_LOG(DEBUG, TAG, "error"); - return CA_STATUS_FAILED; + OIC_LOG(ERROR, TAG, "error"); + return CA_STATUS_INVALID_PARAM; } u_arraylist_free(&context->dataList); -- 2.7.4