replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_edr_adapter / tizen / caedrclient.c
index 5c7ae30..0173190 100644 (file)
 
 #include <string.h>
 #include <bluetooth.h>
+#include <bluetooth_internal.h>
 
 #include "caedrinterface.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "caedrendpoint.h"
 #include "caadapterutils.h"
 #include "caedrutils.h"
 #include "cacommon.h"
 #include "caedrdevicelist.h"
 
+#define MICROSECS_PER_SEC 1000000
+
+/**
+ * Maximum CoAP over TCP header length
+ * to know the total data length.
+ */
+#define EDR_MAX_HEADER_LEN  6
+
 /**
- * @var g_edrDeviceListMutex
- * @brief Mutex to synchronize the access to Bluetooth device information list.
+ * Mutex to synchronize the access to Bluetooth device information list.
  */
-static ca_mutex g_edrDeviceListMutex = NULL;
+static oc_mutex g_edrDeviceListMutex = NULL;
 
 /**
- * @var g_edrDeviceList
- * @brief Peer Bluetooth device information list.
+ * Peer Bluetooth device information list.
  */
 static EDRDeviceList *g_edrDeviceList = NULL;
 
 /**
- * @var gEDRNetworkChangeCallback
- * @brief Maintains the callback to be notified when data received from remote Bluetooth device
+ * Maintains the callback to be notified when data received from remote
+ * Bluetooth device.
  */
 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
 
 /**
- * @var g_edrErrorHandler
- * @brief Error callback to update error in EDR
+ * Error callback to update error in EDR.
  */
 static CAEDRErrorHandleCallback g_edrErrorHandler = NULL;
+
 /**
- * @fn CAEDRManagerInitializeMutex
- * @brief This function creates mutex.
+ * Pending multicast data list to be sent.
  */
-static void CAEDRManagerInitializeMutex(void);
+static u_arraylist_t *g_multicastDataList = NULL;
 
 /**
- * @fn CAEDRManagerTerminateMutex
- * @brief This function frees mutex.
+ * Mutex to synchronize the access to Pending multicast data list.
  */
-static void CAEDRManagerTerminateMutex(void);
+static oc_mutex g_multicastDataListMutex = NULL;
 
 /**
- * @fn CAEDRDataRecvCallback
- * @brief This callback is registered to recieve data on any open RFCOMM connection.
+ * To Store Adapter Mode information
  */
-static void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData);
+static bool g_isDiscoveryServer = false;
 
 /**
- * @brief This function starts device discovery.
- * @return NONE
+ * This function creates mutex.
  */
-static CAResult_t CAEDRStartDeviceDiscovery(void);
+static CAResult_t CAEDRManagerInitializeMutex(void);
 
 /**
- * @fn CAEDRStopServiceSearch
- * @brief This function stops any ongoing service sevice search.
+ * This function frees mutex.
+ */
+static void CAEDRManagerTerminateMutex(void);
+
+/**
+ * This callback is registered to recieve data on any open RFCOMM connection.
+ */
+static void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData);
+
+/**
+ * This function stops any ongoing service sevice search.
  */
 static CAResult_t CAEDRStopServiceSearch(void);
 
 /**
- * @fn CAEDRStopDeviceDiscovery
- * @brief This function stops device discovery.
+ * This function stops device discovery.
  */
 static CAResult_t CAEDRStopDeviceDiscovery(void);
 
 /**
- * @fn CAEDRStartServiceSearch
- * @brief This function searches for OIC service for remote Bluetooth device.
+ * This function searches for OIC service for remote Bluetooth device.
  */
 static CAResult_t CAEDRStartServiceSearch(const char *remoteAddress);
 
 /**
- * @fn CAEDRDeviceDiscoveryCallback
- * @brief This callback is registered to recieve all bluetooth nearby devices when device
- *           scan is initiated.
+ * This callback is registered to recieve all bluetooth nearby devices
+ * when device scan is initiated.
  */
 static void CAEDRDeviceDiscoveryCallback(int result,
                                          bt_adapter_device_discovery_state_e state,
@@ -113,30 +122,27 @@ static void CAEDRDeviceDiscoveryCallback(int result,
                                          void *userData);
 
 /**
- * @fn CAEDRServiceSearchedCallback
- * @brief This callback is registered to recieve all the services remote bluetooth device supports
- *           when service search initiated.
+ * This callback is registered to recieve all the services remote
+ * bluetooth device supports when service search initiated.
  */
 static void CAEDRServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo,
                                         void *userData);
 
 /**
- * @fn CAEDRSocketConnectionStateCallback
- * @brief This callback is registered to receive bluetooth RFCOMM connection state changes.
+ * This callback is registered to receive bluetooth RFCOMM connection
+ * state changes.
  */
 static void CAEDRSocketConnectionStateCallback(int result,
                                     bt_socket_connection_state_e state,
                                               bt_socket_connection_s *connection, void *userData);
 
 /**
- * @fn CAEDRClientConnect
- * @brief Establishes RFCOMM connection with remote bluetooth device
+ * Establishes RFCOMM connection with remote bluetooth device.
  */
 static CAResult_t CAEDRClientConnect(const char *remoteAddress, const char *serviceUUID);
 
 /**
- * @fn CAEDRClientDisconnect
- * @brief  Disconnect RFCOMM client socket connection
+ * Disconnect RFCOMM client socket connection.
  */
 static CAResult_t CAEDRClientDisconnect(const int32_t clientID);
 
@@ -168,7 +174,7 @@ void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e
     {
         case BT_SOCKET_CONNECTED:
             {
-                ca_mutex_lock(g_edrDeviceListMutex);
+                oc_mutex_lock(g_edrDeviceListMutex);
                 CAResult_t res = CAGetEDRDevice(g_edrDeviceList, connection->remote_address,
                                                    &device);
                 if (CA_STATUS_OK != res)
@@ -179,35 +185,34 @@ void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e
                     if (CA_STATUS_OK != res)
                     {
                         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed add device to list ret[%d]", res);
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
                     if(!device)
                     {
                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
                     device->socketFD = connection->socket_fd;
-                    ca_mutex_unlock(g_edrDeviceListMutex);
+                    oc_mutex_unlock(g_edrDeviceListMutex);
                     return;
                 }
 
                 if(!device)
                 {
                     OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
-                    ca_mutex_unlock(g_edrDeviceListMutex);
+                    oc_mutex_unlock(g_edrDeviceListMutex);
                     return;
                 }
                 device->socketFD = connection->socket_fd;
                 while (device->pendingDataList)
                 {
-                    uint32_t sentData = 0;
                     EDRData *edrData = device->pendingDataList->data;
-                    res = CAEDRSendData(device->socketFD, edrData->data,
-                                                     edrData->dataLength, &sentData);
+                    res = CAEDRSendData(device->socketFD, device->remoteAddress,
+                                        edrData->data, edrData->dataLength);
                     if (CA_STATUS_OK != res)
                     {
                         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send pending data [%s]",
@@ -221,17 +226,20 @@ void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e
                     // Remove the data which send from pending list
                     CARemoveEDRDataFromList(&device->pendingDataList);
                 }
-                ca_mutex_unlock(g_edrDeviceListMutex);
+                oc_mutex_unlock(g_edrDeviceListMutex);
             }
             break;
 
         case BT_SOCKET_DISCONNECTED:
             {
-                ca_mutex_lock(g_edrDeviceListMutex);
+                oc_mutex_lock(g_edrDeviceListMutex);
                 CARemoveEDRDeviceFromList(&g_edrDeviceList, connection->remote_address);
-                ca_mutex_unlock(g_edrDeviceListMutex);
+                oc_mutex_unlock(g_edrDeviceListMutex);
             }
             break;
+
+        default:
+            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Unknown Bluetooth Socket connection state");
     }
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
@@ -263,6 +271,10 @@ void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_
         case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
             {
                 OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Discovery finished!");
+                oc_mutex_lock(g_multicastDataListMutex);
+                u_arraylist_destroy(g_multicastDataList);
+                g_multicastDataList = NULL;
+                oc_mutex_unlock(g_multicastDataListMutex);
             }
             break;
 
@@ -275,18 +287,18 @@ void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_
                                                         OIC_EDR_SERVICE_ID))
                 {
                     // Check if the deivce is already in the list
-                    ca_mutex_lock(g_edrDeviceListMutex);
+                    oc_mutex_lock(g_edrDeviceListMutex);
                     if (CA_STATUS_OK == CAGetEDRDevice(g_edrDeviceList,
                                                 discoveryInfo->remote_address, &device))
                     {
                         if(!device)
                         {
                             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
-                            ca_mutex_unlock(g_edrDeviceListMutex);
+                            oc_mutex_unlock(g_edrDeviceListMutex);
                             return;
                         }
                         device->serviceSearched = true;
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
@@ -296,25 +308,61 @@ void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_
                     if (CA_STATUS_OK != res)
                     {
                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add device to list!");
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
                     if(!device)
                     {
                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
+
+                    int lengthData = u_arraylist_length(g_multicastDataList);
+                    for(int len = 0; len < lengthData; len++)
+                    {
+                        // Adding to pending list
+                        EDRData *multicastData =
+                            (EDRData *)u_arraylist_get(g_multicastDataList, len);
+                        if (NULL == multicastData)
+                        {
+                            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "multicastData is NULL");
+                            continue;
+                        }
+                        result = CAAddEDRDataToList(&device->pendingDataList, multicastData->data,
+                                                    multicastData->dataLength);
+                        if (CA_STATUS_OK != result)
+                        {
+                            OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
+                                      "Failed to add data to pending list[%d]", result);
+                            continue;
+                        }
+                    }
+                    if (lengthData)
+                    {
+                        result = CAEDRClientConnect(device->remoteAddress, device->serviceUUID);
+                        if (CA_STATUS_OK != result)
+                        {
+                            OIC_LOG_V(ERROR, EDR_ADAPTER_TAG,
+                                      "Failed to make RFCOMM connection[%d]", result);
+
+                            //Remove the data which added to pending list
+                            CARemoveEDRDataFromList(&device->pendingDataList);
+                        }
+                    }
                     device->serviceSearched = true;
-                    ca_mutex_unlock(g_edrDeviceListMutex);
+                    oc_mutex_unlock(g_edrDeviceListMutex);
                 }
                 else
                 {
-                    OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Device does not support OIC service!");
+                    OIC_LOG(INFO, EDR_ADAPTER_TAG, "Device does not support OIC service!");
                 }
             }
             break;
+
+        default:
+            OIC_LOG(INFO, EDR_ADAPTER_TAG, "Unknown Bluetooth Adapter device discovery state");
     }
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
@@ -331,7 +379,7 @@ void CAEDRServiceSearchedCallback(int32_t result,
         return;
     }
 
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
 
     EDRDevice *device = NULL;
     CAResult_t res = CAGetEDRDevice(g_edrDeviceList, sdpInfo->remote_address, &device);
@@ -340,7 +388,7 @@ void CAEDRServiceSearchedCallback(int32_t result,
         if (device->serviceSearched)
         {
             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Service is already searched for this device!");
-            ca_mutex_unlock(g_edrDeviceListMutex);
+            oc_mutex_unlock(g_edrDeviceListMutex);
             return;
         }
 
@@ -366,7 +414,7 @@ void CAEDRServiceSearchedCallback(int32_t result,
         }
     }
 
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
@@ -375,7 +423,6 @@ CAResult_t CAEDRStartDeviceDiscovery(void)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
-
     bool isDiscoveryStarted = false;
 
     // Check the device discovery state
@@ -399,6 +446,8 @@ CAResult_t CAEDRStartDeviceDiscovery(void)
         }
     }
 
+    g_isDiscoveryServer = true;
+
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -484,14 +533,6 @@ CAResult_t CAEDRClientSetCallbacks(void)
     bt_socket_set_connection_state_changed_cb(CAEDRSocketConnectionStateCallback, NULL);
     bt_socket_set_data_received_cb(CAEDRDataRecvCallback, NULL);
 
-    // Start device discovery
-    CAResult_t result = CAEDRStartDeviceDiscovery();
-    if(CA_STATUS_OK != result)
-    {
-        OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Failed to Start Device discovery");
-        return CA_STATUS_FAILED;
-    }
-
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -517,16 +558,29 @@ void CAEDRClientUnsetCallbacks(void)
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
 
-void CAEDRManagerInitializeMutex(void)
+CAResult_t CAEDRManagerInitializeMutex(void)
 {
+    CAResult_t result = CA_STATUS_OK;
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
     if (!g_edrDeviceListMutex)
     {
-        g_edrDeviceListMutex = ca_mutex_new();
+        g_edrDeviceListMutex = oc_mutex_new();
+    }
+
+    if (!g_multicastDataListMutex)
+    {
+        g_multicastDataListMutex = oc_mutex_new();
+    }
+
+    if (!g_edrDeviceListMutex || !g_multicastDataListMutex)
+    {
+        result = CA_STATUS_NOT_INITIALIZED;
     }
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
+
+    return result;
 }
 
 void CAEDRManagerTerminateMutex(void)
@@ -535,18 +589,25 @@ void CAEDRManagerTerminateMutex(void)
 
     if (g_edrDeviceListMutex)
     {
-        ca_mutex_free(g_edrDeviceListMutex);
+        oc_mutex_free(g_edrDeviceListMutex);
         g_edrDeviceListMutex = NULL;
     }
 
+    if (g_multicastDataListMutex)
+    {
+        oc_mutex_free(g_multicastDataListMutex);
+        g_multicastDataListMutex = NULL;
+    }
+
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
 
-void CAEDRInitializeClient(ca_thread_pool_t handle)
+CAResult_t CAEDRClientInitialize()
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
-    CAEDRManagerInitializeMutex();
+    CAResult_t result = CAEDRManagerInitializeMutex();
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
+    return result;
 }
 
 void CAEDRClientTerminate()
@@ -556,9 +617,17 @@ void CAEDRClientTerminate()
     // Free EDRDevices list
     if (g_edrDeviceListMutex)
     {
-        ca_mutex_lock(g_edrDeviceListMutex);
+        oc_mutex_lock(g_edrDeviceListMutex);
         CADestroyEDRDeviceList(&g_edrDeviceList);
-        ca_mutex_unlock(g_edrDeviceListMutex);
+        oc_mutex_unlock(g_edrDeviceListMutex);
+    }
+
+    if (g_multicastDataListMutex)
+    {
+        oc_mutex_lock(g_multicastDataListMutex);
+        u_arraylist_destroy(g_multicastDataList);
+        g_multicastDataList = NULL;
+        oc_mutex_unlock(g_multicastDataListMutex);
     }
 
     // Free the mutex
@@ -570,7 +639,7 @@ void CAEDRClientDisconnectAll(void)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
 
     EDRDeviceList *cur = g_edrDeviceList;
     while (cur != NULL)
@@ -591,14 +660,15 @@ void CAEDRClientDisconnectAll(void)
         }
     }
 
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
 
 
-CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
-                                      const void *data, uint32_t dataLength, uint32_t *sentLength)
+CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress,
+                                      const uint8_t *data,
+                                      uint32_t dataLength)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
@@ -606,9 +676,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
 
     // Input validation
     VERIFY_NON_NULL(remoteAddress, EDR_ADAPTER_TAG, "Remote address is null");
-    VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
-    VERIFY_NON_NULL(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
 
     if (0 >= dataLength)
     {
@@ -617,7 +685,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
     }
 
     // Check the connection existence with remote device
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
     CAResult_t result = CAGetEDRDevice(g_edrDeviceList, remoteAddress, &device);
     if (CA_STATUS_OK != result)
     {
@@ -628,7 +696,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed create device and add to list!");
 
-            ca_mutex_unlock(g_edrDeviceListMutex);
+            oc_mutex_unlock(g_edrDeviceListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -641,7 +709,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
             // Remove device from list
             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
 
-            ca_mutex_unlock(g_edrDeviceListMutex);
+            oc_mutex_unlock(g_edrDeviceListMutex);
             return CA_STATUS_FAILED;
         }
     }
@@ -652,11 +720,11 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
         // Remove device from list
         CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
 
-        ca_mutex_unlock(g_edrDeviceListMutex);
+        oc_mutex_unlock(g_edrDeviceListMutex);
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
     if (-1 == device->socketFD)
     {
@@ -674,7 +742,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
 
         // Make a rfcomm connection with remote BT Device
         if (device->serviceSearched &&
-            CA_STATUS_OK != CAEDRClientConnect(remoteAddress, serviceUUID))
+            CA_STATUS_OK != CAEDRClientConnect(remoteAddress, OIC_EDR_SERVICE_ID))
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to make RFCOMM connection!");
 
@@ -682,11 +750,10 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
             return CA_STATUS_FAILED;
         }
-        *sentLength = dataLength;
     }
     else
     {
-        result = CAEDRSendData(device->socketFD, data, dataLength, sentLength);
+        result = CAEDRSendData(device->socketFD, device->remoteAddress, data, dataLength);
         if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send data!");
@@ -698,15 +765,13 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *ser
     return CA_STATUS_OK;
 }
 
-CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data,
-                                        uint32_t dataLength, uint32_t *sentLength)
+CAResult_t CAEDRClientSendMulticastData(const uint8_t *data,
+                                        uint32_t dataLength)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
     // Input validation
-    VERIFY_NON_NULL(serviceUUID, EDR_ADAPTER_TAG, "service UUID is null");
     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
-    VERIFY_NON_NULL(sentLength, EDR_ADAPTER_TAG, "Sent data length holder is null");
 
     if (0 >= dataLength)
     {
@@ -714,10 +779,9 @@ CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *dat
         return CA_STATUS_INVALID_PARAM;
     }
 
-    *sentLength = dataLength;
-
     // Send the packet to all OIC devices
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
+
     EDRDeviceList *curList = g_edrDeviceList;
     CAResult_t result = CA_STATUS_FAILED;
     while (curList != NULL)
@@ -733,7 +797,6 @@ CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *dat
 
         if (-1 == device->socketFD)
         {
-            OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN1");
             // Check if the device service search is finished
             if (false == device->serviceSearched)
             {
@@ -760,22 +823,55 @@ CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *dat
                 CARemoveEDRDataFromList(&device->pendingDataList);
                 continue;
             }
-            OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN2");
         }
         else
         {
-            OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN3");
-            result = CAEDRSendData(device->socketFD, data, dataLength, sentLength);
+            result = CAEDRSendData(device->socketFD, device->remoteAddress ,data, dataLength);
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send data to [%s] !",
                           device->remoteAddress);
             }
-            OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN4");
         }
     }
-    ca_mutex_unlock(g_edrDeviceListMutex);
 
+    oc_mutex_unlock(g_edrDeviceListMutex);
+
+    if(g_isDiscoveryServer)
+    {
+        // Start the device Discovery.
+        result = CAEDRStartDeviceDiscovery();
+        if (CA_STATUS_OK == result)
+        {
+            OIC_LOG(INFO, EDR_ADAPTER_TAG, "Add the data to the multicast data list");
+
+            EDRData *multicastData = (EDRData *)OICCalloc(1, sizeof(EDRData));
+            if (NULL == multicastData)
+            {
+                OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
+                goto exit;
+            }
+            multicastData->data = OICCalloc(1, dataLength);
+            if (NULL == multicastData->data)
+            {
+                OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Malloc failed");
+                goto exit;
+            }
+            memcpy(multicastData->data, data, dataLength);
+            multicastData->dataLength = dataLength;
+
+            // Add the data to pending multicast data list.
+            oc_mutex_lock(g_multicastDataListMutex);
+            if (NULL == g_multicastDataList)
+            {
+                g_multicastDataList = u_arraylist_create();
+            }
+            u_arraylist_add(g_multicastDataList, (void *)multicastData);
+            oc_mutex_unlock(g_multicastDataListMutex);
+        }
+    }
+
+exit:
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -849,29 +945,106 @@ void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
     }
 
     // Get EDR device from list
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
     CAResult_t result = CAGetEDRDeviceBySocketId(g_edrDeviceList, data->socket_fd, &device);
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not find the device!");
 
-        ca_mutex_unlock(g_edrDeviceListMutex);
+        oc_mutex_unlock(g_edrDeviceListMutex);
         return;
     }
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
+    //: TODO Need to check if 'check required for socket still connected or not'
     if (!device)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
         return;
     }
 
-    uint32_t sentLength = 0;
+    CAConnectedDeviceInfo_t *deviceInfo =
+        (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(device->remoteAddress);
 
-    g_edrPacketReceivedCallback(device->remoteAddress, data->data,
-                                (uint32_t)data->data_size, &sentLength);
+    if (!deviceInfo)
+    {
+        OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Received Data from new device");
+        deviceInfo = (CAConnectedDeviceInfo_t *) OICCalloc(1, sizeof(*deviceInfo));
+        if (!deviceInfo)
+        {
+            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Out of memory");
+            return;
+        }
 
-    OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
-}
+        deviceInfo->state = STATE_CONNECTED;
+        deviceInfo->recvData = NULL;
+        deviceInfo->recvDataLen = 0;
+        deviceInfo->totalDataLen = 0;
+        result = CAEDRAddDeviceInfoToList(device->remoteAddress, deviceInfo);
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not add device info to list!");
+            OICFree(deviceInfo);
+            return;
+        }
+    }
 
+    if (!deviceInfo->recvData)
+    {
+        OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Callocing deviceInfo->recvData");
+        deviceInfo->recvData = OICCalloc(data->data_size, sizeof(uint8_t));
+        if (!deviceInfo->recvData)
+        {
+            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "out of memory");
+            return;
+        }
+    }
+
+    memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*)data->data,
+           data->data_size);
+    deviceInfo->recvDataLen += data->data_size;
+
+    if (!deviceInfo->totalDataLen)
+    {
+        coap_transport_t transport = coap_get_tcp_header_type_from_initbyte(
+                ((unsigned char *)deviceInfo->recvData)[0] >> 4);
+        size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
+
+        if (deviceInfo->recvDataLen >= headerLen)
+        {
+            // get actual data length from coap over tcp header
+            deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
+                                                                     deviceInfo->recvDataLen);
+            OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
+
+            uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
+            if (!newBuf)
+            {
+                OIC_LOG(ERROR, EDR_ADAPTER_TAG, "out of memory");
+                //Memory free
+                return;
+            }
+            deviceInfo->recvData = newBuf;
+        }
+    }
+
+    if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
+    {
+        if (g_edrPacketReceivedCallback)
+        {
+            OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG,"data will be sent to callback routine: %s, %d",
+                      deviceInfo->recvData, deviceInfo->recvDataLen);
 
+            uint32_t sentLength = 0;
+            g_edrPacketReceivedCallback(device->remoteAddress, (void*) deviceInfo->recvData,
+                                        deviceInfo->recvDataLen, &sentLength);
+
+            OICFree(deviceInfo->recvData);
+            deviceInfo->recvData = NULL;
+            deviceInfo->recvDataLen = 0;
+            deviceInfo->totalDataLen = 0;
+        }
+    }
+
+    OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
+}