From ef6aaed9b053341f613449edcae35c6a5e560c51 Mon Sep 17 00:00:00 2001 From: jnashok Date: Fri, 22 May 2015 16:22:14 +0900 Subject: [PATCH] CA Error handling for BT(EDR) Adapter This adds error handling from BT adapter to the interface controller Interface controller to RI Error Handling was submitted in https://gerrit.iotivity.org/gerrit/#/c/1046/ Change-Id: I6ad67d5a4da4b65bba82c45bddbee3178fb06ef3 Signed-off-by: jnashok Reviewed-on: https://gerrit.iotivity.org/gerrit/1087 Tested-by: jenkins-iotivity Reviewed-by: Jaehong Jo Reviewed-by: Erich Keane --- resource/csdk/connectivity/inc/caedradapter.h | 9 +- resource/csdk/connectivity/inc/caedrinterface.h | 22 +++++ .../src/bt_edr_adapter/android/caedrclient.c | 34 ++++++-- .../connectivity/src/bt_edr_adapter/caedradapter.c | 96 ++++++++++++++++++---- .../src/bt_edr_adapter/linux/caedradapter.c | 5 +- .../src/bt_edr_adapter/tizen/caedrclient.c | 10 +++ .../src/bt_edr_adapter/tizen/caedrendpoint.c | 2 +- .../csdk/connectivity/src/cainterfacecontroller.c | 9 +- 8 files changed, 152 insertions(+), 35 deletions(-) diff --git a/resource/csdk/connectivity/inc/caedradapter.h b/resource/csdk/connectivity/inc/caedradapter.h index b9d7839..7e0b533 100644 --- a/resource/csdk/connectivity/inc/caedradapter.h +++ b/resource/csdk/connectivity/inc/caedradapter.h @@ -43,16 +43,19 @@ extern "C" * @brief Initialize EDR Interface. * @param registerCallback [IN] Callback to register EDR interface to Connectivity * Abstraction Layer - * @param reqRespCallback [IN] Callback to notify request and response messages from server(s) - * started at Connectivity Abstraction Layer. + * @param reqRespCallback [IN] Callback to notify request and response messages from + * server(s) started at Connectivity Abstraction Layer. * @param netCallback [IN] Callback to notify the network additions to Connectivity * Abstraction Layer. + * @param errorCallback [IN] errorCallback to notify error to connectivity common logic + * layer from adapter * @param handle [IN] Threadpool Handle * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, CANetworkPacketReceivedCallback reqRespCallback, - CANetworkChangeCallback netCallback, ca_thread_pool_t handle); + CANetworkChangeCallback netCallback, + CAErrorHandleCallback errorCallback, ca_thread_pool_t handle); /** * @brief Starts EDR connectivity adapters. As its peer to peer it doesnot require to start diff --git a/resource/csdk/connectivity/inc/caedrinterface.h b/resource/csdk/connectivity/inc/caedrinterface.h index 7904c02..cbf26e9 100644 --- a/resource/csdk/connectivity/inc/caedrinterface.h +++ b/resource/csdk/connectivity/inc/caedrinterface.h @@ -103,6 +103,19 @@ typedef void (*CAEDRDataReceivedCallback)(const char *remoteAddress, const void typedef void (*CAEDRNetworkStatusCallback)(CANetworkStatus_t status); /** + * @brief Callback to notify the error in the EDR adapter + * @param remoteAddress [IN] Remote EDR Address + * @param serviceUUID [IN] Service UUID of the device + * @param data [IN] data containing token, uri and coap data + * @param dataLength [IN] length of data + * @param result [IN] error code as defined in CAResult_t + * @return NONE + * @pre Callback must be registered using CAEDRSetPacketReceivedCallback() + */ +typedef void (*CAEDRErrorHandleCallback)(const char *remoteAddress, const char *serviceUUID, + const void *data, uint32_t dataLength, CAResult_t result); + +/** * @brief Initialize the network monitor module * @param threadPool [IN] Threadpool Handle * @return #CA_STATUS_OK or Appropriate error code @@ -188,6 +201,15 @@ void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCall void CAEDRSetNetworkChangeCallback(CAEDRNetworkStatusCallback networkStateChangeCallback); /** + * @brief set error callback to notify error in EDR adapter + * + * @param errorHandleCallback [IN] Callback function to notify the error in the EDR adapter + * @return NONE + */ +void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback); + + +/** * @brief Get the local bluetooth adapter information. * * @param info [OUT] Local bluetooth adapter information diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c index 3d944ee..1ffa8ef 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c @@ -97,6 +97,12 @@ static ca_mutex g_mutexStateList = NULL; */ static ca_mutex g_mutexObjectList = NULL; +/** + * @var g_edrErrorHandler + * @brief Error callback to update error in EDR + */ +static CAEDRErrorHandleCallback g_edrErrorHandler = NULL; + typedef struct send_data { char* address; @@ -198,18 +204,18 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser const void *data, uint32_t dataLength, uint32_t *sentLength) { OIC_LOG(DEBUG, TAG, "IN"); - CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength); + CAResult_t result = CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength); OIC_LOG(DEBUG, TAG, "OUT"); - return CA_STATUS_OK; + return result; } CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data, uint32_t dataLength, uint32_t *sentLength) { OIC_LOG(DEBUG, TAG, "IN"); - CAEDRSendMulticastMessage((const char*) data, dataLength); + CAResult_t result = CAEDRSendMulticastMessage((const char*) data, dataLength); OIC_LOG(DEBUG, TAG, "OUT"); - return CA_STATUS_OK; + return result; } // It will be updated when android EDR support is added @@ -510,8 +516,8 @@ CAResult_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32 { OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data); - CAEDRSendUnicastMessageImpl(address, data, dataLen); - return CA_STATUS_OK; + CAResult_t result = CAEDRSendUnicastMessageImpl(address, data, dataLen); + return result; } CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen) @@ -534,7 +540,12 @@ CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen) isAttached = true; } - CAEDRSendMulticastMessageImpl(env, data, dataLen); + CAResult_t result = CAEDRSendMulticastMessageImpl(env, data, dataLen); + if(CA_STATUS_OK != result) + { + OIC_LOG(ERROR, TAG, "CAEDRSendMulticastMessage - could not send multicast message"); + return result; + } OIC_LOG(DEBUG, TAG, "sent data"); @@ -738,7 +749,9 @@ CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress); if (CA_STATUS_OK != res) { - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] Send data has failed : %s", remoteAddress); + OIC_LOG_V(ERROR, TAG, "CASendMulticastMessageImpl, failed to send message to : %s", + remoteAddress); + g_edrErrorHandler(remoteAddress, OIC_EDR_SERVICE_ID, data, dataLen, res); continue; } } @@ -1074,3 +1087,8 @@ void CAEDRInitializeClient(ca_thread_pool_t handle) CAEDRInitialize(handle); OIC_LOG(DEBUG, TAG, "OUT"); } + +void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback) +{ + g_edrErrorHandler = errorHandleCallback; +} diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/caedradapter.c b/resource/csdk/connectivity/src/bt_edr_adapter/caedradapter.c index dc642f0..678af30 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/caedradapter.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/caedradapter.c @@ -83,6 +83,12 @@ static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL; static CANetworkChangeCallback g_networkChangeCallback = NULL; /** + * @var g_errorCallback + * @brief error Callback to CA adapter + */ +static CAErrorHandleCallback g_errorCallback = NULL; + +/** * @var g_localConnectivity * @brief Information of local Bluetooth adapter. */ @@ -139,10 +145,13 @@ void CAEDRFreeNetworkEvent(CAEDRNetworkEvent *event); static void CAEDRDataDestroyer(void *data, uint32_t size); +static void CAEDRErrorHandler(const char *remoteAddress, const char *serviceUUID, const void *data, + uint32_t dataLength, CAResult_t result); + CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, CANetworkPacketReceivedCallback packetReceivedCallback, CANetworkChangeCallback networkStateChangeCallback, - ca_thread_pool_t handle) + CAErrorHandleCallback errorCallback, ca_thread_pool_t handle) { OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN"); @@ -158,6 +167,7 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, g_edrThreadPool = handle; g_networkPacketReceivedCallback = packetReceivedCallback; g_networkChangeCallback = networkStateChangeCallback; + g_errorCallback = errorCallback; // Initialize EDR Network Monitor CAResult_t err = CAEDRInitializeNetworkMonitor(handle); @@ -170,6 +180,7 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, CAEDRSetNetworkChangeCallback(CAEDRNotifyNetworkStatus); CAEDRSetPacketReceivedCallback(CAAdapterRecvData); + CAEDRSetErrorHandler(CAEDRErrorHandler); CAEDRInitializeClient(handle); CAConnectivityHandler_t handler; @@ -279,6 +290,7 @@ int32_t CASendEDRUnicastData(const CAEndpoint_t *remoteEndpoint, const void *dat if (CA_STATUS_OK != err) { OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Send unicast data failed!, error num [%d]", err); + g_errorCallback(remoteEndpoint, data, dataLength, err); return -1; } @@ -305,6 +317,7 @@ int32_t CASendEDRMulticastData(const CAEndpoint_t *endpoint, const void *data, u if (CA_STATUS_OK != err) { OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Send multicast data failed!, error num [%d]", err); + g_errorCallback(endpoint, data, dataLength, err); return -1; } @@ -534,12 +547,20 @@ void CAAdapterDataSendHandler(void *context) if (NULL == message->remoteEndpoint) { OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "remoteEndpoint is not available"); + return; } else { remoteAddress = message->remoteEndpoint->addr; } + if(!remoteAddress || !serviceUUID) + { + OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDR Send Message error"); + //Error cannot be sent if remote address is NULL + return; + } + uint32_t dataSegmentLength = message->dataLen + CA_HEADER_LENGTH; uint32_t dataLen = message->dataLen; OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "checking for fragmentation and the dataLen is %d", @@ -552,6 +573,7 @@ void CAAdapterDataSendHandler(void *context) if (NULL == dataSegment) { OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Memory allocation failed"); + CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, CA_SEND_FAILED); OICFree(header); return; } @@ -562,6 +584,7 @@ void CAAdapterDataSendHandler(void *context) OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Generate header failed"); OICFree(header); OICFree(dataSegment); + CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, CA_SEND_FAILED); return ; } @@ -582,13 +605,16 @@ void CAAdapterDataSendHandler(void *context) uint32_t iter = dataSegmentLength / CA_SUPPORTED_EDR_MTU_SIZE; uint32_t index = 0; - if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID, dataSegment, length, - &sentLength)) + result = CAEDRClientSendData(remoteAddress, serviceUUID, dataSegment, length, + &sentLength); + if(CA_STATUS_OK != result) { OIC_LOG(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed"); OICFree(dataSegment); + CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, result); return; } + OICFree(dataSegment); for (index = 1; index < iter; index++) @@ -596,11 +622,13 @@ void CAAdapterDataSendHandler(void *context) // Send the remaining header. OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "Sending the chunk number [%d]", index); - if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID, - message->data + ((index * CA_SUPPORTED_EDR_MTU_SIZE) - CA_HEADER_LENGTH), - CA_SUPPORTED_EDR_MTU_SIZE, &sentLength)) + void *dataPtr = message->data + ((index * CA_SUPPORTED_EDR_MTU_SIZE) - CA_HEADER_LENGTH); + result = CAEDRClientSendData(remoteAddress, serviceUUID, + dataPtr, CA_SUPPORTED_EDR_MTU_SIZE, &sentLength); + if(CA_STATUS_OK != result) { OIC_LOG(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed"); + CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, result); return; } } @@ -610,11 +638,13 @@ void CAAdapterDataSendHandler(void *context) { // send the last segment of the data (Ex: 22 bytes of 622 bytes of data when MTU is 200) OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Sending the last chunk"); - if (CA_STATUS_OK != CAEDRClientSendData(remoteAddress, serviceUUID, - message->data + (index * CA_SUPPORTED_EDR_MTU_SIZE) - CA_HEADER_LENGTH, - remainingLen, &sentLength)) + void *dataPtr = message->data + ((index * CA_SUPPORTED_EDR_MTU_SIZE) - CA_HEADER_LENGTH); + result = CAEDRClientSendData(remoteAddress, serviceUUID, dataPtr, + remainingLen, &sentLength); + if(CA_STATUS_OK != result) { OIC_LOG(ERROR, EDR_ADAPTER_TAG, "CAEDRClientSendData API failed"); + CAEDRErrorHandler(remoteAddress, serviceUUID, message->data, message->dataLen, result); return; } } @@ -626,27 +656,32 @@ CAResult_t CAEDRClientSendData(const char *remoteAddress, const char *serviceUUI const void *data, uint32_t dataLength, uint32_t *sentLength) { + CAResult_t result = CA_SEND_FAILED; + // Send the first segment with the header. if ((NULL != remoteAddress) && (0 < strlen(remoteAddress))) //Unicast data { - if (CA_STATUS_OK != CAEDRClientSendUnicastData(remoteAddress, serviceUUID, data, - dataLength, sentLength)) + result = CAEDRClientSendUnicastData(remoteAddress, serviceUUID, data, + dataLength, sentLength); + if (CA_STATUS_OK != result) { OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send unicast data !"); - return CA_STATUS_FAILED; + return result; } } else { OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "sending multicast data : %s", data); - if (CA_STATUS_OK != CAEDRClientSendMulticastData(serviceUUID, data, dataLength, - sentLength)) + result = CAEDRClientSendMulticastData(serviceUUID, data, dataLength, + sentLength); + + if (CA_STATUS_OK != result) { OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send multicast data !"); - return CA_STATUS_FAILED; + return result; } } - return CA_STATUS_OK; + return result; } void CAAdapterDataReceiverHandler(void *context) @@ -788,6 +823,31 @@ void CAAdapterRecvData(const char *remoteAddress, const void *data, uint32_t dat OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT"); } +void CAEDRErrorHandler(const char *remoteAddress, const char *serviceUUID, const void *data, + uint32_t dataLength, CAResult_t result) +{ + OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN"); + + // Input validation + VERIFY_NON_NULL_VOID(data, EDR_ADAPTER_TAG, "Data is null"); + + // Create remote endpoint + CAEndpoint_t *remoteEndpoint = CAAdapterCreateEndpoint(0, CA_ADAPTER_RFCOMM_BTEDR, + remoteAddress, 0); + if (!remoteEndpoint) + { + OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create remote endpoint !"); + return; + } + + g_errorCallback(remoteEndpoint, data, dataLength, result); + + // Free remote endpoint + CAAdapterFreeEndpoint(remoteEndpoint); + + OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT"); +} + CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID, const void *data, uint32_t dataLength, uint32_t *sentLength) { @@ -797,7 +857,7 @@ CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID, { OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Bluetooth adapter is disabled!"); *sentLength = 0; - return CA_STATUS_OK; + return CA_ADAPTER_NOT_ENABLED; } // Input validation VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null"); @@ -809,7 +869,7 @@ CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID, if (NULL == remoteEndpoint) { OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create remote endpoint !"); - return CA_STATUS_FAILED; + return CA_MEMORY_ALLOC_FAILED; } // Add message to data queue diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c b/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c index 820e706..408c164 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c @@ -31,8 +31,9 @@ static CANetworkPacketReceivedCallback g_edrReceivedCallback = NULL; static ca_thread_pool_t g_threadPoolHandle = NULL; CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback, - ca_thread_pool_t handle) + CANetworkPacketReceivedCallback reqRespCallback, + CANetworkChangeCallback networkStateChangeCallback, + CAErrorHandleCallback errorCallback, ca_thread_pool_t handle) { OIC_LOG(DEBUG, TAG, "CAInitializeEDR"); diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrclient.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrclient.c index b489dc3..5c7ae30 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrclient.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrclient.c @@ -56,6 +56,11 @@ static EDRDeviceList *g_edrDeviceList = NULL; static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL; /** + * @var g_edrErrorHandler + * @brief Error callback to update error in EDR + */ +static CAEDRErrorHandleCallback g_edrErrorHandler = NULL; +/** * @fn CAEDRManagerInitializeMutex * @brief This function creates mutex. */ @@ -140,6 +145,11 @@ void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCall g_edrPacketReceivedCallback = packetReceivedCallback; } +void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback) +{ + g_edrErrorHandler = errorHandleCallback; +} + void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e state, bt_socket_connection_s *connection, void *userData) { diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrendpoint.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrendpoint.c index 26e7402..bcf2e89 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrendpoint.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrendpoint.c @@ -48,7 +48,7 @@ CAResult_t CAEDRSendData(int serverFD, const void *data, uint32_t dataLength, { OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "sending data failed!, soketid [%d]", serverFD); *sentDataLen = 0; - return CA_STATUS_FAILED; + return CA_SOCKET_OPERATION_FAILED; } *sentDataLen = dataLen; diff --git a/resource/csdk/connectivity/src/cainterfacecontroller.c b/resource/csdk/connectivity/src/cainterfacecontroller.c index 37645db..4f227c2 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller.c @@ -147,15 +147,18 @@ void CAInitializeAdapters(ca_thread_pool_t handle) // Initialize adapters and register callback. #ifdef IP_ADAPTER - CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle); + CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, + handle); #endif /* IP_ADAPTER */ #ifdef EDR_ADAPTER - CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle); + CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, + CAAdapterErrorHandleCallback, handle); #endif /* EDR_ADAPTER */ #ifdef LE_ADAPTER - CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle); + CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, + handle); #endif /* LE_ADAPTER */ } -- 2.7.4