CA Error handling for BT(EDR) Adapter
authorjnashok <jn.ashok@samsung.com>
Fri, 22 May 2015 07:22:14 +0000 (16:22 +0900)
committerErich Keane <erich.keane@intel.com>
Fri, 26 Jun 2015 16:02:05 +0000 (16:02 +0000)
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 <jn.ashok@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1087
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Erich Keane <erich.keane@intel.com>
resource/csdk/connectivity/inc/caedradapter.h
resource/csdk/connectivity/inc/caedrinterface.h
resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c
resource/csdk/connectivity/src/bt_edr_adapter/caedradapter.c
resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrclient.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrendpoint.c
resource/csdk/connectivity/src/cainterfacecontroller.c

index b9d7839..7e0b533 100644 (file)
@@ -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
index 7904c02..cbf26e9 100644 (file)
@@ -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
index 3d944ee..1ffa8ef 100644 (file)
@@ -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;
+}
index dc642f0..678af30 100644 (file)
@@ -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
index 820e706..408c164 100644 (file)
@@ -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");
 
index b489dc3..5c7ae30 100644 (file)
@@ -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)
 {
index 26e7402..bcf2e89 100644 (file)
@@ -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;
index 37645db..4f227c2 100644 (file)
@@ -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 */
 
 }