Merge branch 'master' into windows-port
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / caleadapter.c
index 20f0f60..302a2e8 100644 (file)
 #ifndef SINGLE_THREAD
 #include "caqueueingthread.h"
 #endif
-#include "cafragmentation.h"
+#if defined(__TIZEN__) || defined(__ANDROID__)
+#include "caleserver.h"
+#include "caleclient.h"
+#endif
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "caremotehandler.h"
+#include "pdu.h"
 
 /**
  * Logging tag for module name.
  */
-#define CALEADAPTER_TAG "OIC_LE_ADAP"
+#define CALEADAPTER_TAG "OIC_CA_LE_ADAP"
+
+/**
+ * The MTU supported for BLE adapter
+ */
+#define CA_SUPPORTED_BLE_MTU_SIZE  20
 
 /**
  * Stores information of all the senders.
@@ -64,7 +73,12 @@ typedef enum
 /**
  * Callback to provide the status of the network change to CA layer.
  */
-static CANetworkChangeCallback g_networkCallback = NULL;
+static CAAdapterChangeCallback g_networkCallback = NULL;
+
+/**
+ * Callback to provide the status of the connection change to CA layer.
+ */
+static CAConnectionChangeCallback g_connectionCallback = NULL;
 
 /**
  * bleAddress of the local adapter. Value will be initialized to zero,
@@ -140,8 +154,10 @@ static CAErrorHandleCallback g_errorHandler = NULL;
 /**
  * Register network change notification callback.
  *
- * @param[in]  netCallback CANetworkChangeCallback callback which will
- *                         be set for the change in network.
+ * @param[in]  netCallback  CAAdapterChangeCallback callback which will
+ *                          be set for the change in adapter.
+ * @param[in]  connCallback CAConnectionChangeCallback callback which will
+ *                          be set for the change in connection.
  *
  * @return  0 on success otherwise a positive error value.
  * @retval  ::CA_STATUS_OK  Successful.
@@ -149,7 +165,8 @@ static CAErrorHandleCallback g_errorHandler = NULL;
  * @retval  ::CA_STATUS_FAILED Operation failed.
  *
  */
-static CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
+static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCallback,
+                                                   CAConnectionChangeCallback connCallback);
 
 /**
  * Set the thread pool handle which is required for spawning new
@@ -162,7 +179,7 @@ static CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCa
 static void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle);
 
 /**
- * Call the callback to the upper layer when the device state gets
+ * Call the callback to the upper layer when the adapter state gets
  * changed.
  *
  * @param[in] adapter_state New state of the adapter to be notified to
@@ -171,6 +188,16 @@ static void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle);
 static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state);
 
 /**
+ * Call the callback to the upper layer when the device connection state gets
+ * changed.
+ *
+ * @param[in] address      LE address of the device to be notified to the upper layer.
+ * @param[in] isConnected  whether connection state is connected or not.
+ */
+static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const char* address,
+                                         bool isConnected);
+
+/**
  * Used to initialize all required mutex variable for LE Adapter
  * implementation.
  *
@@ -375,6 +402,28 @@ static void CAFreeLEData(CALEData_t *bleData);
  */
 static void CALEDataDestroyer(void *data, uint32_t size);
 
+#ifndef SINGLE_THREAD
+/**
+ * remove request or response data of send queue.
+ *
+ * @param[in] queueHandle    queue to process the outgoing packets.
+ * @param[in] mutex          mutex related to sender for client / server.
+ * @param[in] address        target address to remove data in queue.
+ */
+static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle,
+                                    ca_mutex mutex,
+                                    const char* address);
+
+/**
+ * remove all received data of data list from receive queue.
+ *
+ * @param[in] dataInfoList   received data list to remove for client / server.
+ * @param[in] address        target address to remove data in queue.
+ */
+static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList,
+                                       const char* address);
+#endif
+
 static CAResult_t CAInitLEServerQueues()
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
@@ -713,8 +762,9 @@ static void CALEDataReceiverHandler(void *threadData)
             newSender->remoteEndpoint = NULL;
 
             OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header");
-            newSender->totalDataLen = CAParseHeader(bleData->data,
-                                                    bleData->dataLen);
+
+            newSender->totalDataLen = coap_get_total_message_length(bleData->data, bleData->dataLen);
+
             if(!(newSender->totalDataLen))
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "Total Data Length is parsed as 0!!!");
@@ -752,10 +802,20 @@ static void CALEDataReceiverHandler(void *threadData)
                 ca_mutex_unlock(g_bleReceiveDataMutex);
                 return;
             }
-            memcpy(newSender->defragData, bleData->data + CA_HEADER_LENGTH,
-                   bleData->dataLen - CA_HEADER_LENGTH);
-            newSender->recvDataLen += bleData->dataLen - CA_HEADER_LENGTH;
-            u_arraylist_add(bleData->senderInfo, (void *)newSender);
+
+            if (newSender->recvDataLen + bleData->dataLen > newSender->totalDataLen)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "buffer is smaller than received data");
+                OICFree(newSender->defragData);
+                CAFreeEndpoint(newSender->remoteEndpoint);
+                OICFree(newSender);
+                ca_mutex_unlock(g_bleReceiveDataMutex);
+                return;
+            }
+            memcpy(newSender->defragData, bleData->data, bleData->dataLen);
+            newSender->recvDataLen += bleData->dataLen;
+
+            u_arraylist_add(bleData->senderInfo,(void *)newSender);
 
             //Getting newSender index position in bleSenderInfo array list
             if(CA_STATUS_OK !=
@@ -840,10 +900,7 @@ static void CALEServerSendDataThread(void *threadData)
         return;
     }
 
-    uint8_t * const header = OICCalloc(CA_HEADER_LENGTH, 1);
-    VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed");
-
-    const uint32_t totalLength = bleData->dataLen + CA_HEADER_LENGTH;
+    const uint32_t totalLength = bleData->dataLen;
 
     OIC_LOG_V(DEBUG,
               CALEADAPTER_TAG,
@@ -855,39 +912,24 @@ static void CALEServerSendDataThread(void *threadData)
     if (NULL == dataSegment)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
-        OICFree(header);
         return;
     }
 
-    CAResult_t result = CAGenerateHeader(header,
-                                         CA_HEADER_LENGTH,
-                                         bleData->dataLen);
-    if (CA_STATUS_OK != result )
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
-        OICFree(header);
-        OICFree(dataSegment);
-        return;
-    }
-
-    memcpy(dataSegment, header, CA_HEADER_LENGTH);
-    OICFree(header);
-
     uint32_t length = 0;
     if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
     {
         length = totalLength;
-        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen);
+        memcpy(dataSegment, bleData->data, bleData->dataLen);
     }
     else
     {
         length =  CA_SUPPORTED_BLE_MTU_SIZE;
-        memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data,
-               CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
+        memcpy(dataSegment, bleData->data, CA_SUPPORTED_BLE_MTU_SIZE);
     }
 
     uint32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE;
     uint32_t index = 0;
+    CAResult_t result = CA_STATUS_FAILED;
 
     // Send the first segment with the header.
     if (NULL != bleData->remoteEndpoint) // Sending Unicast Data
@@ -927,8 +969,9 @@ static void CALEServerSendDataThread(void *threadData)
             result =
                 CAUpdateCharacteristicsToGattClient(
                     bleData->remoteEndpoint->addr,
-                    bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH),
+                    bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE)),
                     CA_SUPPORTED_BLE_MTU_SIZE);
+
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR, CALEADAPTER_TAG,
@@ -949,10 +992,12 @@ static void CALEServerSendDataThread(void *threadData)
             // send the last segment of the data (Ex: 22 bytes of 622
             // bytes of data when MTU is 200)
             OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+
             result = CAUpdateCharacteristicsToGattClient(
                          bleData->remoteEndpoint->addr,
-                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
                          remainingLen);
+
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR,
@@ -986,9 +1031,11 @@ static void CALEServerSendDataThread(void *threadData)
         {
             // Send the remaining header.
             OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index);
+
             result = CAUpdateCharacteristicsToAllGattClients(
-                         bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH),
+                         bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE)),
                          CA_SUPPORTED_BLE_MTU_SIZE);
+
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
@@ -1006,9 +1053,11 @@ static void CALEServerSendDataThread(void *threadData)
         {
             // send the last segment of the data
             OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+
             result = CAUpdateCharacteristicsToAllGattClients(
-                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
                          remainingLen);
+
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
@@ -1036,47 +1085,32 @@ static void CALEClientSendDataThread(void *threadData)
         return;
     }
 
-    uint8_t * const header = OICCalloc(CA_HEADER_LENGTH, 1);
-    VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed");
+    const uint32_t totalLength = bleData->dataLen;
 
-    const uint32_t totalLength = bleData->dataLen + CA_HEADER_LENGTH;
     uint8_t *dataSegment = OICCalloc(totalLength, 1);
     if (NULL == dataSegment)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
-        OICFree(header);
         return;
     }
 
-    CAResult_t result = CAGenerateHeader(header,
-                                         CA_HEADER_LENGTH,
-                                         bleData->dataLen);
-    if (CA_STATUS_OK != result )
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
-        OICFree(header);
-        OICFree(dataSegment);
-        return ;
-    }
-    memcpy(dataSegment, header, CA_HEADER_LENGTH);
-    OICFree(header);
-
     uint32_t length = 0;
     if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
     {
         length = totalLength;
-        memcpy(dataSegment + CA_HEADER_LENGTH,
+        memcpy(dataSegment,
                bleData->data,
                bleData->dataLen);
     }
     else
     {
         length = CA_SUPPORTED_BLE_MTU_SIZE;
-        memcpy(dataSegment + CA_HEADER_LENGTH,
+        memcpy(dataSegment,
                bleData->data,
-               CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
+               CA_SUPPORTED_BLE_MTU_SIZE);
     }
 
+    CAResult_t result = CA_STATUS_FAILED;
     const uint32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE;
     uint32_t index = 0;
     if (NULL != bleData->remoteEndpoint) //Sending Unicast Data
@@ -1115,9 +1149,10 @@ static void CALEClientSendDataThread(void *threadData)
             // Send the remaining header.
             result = CAUpdateCharacteristicsToGattServer(
                      bleData->remoteEndpoint->addr,
-                     bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                     bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
                      CA_SUPPORTED_BLE_MTU_SIZE,
                      LE_UNICAST, 0);
+
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR,
@@ -1138,9 +1173,10 @@ static void CALEClientSendDataThread(void *threadData)
             // send the last segment of the data (Ex: 22 bytes of 622
             // bytes of data when MTU is 200)
             OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+
             result = CAUpdateCharacteristicsToGattServer(
                      bleData->remoteEndpoint->addr,
-                     bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                     bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
                      remainingLen,
                      LE_UNICAST, 0);
 
@@ -1174,8 +1210,9 @@ static void CALEClientSendDataThread(void *threadData)
         for (index = 1; index < iter; index++)
         {
             result = CAUpdateCharacteristicsToAllGattServers(
-                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                         bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
                          CA_SUPPORTED_BLE_MTU_SIZE);
+
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
@@ -1196,8 +1233,9 @@ static void CALEClientSendDataThread(void *threadData)
             OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
             result =
                 CAUpdateCharacteristicsToAllGattServers(
-                    bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+                    bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
                     remainingLen);
+
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR, CALEADAPTER_TAG,
@@ -1510,7 +1548,7 @@ static void CATerminateLE();
  *
  * @param[in] remoteAddress Remote address of the device from where
  *                          data is received.
- * @param[in] data          Actual data recevied from the remote
+ * @param[in] data          Actual data received from the remote
  *                          device.
  * @param[in] dataLength    Length of the data received from the
  *                          remote device.
@@ -1626,13 +1664,15 @@ static CAResult_t CALEAdapterGattServerStart()
 static CAResult_t CALEAdapterGattServerStop()
 {
 #ifndef SINGLE_THREAD
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEAdapterGattServerStop");
+
+    CAResult_t result = CAStopLEGattServer();
     ca_mutex_lock(g_bleServerSendDataMutex);
-    CAResult_t result = CAQueueingThreadStop(g_bleServerSendQueueHandle);
-    ca_mutex_unlock(g_bleServerSendDataMutex);
     if (CA_STATUS_OK == result)
     {
-        result = CAStopLEGattServer();
+        result = CAQueueingThreadStop(g_bleServerSendQueueHandle);
     }
+    ca_mutex_unlock(g_bleServerSendDataMutex);
 
     return result;
 #else
@@ -1672,13 +1712,12 @@ static CAResult_t CALEAdapterGattClientStart()
 static CAResult_t CALEAdapterGattClientStop()
 {
 #ifndef SINGLE_THREAD
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEAdapterGattClientStop");
+    CAStopLEGattClient();
+
     ca_mutex_lock(g_bleClientSendDataMutex);
     CAResult_t result = CAQueueingThreadStop(g_bleClientSendQueueHandle);
     ca_mutex_unlock(g_bleClientSendDataMutex);
-    if (CA_STATUS_OK == result)
-    {
-        CAStopLEGattClient();
-    }
 
     return result;
 #else
@@ -1690,7 +1729,8 @@ static CAResult_t CALEAdapterGattClientStop()
 
 CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
                           CANetworkPacketReceivedCallback reqRespCallback,
-                          CANetworkChangeCallback netCallback,
+                          CAAdapterChangeCallback netCallback,
+                          CAConnectionChangeCallback connCallback,
                           CAErrorHandleCallback errorCallback,
                           ca_thread_pool_t handle)
 {
@@ -1700,6 +1740,7 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
     VERIFY_NON_NULL(registerCallback, CALEADAPTER_TAG, "RegisterConnectivity callback is null");
     VERIFY_NON_NULL(reqRespCallback, CALEADAPTER_TAG, "PacketReceived Callback is null");
     VERIFY_NON_NULL(netCallback, CALEADAPTER_TAG, "NetworkChange Callback is null");
+    VERIFY_NON_NULL(connCallback, CALEADAPTER_TAG, "ConnectionChange Callback is null");
 
     CAResult_t result = CA_STATUS_OK;
     result = CAInitLEAdapterMutex();
@@ -1715,7 +1756,7 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitializeLENetworkMonitor() failed");
         return CA_STATUS_FAILED;
     }
-    CAInitializeLEAdapter(handle);
+    CAInitializeLEAdapter();
 
     CASetLEClientThreadPoolHandle(handle);
 
@@ -1741,7 +1782,7 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
 
     CASetBLEClientErrorHandleCallback(CALEErrorHandler);
     CASetBLEServerErrorHandleCallback(CALEErrorHandler);
-    CALERegisterNetworkNotifications(netCallback);
+    CALERegisterNetworkNotifications(netCallback, connCallback);
 
     g_errorHandler = errorCallback;
 
@@ -1756,10 +1797,11 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
             .sendDataToAll = CASendLEMulticastData,
             .GetnetInfo = CAGetLEInterfaceInformation,
             .readData = CAReadLEData,
-            .terminate = CATerminateLE
+            .terminate = CATerminateLE,
+            .cType = CA_ADAPTER_GATT_BTLE
         };
 
-    registerCallback(connHandler, CA_ADAPTER_GATT_BTLE);
+    registerCallback(connHandler);
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
 
@@ -1809,7 +1851,7 @@ static void CATerminateLE()
 
     CASetLEReqRespServerCallback(NULL);
     CASetLEReqRespClientCallback(NULL);
-    CALERegisterNetworkNotifications(NULL);
+    CALERegisterNetworkNotifications(NULL, NULL);
     CASetLEReqRespAdapterCallback(NULL);
     CATerminateLENetworkMonitor();
 
@@ -1875,6 +1917,7 @@ static CAResult_t CAStartLEListeningServer()
             OIC_LOG(DEBUG,
                     CALEADAPTER_TAG,
                     "Listen Server will be started once BT Adapter is enabled");
+            result = CA_STATUS_OK;
         }
     }
     else
@@ -1931,6 +1974,7 @@ static CAResult_t CAStartLEDiscoveryServer()
             OIC_LOG(DEBUG,
                     CALEADAPTER_TAG,
                     "Discovery Server will be started once BT Adapter is enabled");
+            result = CA_STATUS_OK;
         }
     }
     else
@@ -2125,12 +2169,14 @@ static CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *siz
     return CA_STATUS_OK;
 }
 
-static CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
+static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCallback,
+                                                   CAConnectionChangeCallback connCallback)
 {
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 
     ca_mutex_lock(g_bleNetworkCbMutex);
     g_networkCallback = netCallback;
+    g_connectionCallback = connCallback;
     ca_mutex_unlock(g_bleNetworkCbMutex);
     CAResult_t res = CA_STATUS_OK;
     if (netCallback)
@@ -2150,22 +2196,93 @@ static CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCa
         }
     }
 
+    if (g_connectionCallback)
+    {
+        res = CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCb);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLENWConnectionStateChangedCb failed!");
+        }
+    }
+
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return res;
 }
 
-static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state)
+static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const char* address,
+                                         bool isConnected)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEDeviceStateChangedCb");
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEConnectionStateChangedCb");
+
+    VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address");
+    (void)adapter;
+
+#ifdef __TIZEN__
+    ca_mutex_lock(g_bleIsServerMutex);
+    switch (g_adapterType)
+    {
+        case ADAPTER_SERVER:
+            CALEGattServerConnectionStateChanged(isConnected, address);
+            break;
+        case ADAPTER_CLIENT:
+            CALEGattConnectionStateChanged(isConnected, address);
+            break;
+        case ADAPTER_BOTH_CLIENT_SERVER:
+            CALEGattConnectionStateChanged(isConnected, address);
+            CALEGattServerConnectionStateChanged(isConnected, address);
+            break;
+        default:
+            break;
+    }
+    ca_mutex_unlock(g_bleIsServerMutex);
+#endif
+
+    if(!isConnected)
+    {
+#ifndef SINGLE_THREAD
+        if(g_bleClientSenderInfo)
+        {
+            CALERemoveReceiveQueueData(g_bleClientSenderInfo, address);
+        }
+
+        if(g_bleServerSenderInfo)
+        {
+            CALERemoveReceiveQueueData(g_bleServerSenderInfo, address);
+        }
+
+        // remove data of send queue.
+        if (g_bleClientSendQueueHandle)
+        {
+            CALERemoveSendQueueData(g_bleClientSendQueueHandle,
+                                    g_bleClientSendDataMutex,
+                                    address);
+        }
+
+        if (g_bleServerSendQueueHandle)
+        {
+            CALERemoveSendQueueData(g_bleServerSendQueueHandle,
+                                    g_bleServerSendDataMutex,
+                                    address);
+        }
+#endif
+    }
 
-    VERIFY_NON_NULL_VOID(g_localBLEAddress, CALEADAPTER_TAG, "g_localBLEAddress is null");
     CAEndpoint_t localEndpoint = { .adapter = CA_ADAPTER_GATT_BTLE };
+    OICStrcpy(localEndpoint.addr, sizeof(localEndpoint.addr), address);
 
-    ca_mutex_lock(g_bleLocalAddressMutex);
-    OICStrcpy(localEndpoint.addr,
-              sizeof(localEndpoint.addr),
-              g_localBLEAddress);
-    ca_mutex_unlock(g_bleLocalAddressMutex);
+    ca_mutex_lock(g_bleNetworkCbMutex);
+    if (g_connectionCallback)
+    {
+        g_connectionCallback(&localEndpoint, isConnected);
+    }
+    ca_mutex_unlock(g_bleNetworkCbMutex);
+
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+}
+
+static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state)
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEDeviceStateChangedCb");
 
     if (CA_ADAPTER_ENABLED == adapter_state)
     {
@@ -2211,7 +2328,7 @@ static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state)
     ca_mutex_lock(g_bleNetworkCbMutex);
     if (NULL != g_networkCallback)
     {
-        g_networkCallback(&localEndpoint, adapter_state);
+        g_networkCallback(CA_ADAPTER_GATT_BTLE, adapter_state);
     }
     else
     {
@@ -2267,30 +2384,13 @@ static CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint,
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
 
 #ifdef SINGLE_THREAD
-    uint8_t header[CA_HEADER_LENGTH] = { 0 };
-
-    CAResult_t result =
-        CAGenerateHeader(header, CA_HEADER_LENGTH, dataLen);
-
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
-        return CA_STATUS_FAILED;
-    }
-
     if (!CAIsLEConnected())
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "le not conn");
         return CA_STATUS_FAILED;
     }
 
-    result = CAUpdateCharacteristicsToAllGattClients(header, CA_HEADER_LENGTH);
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed");
-        return CA_STATUS_FAILED;
-    }
-
+    CAResult_t result = CA_STATUS_OK;
     const uint32_t dataLimit = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
     for (uint32_t iter = 0; iter < dataLimit; iter++)
     {
@@ -2513,3 +2613,69 @@ static void CALEErrorHandler(const char *remoteAddress,
 
     OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEErrorHandler OUT");
 }
+
+#ifndef SINGLE_THREAD
+static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, ca_mutex mutex,
+                                    const char* address)
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALERemoveSendQueueData");
+
+    VERIFY_NON_NULL_VOID(queueHandle, CALEADAPTER_TAG, "queueHandle");
+    VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address");
+
+    ca_mutex_lock(mutex);
+    while (u_queue_get_size(queueHandle->dataQueue) > 0)
+    {
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "get data from queue");
+        u_queue_message_t *message = u_queue_get_element(queueHandle->dataQueue);
+        if (NULL != message)
+        {
+            CALEData_t *bleData = (CALEData_t *) message->msg;
+            if (bleData && bleData->remoteEndpoint)
+            {
+                if (!strcmp(bleData->remoteEndpoint->addr, address))
+                {
+                    OIC_LOG(DEBUG, CALEADAPTER_TAG, "found the message of disconnected device");
+                    if (NULL != queueHandle->destroy)
+                    {
+                        queueHandle->destroy(message->msg, message->size);
+                    }
+                    else
+                    {
+                        OICFree(message->msg);
+                    }
+
+                    OICFree(message);
+                }
+            }
+        }
+    }
+    ca_mutex_unlock(mutex);
+}
+
+static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList, const char* address)
+{
+    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALERemoveReceiveQueueData");
+
+    VERIFY_NON_NULL_VOID(dataInfoList, CALEADAPTER_TAG, "dataInfoList");
+    VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address");
+
+    CABLESenderInfo_t *senderInfo = NULL;
+    uint32_t senderIndex = 0;
+
+    if(CA_STATUS_OK == CALEGetSenderInfo(address, dataInfoList, &senderInfo,
+                                         &senderIndex))
+    {
+        u_arraylist_remove(dataInfoList, senderIndex);
+        OICFree(senderInfo->defragData);
+        OICFree(senderInfo->remoteEndpoint);
+        OICFree(senderInfo);
+
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "SenderInfo is removed for disconnection");
+    }
+    else
+    {
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "SenderInfo doesn't exist");
+    }
+}
+#endif