BLE Adapter code updated for Tizen-4.0 14/192414/1
authorAmit KS <amit.s12@samsung.com>
Mon, 5 Nov 2018 09:41:30 +0000 (15:11 +0530)
committerAmit KS <amit.s12@samsung.com>
Mon, 5 Nov 2018 09:41:30 +0000 (15:11 +0530)
https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/331
(cherry picked from commit d38432e9d10f45248bd908cdac10a21fa55e0ab1)

Change-Id: I2c2064842acedac91bcad20944c4c910f16a8228
Signed-off-by: Amit KS <amit.s12@samsung.com>
13 files changed:
resource/csdk/SConscript
resource/csdk/connectivity/src/SConscript
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c
resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.h
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleutil.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleutil.h
resource/csdk/resource-directory/SConscript
resource/csdk/stack/samples/tizen/build/SConscript
resource/csdk/stack/samples/tizen/build/gbsbuild.sh
tools/tizen/.gbs.conf

index 5420d98..f12a87a 100644 (file)
@@ -94,6 +94,9 @@ liboctbstack_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
 
 liboctbstack_env.PrependUnique(LIBS = ['ocsrm', 'coap'])
 
+if target_os in ['tizen']:
+    liboctbstack_env.AppendUnique(LIBS = ['pthread'])
+
 if target_os in ['linux'] and liboctbstack_env.get('SIMULATOR', False):
        liboctbstack_env.Append( RPATH = liboctbstack_env.Literal('\\$$ORIGIN'))
 
index 1abd0ce..0beba71 100644 (file)
@@ -214,6 +214,9 @@ if lib_env.get('SECURED') == '1':
                        lib_env.PrependUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto'])
                        lib_env.PrependUnique(LIBS = ['timer'])
 
+if ca_os in ['tizen']:
+    lib_env.AppendUnique(LIBS=['pthread'])
+
 if ca_os in ['android', 'tizen', 'linux']:
        lib_env.AppendUnique(LIBS = ['coap'])
        if ca_os != 'android':
index 87a2d6e..9977465 100644 (file)
@@ -92,7 +92,6 @@ static oc_mutex g_threadWriteCharacteristicMutex = NULL;
 static oc_cond g_threadWriteCharacteristicCond = NULL;
 static bool g_isSignalSetFlag = false;
 
-static oc_mutex g_bleReqRespClientCbMutex = NULL;
 static oc_mutex g_bleServerBDAddressMutex = NULL;
 
 static oc_mutex g_deviceListMutex = NULL;
@@ -4441,16 +4440,6 @@ void CALEClientUpdateSendCnt(JNIEnv *env)
 
 CAResult_t CALEClientInitGattMutexVaraibles()
 {
-    if (NULL == g_bleReqRespClientCbMutex)
-    {
-        g_bleReqRespClientCbMutex = oc_mutex_new();
-        if (NULL == g_bleReqRespClientCbMutex)
-        {
-            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
-            return CA_STATUS_FAILED;
-        }
-    }
-
     if (NULL == g_bleServerBDAddressMutex)
     {
         g_bleServerBDAddressMutex = oc_mutex_new();
@@ -4576,9 +4565,7 @@ CAResult_t CALEClientInitGattMutexVaraibles()
 
 void CALEClientTerminateGattMutexVariables()
 {
-    oc_mutex_free(g_bleReqRespClientCbMutex);
-    g_bleReqRespClientCbMutex = NULL;
-
+   
     oc_mutex_free(g_bleServerBDAddressMutex);
     g_bleServerBDAddressMutex = NULL;
 
@@ -4782,9 +4769,9 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t
 
 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
 {
-    oc_mutex_lock(g_bleReqRespClientCbMutex);
+    
     g_CABLEClientDataReceivedCallback = callback;
-    oc_mutex_unlock(g_bleReqRespClientCbMutex);
+    
 }
 
 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
index 7ecbefa..94b4f6e 100755 (executable)
@@ -59,7 +59,7 @@ typedef struct
     uint32_t totalDataLen;
     uint8_t *defragData;
     CAEndpoint_t *remoteEndpoint;
- } CABLESenderInfo_t;
+} CABLESenderInfo_t;
 
 typedef enum
 {
@@ -111,12 +111,6 @@ static CADataType_t g_dataType = CA_REQUEST_DATA;
 static oc_mutex g_bleIsServerMutex = NULL;
 
 /**
- * Mutex to synchronize the callback to be called for the network
- * changes.
- */
-static oc_mutex g_bleNetworkCbMutex = NULL;
-
-/**
  * Mutex to synchronize the updates of the local LE address of the
  * adapter.
  */
@@ -128,35 +122,15 @@ static oc_mutex g_bleLocalAddressMutex = NULL;
 static ca_thread_pool_t g_bleAdapterThreadPool = NULL;
 
 /**
- * Mutex to synchronize the task to be pushed to thread pool.
- */
-static oc_mutex g_bleAdapterThreadPoolMutex = NULL;
-
-/**
- * Mutex to synchronize the queing of the data from SenderQueue.
- */
-static oc_mutex g_bleClientSendDataMutex = NULL;
-
-/**
  * Mutex to synchronize the queing of the data from ReceiverQueue.
  */
 static oc_mutex g_bleClientReceiveDataMutex = NULL;
 
 /**
- * Mutex to synchronize the queing of the data from SenderQueue.
- */
-static oc_mutex g_bleServerSendDataMutex = NULL;
-
-/**
  * Mutex to synchronize the queing of the data from ReceiverQueue.
  */
 static oc_mutex g_bleServerReceiveDataMutex = NULL;
 
-/**
- * Mutex to synchronize the callback to be called for the
- * adapterReqResponse.
- */
-static oc_mutex g_bleAdapterReqRespCbMutex = NULL;
 
 /**
  * Callback to be called when network packet received from either
@@ -523,7 +497,6 @@ static void CALEDataDestroyer(void *data, uint32_t size);
  * @param[in] address        target address to remove data in queue.
  */
 static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle,
-                                    oc_mutex mutex,
                                     const char* address);
 
 /**
@@ -540,7 +513,7 @@ static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList,
  * for client / server which is matched same leAddress and port.
  *
  * @param[in]  leAddress       target address to get serderInfo.
- * @param[in]  port            target port to get serderInfo.
+ * @param[in]  port            target port to get senderInfo.
  * @param[in]  senderInfoList  received data list for client / server.
  * @param[out] senderInfo      Pointer to contain matched(leAddress and port)
  *                             received data info.
@@ -569,13 +542,12 @@ static CAResult_t CALEGetPortsFromSenderInfo(const char *leAddress,
 
 static CAResult_t CAInitLEServerQueues()
 {
-    oc_mutex_lock(g_bleAdapterThreadPoolMutex);
-
+    
     CAResult_t result = CAInitLEServerSenderQueue();
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerSenderQueue failed");
-        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        
         return CA_STATUS_FAILED;
     }
 
@@ -583,7 +555,6 @@ static CAResult_t CAInitLEServerQueues()
     if (!g_bleServerSenderInfo)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "memory allocation failed!");
-        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
@@ -592,25 +563,19 @@ static CAResult_t CAInitLEServerQueues()
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEServerReceiverQueue failed");
         u_arraylist_free(&g_bleServerSenderInfo);
-        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
 
     g_dataBleServerReceiverHandlerState = true;
-
-    oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
     return CA_STATUS_OK;
 }
 
 static CAResult_t CAInitLEClientQueues()
 {
-    oc_mutex_lock(g_bleAdapterThreadPoolMutex);
-
     CAResult_t result = CAInitLEClientSenderQueue();
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientSenderQueue failed");
-        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -618,7 +583,6 @@ static CAResult_t CAInitLEClientQueues()
     if (!g_bleClientSenderInfo)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "memory allocation failed!");
-        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
@@ -627,13 +591,11 @@ static CAResult_t CAInitLEClientQueues()
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEClientReceiverQueue failed");
         u_arraylist_free(&g_bleClientSenderInfo);
-        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
 
     g_dataBleClientReceiverHandlerState = true;
 
-    oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
     return CA_STATUS_OK;
 }
 
@@ -749,7 +711,7 @@ static CAResult_t CAInitLEServerSenderQueue()
     return CA_STATUS_OK;
 }
 
-static void CALEClearSenderInfoImpl(u_arraylist_t ** list)
+static void CALEClearSenderInfoImpl(u_arraylist_t **list)
 {
     const size_t length = u_arraylist_length(*list);
     for (size_t i = 0; i < length; ++i)
@@ -1117,7 +1079,6 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
 
         if (senderInfo->totalDataLen == senderInfo->recvDataLen)
         {
-            oc_mutex_lock(g_bleAdapterReqRespCbMutex);
             if (NULL == g_networkPacketReceivedCallback)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
@@ -1125,7 +1086,6 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
                 u_arraylist_remove(bleData->senderInfo, senderIndex);
                 OICFree(senderInfo->defragData);
                 OICFree(senderInfo);
-                oc_mutex_unlock(g_bleAdapterReqRespCbMutex);
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
@@ -1152,7 +1112,6 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
                         break;
                     default:
                         OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Unsupported rcvr type:%d",receiverType);
-                        oc_mutex_unlock(g_bleAdapterReqRespCbMutex);
                         u_arraylist_remove(bleData->senderInfo, senderIndex);
                         senderInfo->remoteEndpoint = NULL;
                         senderInfo->defragData = NULL;
@@ -1184,7 +1143,6 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
             }
 #endif
 
-            oc_mutex_unlock(g_bleAdapterReqRespCbMutex);
             u_arraylist_remove(bleData->senderInfo, senderIndex);
             senderInfo->remoteEndpoint = NULL;
             senderInfo->defragData = NULL;
@@ -1222,7 +1180,7 @@ static void CALEServerSendDataThread(void *threadData)
         return;
     }
 
-#if defined(__TIZEN__) || defined(__ANDROID__)
+#if defined(__ANDROID__)
     // get MTU size
     g_mtuSize = CALEServerGetMtuSize(bleData->remoteEndpoint->addr);
 #endif
@@ -1505,7 +1463,7 @@ static void CALEClientSendDataThread(void *threadData)
         return;
     }
 
-#if defined(__TIZEN__) || defined(__ANDROID__)
+#if defined(__ANDROID__)
     // get MTU size
     if (false == CALEClientIsConnected(bleData->remoteEndpoint->addr))
     {
@@ -2161,17 +2119,6 @@ static CAResult_t CAInitLEAdapterMutex()
         }
     }
 
-    if (NULL == g_bleNetworkCbMutex)
-    {
-        g_bleNetworkCbMutex = oc_mutex_new();
-        if (NULL == g_bleNetworkCbMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
-            CATerminateLEAdapterMutex();
-            return CA_STATUS_FAILED;
-        }
-    }
-
     if (NULL == g_bleLocalAddressMutex)
     {
         g_bleLocalAddressMutex = oc_mutex_new();
@@ -2183,49 +2130,7 @@ static CAResult_t CAInitLEAdapterMutex()
         }
     }
 
-    if (NULL == g_bleAdapterThreadPoolMutex)
-    {
-        g_bleAdapterThreadPoolMutex = oc_mutex_new();
-        if (NULL == g_bleAdapterThreadPoolMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
-            CATerminateLEAdapterMutex();
-            return CA_STATUS_FAILED;
-        }
-    }
-
-    if (NULL == g_bleClientSendDataMutex)
-    {
-        g_bleClientSendDataMutex = oc_mutex_new();
-        if (NULL == g_bleClientSendDataMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
-            CATerminateLEAdapterMutex();
-            return CA_STATUS_FAILED;
-        }
-    }
-
-    if (NULL == g_bleServerSendDataMutex)
-    {
-        g_bleServerSendDataMutex = oc_mutex_new();
-        if (NULL == g_bleServerSendDataMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
-            CATerminateLEAdapterMutex();
-            return CA_STATUS_FAILED;
-        }
-    }
-
-    if (NULL == g_bleAdapterReqRespCbMutex)
-    {
-        g_bleAdapterReqRespCbMutex = oc_mutex_new();
-        if (NULL == g_bleAdapterReqRespCbMutex)
-        {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
-            CATerminateLEAdapterMutex();
-            return CA_STATUS_FAILED;
-        }
-    }
+    
 
     if (NULL == g_bleServerReceiveDataMutex)
     {
@@ -2257,23 +2162,11 @@ static void CATerminateLEAdapterMutex()
     oc_mutex_free(g_bleIsServerMutex);
     g_bleIsServerMutex = NULL;
 
-    oc_mutex_free(g_bleNetworkCbMutex);
-    g_bleNetworkCbMutex = NULL;
-
+    
     oc_mutex_free(g_bleLocalAddressMutex);
     g_bleLocalAddressMutex = NULL;
 
-    oc_mutex_free(g_bleAdapterThreadPoolMutex);
-    g_bleAdapterThreadPoolMutex = NULL;
-
-    oc_mutex_free(g_bleClientSendDataMutex);
-    g_bleClientSendDataMutex = NULL;
-
-    oc_mutex_free(g_bleServerSendDataMutex);
-    g_bleServerSendDataMutex = NULL;
-
-    oc_mutex_free(g_bleAdapterReqRespCbMutex);
-    g_bleAdapterReqRespCbMutex = NULL;
+    
 
     oc_mutex_free(g_bleServerReceiveDataMutex);
     g_bleServerReceiveDataMutex = NULL;
@@ -2501,10 +2394,7 @@ static CAResult_t CALEAdapterGattServerStart()
     */
     if (CA_STATUS_OK == result)
     {
-        oc_mutex_lock(g_bleServerSendDataMutex);
         result = CAQueueingThreadStart(g_bleServerSendQueueHandle);
-        oc_mutex_unlock(g_bleServerSendDataMutex);
-
         if (CA_STATUS_OK != result)
         {
             OIC_LOG_V(ERROR,
@@ -2531,14 +2421,11 @@ static CAResult_t CALEAdapterGattServerStop()
 
 #ifndef SINGLE_THREAD
 
-    oc_mutex_lock(g_bleServerSendDataMutex);
     CAResult_t res = CAQueueingThreadStop(g_bleServerSendQueueHandle);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAQueueingThreadStop has failed");
     }
-    oc_mutex_unlock(g_bleServerSendDataMutex);
-
     res = CAStopLEGattServer();
     if (CA_STATUS_OK != res)
     {
@@ -2564,10 +2451,7 @@ static CAResult_t CALEAdapterGattClientStart()
     */
     if (CA_STATUS_OK == result)
     {
-        oc_mutex_lock(g_bleClientSendDataMutex);
         result = CAQueueingThreadStart(g_bleClientSendQueueHandle);
-        oc_mutex_unlock(g_bleClientSendDataMutex);
-
         if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR,
@@ -2586,10 +2470,8 @@ static CAResult_t CALEAdapterGattClientStop()
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
     CAStopLEGattClient();
 
-    oc_mutex_lock(g_bleClientSendDataMutex);
     CAResult_t result = CAQueueingThreadStop(g_bleClientSendQueueHandle);
-    oc_mutex_unlock(g_bleClientSendDataMutex);
-
+    
     return result;
 #else
     CAStopLEGattClient();
@@ -3208,10 +3090,8 @@ static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCa
 {
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
-    oc_mutex_lock(g_bleNetworkCbMutex);
     g_networkCallback = netCallback;
     g_connectionCallback = connCallback;
-    oc_mutex_unlock(g_bleNetworkCbMutex);
     CAResult_t res = CA_STATUS_OK;
     if (netCallback)
     {
@@ -3298,16 +3178,12 @@ static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const cha
         // remove data of send queue.
         if (g_bleClientSendQueueHandle)
         {
-            CALERemoveSendQueueData(g_bleClientSendQueueHandle,
-                                    g_bleClientSendDataMutex,
-                                    address);
+            CALERemoveSendQueueData(g_bleClientSendQueueHandle, address);
         }
 
         if (g_bleServerSendQueueHandle)
         {
-            CALERemoveSendQueueData(g_bleServerSendQueueHandle,
-                                    g_bleServerSendDataMutex,
-                                    address);
+            CALERemoveSendQueueData(g_bleServerSendQueueHandle, address);
         }
 #endif
 
@@ -3390,10 +3266,7 @@ static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
     VERIFY_NON_NULL_RET(g_bleClientSendQueueHandle, CALEADAPTER_TAG,
                         "g_bleClientSendQueueHandle is  NULL",
                         CA_STATUS_FAILED);
-    VERIFY_NON_NULL_RET(g_bleClientSendDataMutex, CALEADAPTER_TAG,
-                        "g_bleClientSendDataMutex is NULL",
-                        CA_STATUS_FAILED);
-
+    
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%u]", dataLen);
 
     CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLen, NULL);
@@ -3403,9 +3276,13 @@ static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
         return CA_MEMORY_ALLOC_FAILED;
     }
     // Add message to send queue
-    oc_mutex_lock(g_bleClientSendDataMutex);
-    CAQueueingThreadAddData(g_bleClientSendQueueHandle, bleData, sizeof(CALEData_t));
-    oc_mutex_unlock(g_bleClientSendDataMutex);
+    
+    CAResult_t res = CAQueueingThreadAddData(g_bleClientSendQueueHandle, bleData,
+                                             sizeof(CALEData_t));
+    if (CA_STATUS_OK != res)
+    {
+        CALEDataDestroyer(bleData, sizeof(CALEData_t));
+    }
 #endif
     return CA_STATUS_OK;
 }
@@ -3433,13 +3310,7 @@ static CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint,
     }
 #else
     VERIFY_NON_NULL_RET(g_bleServerSendQueueHandle, CALEADAPTER_TAG,
-                        "BleClientReceiverQueue is NULL",
-                        CA_STATUS_FAILED);
-    VERIFY_NON_NULL_RET(g_bleServerSendDataMutex, CALEADAPTER_TAG,
-                        "BleClientSendDataMutex is NULL",
-                        CA_STATUS_FAILED);
-
-    VERIFY_NON_NULL_RET(g_bleServerSendQueueHandle, CALEADAPTER_TAG, "sendQueueHandle",
+                        "g_bleServerSendQueueHandle is NULL",
                         CA_STATUS_FAILED);
 
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%d]", dataLen);
@@ -3454,11 +3325,14 @@ static CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint,
     }
 
     // Add message to send queue
-    oc_mutex_lock(g_bleServerSendDataMutex);
-    CAQueueingThreadAddData(g_bleServerSendQueueHandle,
-                            bleData,
-                            sizeof(CALEData_t));
-    oc_mutex_unlock(g_bleServerSendDataMutex);
+    
+    CAResult_t res = CAQueueingThreadAddData(g_bleServerSendQueueHandle,
+                                           bleData,
+                                           sizeof(CALEData_t));
+    if (CA_STATUS_OK != res)
+    {
+        CALEDataDestroyer(bleData, sizeof(CALEData_t));
+    }
 #endif
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return CA_STATUS_OK;
@@ -3591,18 +3465,14 @@ static CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress,
 
 static void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle)
 {
-    oc_mutex_lock(g_bleAdapterThreadPoolMutex);
     g_bleAdapterThreadPool = handle;
-    oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
+    
 }
 
 static void CASetLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback)
 {
-    oc_mutex_lock(g_bleAdapterReqRespCbMutex);
-
     g_networkPacketReceivedCallback = callback;
 
-    oc_mutex_unlock(g_bleAdapterReqRespCbMutex);
 }
 
 static void CALEErrorHandler(const char *remoteAddress,
@@ -3628,44 +3498,42 @@ static void CALEErrorHandler(const char *remoteAddress,
 }
 
 #ifndef SINGLE_THREAD
-static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, oc_mutex mutex,
-                                    const char* address)
+static bool CALEClearQueueAddressDataContext(void *data, uint32_t size, void *ctx)
+{
+    if (NULL == data || NULL == ctx)
+    {
+        return false;
+    }
+
+    CALEData_t *caLeData = (CALEData_t *)data;
+    const char *address = (const char *)ctx;
+
+    if (NULL != caLeData && NULL != caLeData->remoteEndpoint)
+    {
+        if (!strcasecmp(caLeData->remoteEndpoint->addr, address))
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, const char* address)
 {
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     VERIFY_NON_NULL_VOID(queueHandle, CALEADAPTER_TAG, "queueHandle");
     VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address");
 
-    oc_mutex_lock(mutex);
-    oc_mutex_lock(queueHandle->threadMutex);
-    while (u_queue_get_size(queueHandle->dataQueue) > 0)
+    CAResult_t res = CAQueueingThreadClearContextData(queueHandle,
+                                                      CALEClearQueueAddressDataContext,
+                                                      address);
+    if (CA_STATUS_OK != res)
     {
-        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 (!strcasecmp(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);
-                }
-            }
-        }
+        
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Could not clear the send queue");
     }
-    oc_mutex_unlock(queueHandle->threadMutex);
-    oc_mutex_unlock(mutex);
+    
 }
 
 static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList, const char* address)
index b0f374c..87c47b8 100644 (file)
 uint64_t const TIMEOUT = 30 * MICROSECS_PER_SEC;
 
 /**
+ * Flag to check if scanning is in progress
+ */
+static bool g_isScanningInProgress = false;
+
+/**
+ * Mutex to synchronize access to g_isScanningInProgress
+ */
+static oc_mutex g_isScanningInProgressMutex = NULL;
+
+/**
+ * Flag to check if connection is in progress
+ */
+static bool g_isConnectionInProgress = false;
+
+/**
+ * Mutex to synchronize access to g_isConnectionInProgress
+ */
+static oc_mutex g_isConnectionInProgressMutex = NULL;
+
+/**
  * Flag to check if multicast is already in progress.
  */
 static bool g_isMulticastInProgress = false;
 
 /**
- * Pending multicast data list to be sent.
+ * Flag to check if unicast scan is in progress
  */
-static u_arraylist_t *g_multicastDataList = NULL;
+static bool g_isUnicastScanInProgress = false;
 
 /**
- * Mutex to synchronize the access to Pending multicast data list.
+ * Mutex to synchronize access to g_isMulticastInProgress
+ * and g_isUnicastScanInProgress
  */
-static oc_mutex g_multicastDataListMutex = NULL;
+static oc_mutex g_scanMutex = NULL;
 
 /**
- * List of devices discovered.
+ * Pending multicast data list to be sent.
  */
-static u_arraylist_t *g_deviceDiscoveredList = NULL;
+static u_arraylist_t *g_multicastDataList = NULL;
 
 /**
- * Mutex to synchronize the access to discovered devices list.
+ * Mutex to synchronize the access to Pending multicast data list.
  */
-static oc_mutex g_deviceDiscoveredListMutex = NULL;
+static oc_mutex g_multicastDataListMutex = NULL;
 
 /**
  * Condition to start the timer for scanning.
@@ -157,77 +178,6 @@ static GMainLoop *g_eventLoop = NULL;
  */
 static ca_thread_pool_t g_LEClientThreadPool = NULL;
 
-bool CALEIsHaveService(bt_adapter_le_device_scan_result_info_s* scanInfo, char* service_uuid)
-{
-    bool ret = false;
-    char **uuids = NULL;
-    int count = 0;
-    int result = 0;
-
-    // For arduino servers, scan response will give the UUIDs advertised.
-    result = bt_adapter_le_get_scan_result_service_uuids(scanInfo,
-                                                         BT_ADAPTER_LE_PACKET_SCAN_RESPONSE,
-                                                         &uuids, &count);
-    if (result == BT_ERROR_NONE && NULL != uuids)
-    {
-        int i;
-        for (i = 0; i < count; i++)
-        {
-            if (0 == strcasecmp(uuids[i], service_uuid))
-            {
-                OIC_LOG_V(DEBUG, TAG, "Service[%s] Found in %s",
-                          uuids[i], scanInfo->remote_address);
-                ret = true;
-            }
-            OICFree(uuids[i]);
-        }
-        OICFree(uuids);
-    }
-
-    // For android/tizen servers, advertising packet will give the UUIDs.
-    result = bt_adapter_le_get_scan_result_service_uuids(scanInfo,
-                                                         BT_ADAPTER_LE_PACKET_ADVERTISING,
-                                                         &uuids, &count);
-    if (result == BT_ERROR_NONE && NULL != uuids)
-    {
-        int i;
-        for (i = 0; i < count; i++)
-        {
-            if (0 == strcasecmp(uuids[i], service_uuid))
-            {
-                OIC_LOG_V(DEBUG, TAG, "Service[%s] Found in %s",
-                          uuids[i], scanInfo->remote_address);
-                ret = true;
-            }
-            OICFree(uuids[i]);
-        }
-        OICFree(uuids);
-    }
-
-    return ret;
-}
-
-bool CALEIsDeviceDiscovered(const char * address)
-{
-    if (g_deviceDiscoveredList)
-    {
-        oc_mutex_lock(g_deviceDiscoveredListMutex);
-        uint32_t arrayLength = u_arraylist_length(g_deviceDiscoveredList);
-        for (uint32_t i = 0; i < arrayLength; i++)
-        {
-            char *deviceAddr = u_arraylist_get(g_deviceDiscoveredList, i);
-            if (0 == strcasecmp(deviceAddr, address))
-            {
-                oc_mutex_unlock(g_deviceDiscoveredListMutex);
-                return true;
-            }
-
-        }
-        oc_mutex_unlock(g_deviceDiscoveredListMutex);
-    }
-    return false;
-}
-
 void CALEGattCharacteristicChangedCb(bt_gatt_h characteristic,
                                      char *value,
                                      int valueLen, void *userData)
@@ -285,20 +235,60 @@ void CALEGattCharacteristicWriteCb(int result, bt_gatt_h reqHandle, void *userDa
     OIC_LOG(DEBUG, TAG, "OUT ");
 }
 
-void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
+CAResult_t CALEGattInitiateConnection(const char *remoteAddress)
 {
-    OIC_LOG(DEBUG, TAG, "IN ");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
+    oc_mutex_lock(g_isConnectionInProgressMutex);
+    if (g_isConnectionInProgress)
+    {
+        oc_mutex_unlock(g_isConnectionInProgressMutex);
+        OIC_LOG(DEBUG, TAG, "Connection already in progress, cannot initiate new connection");
+        return CA_STATUS_FAILED;
+    }
+    g_isConnectionInProgress = true;
+    oc_mutex_unlock(g_isConnectionInProgressMutex);
+
+    // Pause the scanning
+    CALEGattStopDeviceScanning();
+
+    OIC_LOG_V(DEBUG, TAG,
+              "Trying to do Gatt connection to [%s]", remoteAddress);
 
-    // Start the scanning.
-    CAResult_t ret = CALEGattStartDeviceScanning();
-    if (CA_STATUS_OK != ret)
+    oc_mutex_lock(g_LEClientThreadPoolMutex);
+    if (NULL == g_LEClientThreadPool)
     {
-        OIC_LOG(ERROR, TAG, "CALEGattStartDeviceDiscovery Failed");
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
+        OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
+        return CA_STATUS_FAILED;
     }
-    // Signal the start timer.
-    oc_cond_signal(g_scanningTimeCond);
+
+    char *addr = OICStrdup(remoteAddress);
+    if (NULL == addr)
+    {
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
+        OIC_LOG(ERROR, TAG, "OICStrdup failed");
+        return CA_STATUS_FAILED;
+    }
+
+    CAResult_t res = ca_thread_pool_add_task(g_LEClientThreadPool, CAGattConnectThread, addr, NULL);
+    oc_mutex_unlock(g_LEClientThreadPoolMutex);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "ca_thread_pool_add_task failed with ret [%d]", res);
+        OICFree(addr);
+        return CA_STATUS_FAILED;
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN ");
+
+    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
 
     if (!connected)
     {
@@ -311,34 +301,102 @@ void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
     {
         OIC_LOG_V(DEBUG, TAG, "Connected to [%s] ", remoteAddress);
 
-        char *addr = OICStrdup(remoteAddress);
-        if (NULL == addr)
+        oc_mutex_lock(g_isConnectionInProgressMutex);
+        g_isConnectionInProgress = false;
+        oc_mutex_unlock(g_isConnectionInProgressMutex);
+
+        // Resume the scanning
+        oc_mutex_lock(g_scanMutex);
+        if (g_isMulticastInProgress || g_isUnicastScanInProgress)
         {
-            OIC_LOG(ERROR, TAG, "addr is NULL");
+            CAResult_t ret = CALEGattStartDeviceScanning();
+            if (CA_STATUS_OK != ret)
+            {
+                OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning Failed");
+            }
+        }
+        oc_mutex_unlock(g_scanMutex);
+
+        LEServerInfo *serverInfo = NULL;
+        oc_mutex_lock(g_LEServerListMutex);
+        if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
+        {
+            oc_mutex_unlock(g_LEServerListMutex);
+            OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
             return;
         }
 
+        serverInfo->status = LE_STATUS_CONNECTED;
+        oc_mutex_unlock(g_LEServerListMutex);
+
         oc_mutex_lock(g_LEClientThreadPoolMutex);
         if (NULL == g_LEClientThreadPool)
         {
+            oc_mutex_unlock(g_LEClientThreadPoolMutex);
             OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
-            OICFree(addr);
+            return;
+        }
+
+        char *addr = OICStrdup(remoteAddress);
+        if (NULL == addr)
+        {
             oc_mutex_unlock(g_LEClientThreadPoolMutex);
+            OIC_LOG(ERROR, TAG, "addr is NULL");
             return;
         }
 
-        ret = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
-                                      addr, NULL);
+        CAResult_t ret = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
+                                                 addr, NULL);
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
         if (CA_STATUS_OK != ret)
         {
             OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
             OICFree(addr);
         }
-        oc_mutex_unlock(g_LEClientThreadPoolMutex);
     }
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
+static bool CALEIsHaveServiceImpl(bt_adapter_le_device_scan_result_info_s *scanInfo,
+                                  const char *service_uuid,
+                                  bt_adapter_le_packet_type_e pkt_type)
+{
+    bool ret = false;
+    char **uuids = NULL;
+    int count = 0;
+    int result = 0;
+
+    result = bt_adapter_le_get_scan_result_service_uuids(scanInfo,
+             pkt_type, &uuids, &count);
+    if (result == BT_ERROR_NONE && NULL != uuids)
+    {
+        for (int i = 0; i < count; i++)
+        {
+            if (0 == strcasecmp(uuids[i], service_uuid))
+            {
+                OIC_LOG_V(DEBUG, TAG, "Service[%s] Found in %s",
+                          uuids[i], scanInfo->remote_address);
+                ret = true;
+            }
+            OICFree(uuids[i]);
+        }
+        OICFree(uuids);
+    }
+    return ret;
+}
+
+static bool CALEIsHaveService(bt_adapter_le_device_scan_result_info_s *scanInfo,
+                              const char *service_uuid)
+{
+    return
+        // For arduino servers, scan response will give the UUIDs advertised.
+        CALEIsHaveServiceImpl(scanInfo, service_uuid,
+                              BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) ||
+        // For android/tizen servers, advertising packet will give the UUIDs.
+        CALEIsHaveServiceImpl(scanInfo, service_uuid,
+                              BT_ADAPTER_LE_PACKET_ADVERTISING);
+}
+
 void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s *scanInfo,
                              void *userData)
 {
@@ -356,65 +414,153 @@ void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s
               scanInfo->adv_data_len, scanInfo->scan_data_len, scanInfo->rssi,
               scanInfo->address_type);
 
-    // Check if device is already discovered.
-    if (CALEIsDeviceDiscovered(scanInfo->remote_address))
+    // Check if scanning was stopped (since this callback is
+    // being triggered even after stopping the scan)
+    oc_mutex_lock(g_isScanningInProgressMutex);
+    if (!g_isScanningInProgress)
     {
-        OIC_LOG_V(INFO, TAG, "Device[%s] is already discovered", scanInfo->remote_address);
+        oc_mutex_unlock(g_isScanningInProgressMutex);
+        OIC_LOG(DEBUG, TAG, "Scanning not in progress, so ignoring callback");
         return;
     }
+    oc_mutex_unlock(g_isScanningInProgressMutex);
+
+    oc_mutex_lock(g_scanMutex);
+    bool isMulticastInProgress = g_isMulticastInProgress;
+    oc_mutex_unlock(g_scanMutex);
+
+    LEServerInfo *serverInfo = NULL;
+    oc_mutex_lock(g_LEServerListMutex);
+    CAResult_t ret = CAGetLEServerInfo(g_LEServerList, scanInfo->remote_address, &serverInfo);
 
-    if (!CALEIsHaveService(scanInfo, CA_GATT_SERVICE_UUID))
+    if (CA_STATUS_OK == ret && serverInfo->status == LE_STATUS_UNICAST_PENDING)
     {
-        oc_mutex_lock(g_deviceDiscoveredListMutex);
-        // Add the the device Discovered list.
-        if (NULL == g_deviceDiscoveredList)
+        // Stop the scan if no other device is in unicast pending
+        // state and if multicast is not in progress
+        LEServerInfoList *curNode = g_LEServerList;
+        for (; curNode; curNode = curNode->next)
+        {
+            if (curNode->serverInfo == serverInfo)
+            {
+                continue;
+            }
+            if (curNode->serverInfo->status == LE_STATUS_UNICAST_PENDING)
+            {
+                break;
+            }
+        }
+
+        if (NULL == curNode)
         {
-            g_deviceDiscoveredList = u_arraylist_create();
+            oc_mutex_lock(g_scanMutex);
+            if (!g_isMulticastInProgress && g_isUnicastScanInProgress)
+            {
+                CALEGattStopDeviceScanning();
+                g_isUnicastScanInProgress = false;
+                oc_cond_signal(g_scanningTimeCond);
+            }
+            oc_mutex_unlock(g_scanMutex);
         }
-        char *deviceAddr = OICStrdup(scanInfo->remote_address);
-        if (NULL == deviceAddr)
+
+        if (!CALEIsHaveService(scanInfo, CA_GATT_SERVICE_UUID))
         {
-            OIC_LOG_V(ERROR, TAG, "Device address is NULL");
-            oc_mutex_unlock(g_deviceDiscoveredListMutex);
+            serverInfo->status = LE_STATUS_INVALID;
+            OIC_LOG_V(DEBUG, TAG, "Device [%s] does not support OIC service", serverInfo->remoteAddress);
+            oc_mutex_unlock(g_LEServerListMutex);
             return;
         }
 
-        u_arraylist_add(g_deviceDiscoveredList, (void *) deviceAddr);
-        oc_mutex_unlock(g_deviceDiscoveredListMutex);
-        OIC_LOG_V(INFO, TAG, "Device[%s] is don't have service", scanInfo->remote_address);
+        serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
+        if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
+        {
+            serverInfo->status = LE_STATUS_DISCOVERED;
+            OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
+            oc_mutex_unlock(g_LEServerListMutex);
+            return;
+        }
+        oc_mutex_unlock(g_LEServerListMutex);
+        OIC_LOG(DEBUG, TAG, "OUT");
         return;
     }
 
-    // Stop the scan before invoking bt_gatt_connect().
-    CALEGattStopDeviceScanning();
+    if (isMulticastInProgress)
+    {
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(DEBUG, TAG,
+                      "Newly discovered device with address [%s], adding to list", scanInfo->remote_address);
 
-    size_t len = strlen(scanInfo->remote_address);
+            char *addr = OICStrdup(scanInfo->remote_address);
+            if (NULL == addr)
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Device address is NULL");
+                return;
+            }
+            serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
+            if (NULL == serverInfo)
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Calloc failed");
+                OICFree(addr);
+                return;
+            }
+            serverInfo->remoteAddress = addr;
+            serverInfo->status = LE_STATUS_DISCOVERED;
 
-    char *addr = (char *)OICMalloc(sizeof(char) * (len + 1));
-    VERIFY_NON_NULL_VOID(addr, TAG, "Malloc failed");
+            if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", scanInfo->remote_address);
+                CAFreeLEServerInfo(serverInfo);
+                return;
+            }
 
-    strncpy(addr, scanInfo->remote_address, len + 1);
+            if (!CALEIsHaveService(scanInfo, CA_GATT_SERVICE_UUID))
+            {
+                serverInfo->status = LE_STATUS_INVALID;
+                OIC_LOG_V(DEBUG, TAG, "Device [%s] does not support OIC service", serverInfo->remoteAddress);
+                oc_mutex_unlock(g_LEServerListMutex);
+                return;
+            }
 
-    OIC_LOG_V(DEBUG, TAG,
-              "Trying to do Gatt connection to [%s]", addr);
+            oc_mutex_lock(g_multicastDataListMutex);
+            uint32_t lengthData = u_arraylist_length(g_multicastDataList);
+            for (uint32_t len = 0; len < lengthData; ++len)
+            {
+                LEData *multicastData = (LEData *)u_arraylist_get(g_multicastDataList, len);
+                if (NULL == multicastData)
+                {
+                    OIC_LOG(ERROR, TAG, "multicastData is NULL");
+                    continue;
+                }
+                if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList,
+                                                      multicastData->data, multicastData->dataLength))
+                {
+                    OIC_LOG(ERROR, TAG, "Failed to add to pending list");
+                    continue;
+                }
+            }
+            oc_mutex_unlock(g_multicastDataListMutex);
+        }
 
-    oc_mutex_lock(g_LEClientThreadPoolMutex);
-    if (NULL == g_LEClientThreadPool)
-    {
-        OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
-        OICFree(addr);
-        oc_mutex_unlock(g_LEClientThreadPoolMutex);
-        return;
+        if (serverInfo->status == LE_STATUS_DISCOVERED)
+        {
+            // Initiate connection if not yet initiated
+            serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
+            if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
+            {
+                OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
+                serverInfo->status = LE_STATUS_DISCOVERED;
+            }
+        }
+        else
+        {
+            OIC_LOG_V(DEBUG, TAG, "Device already discovered, status= [%d]", serverInfo->status);
+        }
     }
 
-    CAResult_t res = ca_thread_pool_add_task(g_LEClientThreadPool, CAGattConnectThread, addr, NULL);
-    if (CA_STATUS_OK != res)
-    {
-        OIC_LOG_V(ERROR, TAG,
-                  "ca_thread_pool_add_task failed with ret [%d]", res);
-        OICFree(addr);
-    }
-    oc_mutex_unlock(g_LEClientThreadPoolMutex);
+    oc_mutex_unlock(g_LEServerListMutex);
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -502,22 +648,16 @@ void CAStartTimerThread(void *data)
     OIC_LOG(DEBUG, TAG, "IN");
     while (g_isLEGattClientStarted)
     {
-        oc_mutex_lock(g_multicastDataListMutex);
-        if (!g_isMulticastInProgress)
+        oc_mutex_lock(g_scanMutex);
+        if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
         {
             OIC_LOG(DEBUG, TAG, "waiting....");
-            oc_cond_wait(g_startTimerCond, g_multicastDataListMutex);
+            oc_cond_wait(g_startTimerCond, g_scanMutex);
             OIC_LOG(DEBUG, TAG, "Wake up");
-            g_isMulticastInProgress = true;
-
-            if (!g_isLEGattClientStarted)
-            {
-               break;
-            }
         }
 
         // Timed conditional wait for stopping the scan.
-        OCWaitResult_t ret = oc_cond_wait_for(g_scanningTimeCond, g_multicastDataListMutex,
+        OCWaitResult_t ret = oc_cond_wait_for(g_scanningTimeCond, g_scanMutex,
                                               TIMEOUT);
         if (OC_WAIT_TIMEDOUT == ret)
         {
@@ -525,18 +665,18 @@ void CAStartTimerThread(void *data)
             // Call stop scan.
             CALEGattStopDeviceScanning();
 
-            // Clear the data list and device list.
-            u_arraylist_destroy(g_multicastDataList);
-            g_multicastDataList = NULL;
-
-            oc_mutex_lock(g_deviceDiscoveredListMutex);
-            u_arraylist_destroy(g_deviceDiscoveredList);
-            g_deviceDiscoveredList = NULL;
-            oc_mutex_unlock(g_deviceDiscoveredListMutex);
-
-            g_isMulticastInProgress = false;
+            if (g_isMulticastInProgress)
+            {
+                oc_mutex_lock(g_multicastDataListMutex);
+                // Clear the data list and device list.
+                u_arraylist_destroy(g_multicastDataList);
+                g_multicastDataList = NULL;
+                oc_mutex_unlock(g_multicastDataListMutex);
+                g_isMulticastInProgress = false;
+            }
+            g_isUnicastScanInProgress = false;
         }
-        oc_mutex_unlock(g_multicastDataListMutex);
+        oc_mutex_unlock(g_scanMutex);
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -559,8 +699,6 @@ void CAStopLEGattClient()
 
     CALEGattStopDeviceScanning();
 
-    // this flag should be set before signal g_startTimerCond.
-    // since scan thread can be stopped through this flag.
     g_isLEGattClientStarted = false;
 
     // Signal the conditions waiting in Start timer.
@@ -576,14 +714,6 @@ void CAStopLEGattClient()
         oc_mutex_unlock(g_multicastDataListMutex);
     }
 
-    if (NULL != g_deviceDiscoveredList)
-    {
-        oc_mutex_lock(g_deviceDiscoveredListMutex);
-        u_arraylist_destroy(g_deviceDiscoveredList);
-        g_deviceDiscoveredList = NULL;
-        oc_mutex_unlock(g_deviceDiscoveredListMutex);
-    }
-
     oc_mutex_lock(g_LEServerListMutex);
     CAFreeLEServerList(g_LEServerList);
     g_LEServerList = NULL;
@@ -593,8 +723,6 @@ void CAStopLEGattClient()
     oc_cond_signal(g_threadWriteCharacteristicCond);
     oc_mutex_unlock(g_threadWriteCharacteristicMutex);
 
-    CAResetRegisteredServiceCount();
-
     GMainContext  *context_event_loop = NULL;
     // Required for waking up the thread which is running in gmain loop
     if (NULL != g_eventLoop)
@@ -694,6 +822,26 @@ CAResult_t CAInitGattClientMutexVariables()
         }
     }
 
+    if (NULL == g_isScanningInProgressMutex)
+    {
+        g_isScanningInProgressMutex = oc_mutex_new();
+        if (NULL == g_isScanningInProgressMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_isConnectionInProgressMutex)
+    {
+        g_isConnectionInProgressMutex = oc_mutex_new();
+        if (NULL == g_isConnectionInProgressMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
     if (NULL == g_multicastDataListMutex)
     {
         g_multicastDataListMutex = oc_mutex_new();
@@ -704,10 +852,10 @@ CAResult_t CAInitGattClientMutexVariables()
         }
     }
 
-    if (NULL == g_deviceDiscoveredListMutex)
+    if (NULL == g_scanMutex)
     {
-        g_deviceDiscoveredListMutex = oc_mutex_new();
-        if (NULL == g_deviceDiscoveredListMutex)
+        g_scanMutex = oc_mutex_new();
+        if (NULL == g_scanMutex)
         {
             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
@@ -777,11 +925,17 @@ void CATerminateGattClientMutexVariables()
     oc_mutex_free(g_LEClientThreadPoolMutex);
     g_LEClientThreadPoolMutex = NULL;
 
+    oc_mutex_free(g_isScanningInProgressMutex);
+    g_isScanningInProgressMutex = NULL;
+
+    oc_mutex_free(g_isConnectionInProgressMutex);
+    g_isConnectionInProgressMutex = NULL;
+
     oc_mutex_free(g_multicastDataListMutex);
     g_multicastDataListMutex = NULL;
 
-    oc_mutex_free(g_deviceDiscoveredListMutex);
-    g_deviceDiscoveredListMutex = NULL;
+    oc_mutex_free(g_scanMutex);
+    g_scanMutex = NULL;
 
     oc_mutex_free(g_threadWriteCharacteristicMutex);
     g_threadWriteCharacteristicMutex = NULL;
@@ -811,14 +965,21 @@ void CALEGattUnSetCallbacks()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    int numOfServersConnected = CAGetRegisteredServiceCount();
-    LEServerInfo *leServerInfo = NULL;
+    bt_gatt_unset_connection_state_changed_cb();
 
-    for (int32_t index = 0; index < numOfServersConnected; index++)
+    oc_mutex_lock(g_LEServerListMutex);
+    LEServerInfoList *curNode = g_LEServerList;
+    while (curNode)
     {
-        CAGetLEServerInfoByPosition(g_LEServerList, index, &leServerInfo);
-        bt_gatt_client_unset_characteristic_value_changed_cb(leServerInfo->readChar);
+        LEServerInfo *serverInfo = curNode->serverInfo;
+        if (serverInfo->status >= LE_STATUS_SERVICES_DISCOVERED)
+        {
+            bt_gatt_client_unset_characteristic_value_changed_cb(serverInfo->readChar);
+        }
+        curNode = curNode->next;
     }
+    oc_mutex_unlock(g_LEServerListMutex);
+
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -826,13 +987,24 @@ CAResult_t CALEGattStartDeviceScanning()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    int ret = bt_adapter_le_start_scan(CALEAdapterScanResultCb, NULL);
-    if(BT_ERROR_NONE != ret)
+    oc_mutex_lock(g_isScanningInProgressMutex);
+    if (!g_isScanningInProgress)
     {
-        OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_scan failed[%s]",
-                  CALEGetErrorMsg(ret));
-        return CA_STATUS_FAILED;
+        int ret = bt_adapter_le_start_scan(CALEAdapterScanResultCb, NULL);
+        if (BT_ERROR_NONE != ret)
+        {
+            oc_mutex_unlock(g_isScanningInProgressMutex);
+            OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_scan failed[%s]",
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+        g_isScanningInProgress = true;
     }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "Ignore, scanning already in progress");
+    }
+    oc_mutex_unlock(g_isScanningInProgressMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -842,12 +1014,24 @@ void CALEGattStopDeviceScanning()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    int ret = bt_adapter_le_stop_scan();
-    if (BT_ERROR_NONE != ret)
+    oc_mutex_lock(g_isScanningInProgressMutex);
+    if (g_isScanningInProgress)
     {
-        OIC_LOG_V(ERROR, TAG, "bt_adapter_le_stop_scan failed[%s]",
-                  CALEGetErrorMsg(ret));
+        int ret = bt_adapter_le_stop_scan();
+        if (BT_ERROR_NONE != ret)
+        {
+            oc_mutex_unlock(g_isScanningInProgressMutex);
+            OIC_LOG_V(ERROR, TAG, "bt_adapter_le_stop_scan failed[%s]",
+                      CALEGetErrorMsg(ret));
+            return;
+        }
+        g_isScanningInProgress = false;
     }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "Ignore, scanning not in progress");
+    }
+    oc_mutex_unlock(g_isScanningInProgressMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -882,60 +1066,17 @@ CAResult_t CALEGattConnect(const char *remoteAddress)
                         "remote address is NULL", CA_STATUS_FAILED);
 
     oc_mutex_lock(g_LEClientConnectMutex);
-    bool isConnected = false;
-    int ret = bt_device_is_profile_connected(remoteAddress, BT_PROFILE_GATT, &isConnected);
+    CAResult_t result = CA_STATUS_OK;
+
+    int ret = bt_gatt_connect(remoteAddress, false);
     if (BT_ERROR_NONE != ret)
     {
-        OIC_LOG_V(ERROR, TAG, "bt_device_is_profile_connected Failed with ret value [%s] ",
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_connect Failed with ret value [%s] ",
                   CALEGetErrorMsg(ret));
         oc_mutex_unlock(g_LEClientConnectMutex);
         return CA_STATUS_FAILED;
     }
 
-    CAResult_t result = CA_STATUS_OK;
-    if (!isConnected)
-    {
-        ret = bt_gatt_connect(remoteAddress, true);
-
-        if (BT_ERROR_NONE != ret)
-        {
-            OIC_LOG_V(ERROR, TAG, "bt_gatt_connect Failed with ret value [%s] ",
-                      CALEGetErrorMsg(ret));
-            oc_mutex_unlock(g_LEClientConnectMutex);
-            return CA_STATUS_FAILED;
-        }
-    }
-    else
-    {
-        OIC_LOG_V(INFO, TAG, "Remote address[%s] is already connected",
-                  remoteAddress);
-        char *addr = OICStrdup(remoteAddress);
-        if (NULL == addr)
-        {
-            OIC_LOG(ERROR, TAG, "addr is NULL");
-            oc_mutex_unlock(g_LEClientConnectMutex);
-            return CA_STATUS_FAILED;
-        }
-
-        oc_mutex_lock(g_LEClientThreadPoolMutex);
-        if (NULL == g_LEClientThreadPool)
-        {
-            OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
-            OICFree(addr);
-            oc_mutex_unlock(g_LEClientThreadPoolMutex);
-            oc_mutex_unlock(g_LEClientConnectMutex);
-            return CA_STATUS_FAILED;
-        }
-
-        result = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
-                                         addr, NULL);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", result);
-            OICFree(addr);
-        }
-        oc_mutex_unlock(g_LEClientThreadPoolMutex);
-    }
     oc_mutex_unlock(g_LEClientConnectMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -962,7 +1103,86 @@ CAResult_t CALEGattDisConnect(const char *remoteAddress)
     return CA_STATUS_OK;
 }
 
-void CADiscoverLEServicesThread (void *remoteAddress)
+CAResult_t CAUpdateCharacteristicsToGattServerImpl(LEServerInfo *serverInfo,
+        const uint8_t *data, const uint32_t dataLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(serverInfo, TAG, "Server Info is NULL");
+
+    CALEGattStopDeviceScanning();
+
+    OIC_LOG_V(DEBUG, TAG, "Updating the data of length [%d] to [%s] ", dataLen,
+              serverInfo->remoteAddress);
+
+    int result = bt_gatt_set_value(serverInfo->writeChar, (char *)data, dataLen);
+
+    if (BT_ERROR_NONE != result)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_set_value Failed with return val [%s]",
+                  CALEGetErrorMsg(result));
+        goto exit;
+    }
+
+    result = bt_gatt_client_write_value(serverInfo->writeChar, CALEGattCharacteristicWriteCb,
+                                        NULL);
+    if (BT_ERROR_NONE != result)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_client_write_value Failed with return val [%s]",
+                  CALEGetErrorMsg(result));
+        goto exit;
+    }
+
+    // wait for callback for write Characteristic with success to sent data
+    OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
+    oc_mutex_lock(g_threadWriteCharacteristicMutex);
+    if (!g_isSignalSetFlag)
+    {
+        OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
+        if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
+                                                g_threadWriteCharacteristicMutex,
+                                                WAIT_TIME_WRITE_CHARACTERISTIC))
+        {
+            g_isSignalSetFlag = false;
+            oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+            OIC_LOG(ERROR, TAG, "there is no response. write has failed");
+            goto exit;
+        }
+    }
+    // reset flag set by writeCharacteristic Callback
+    g_isSignalSetFlag = false;
+    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+    oc_mutex_lock(g_scanMutex);
+    if (g_isMulticastInProgress || g_isUnicastScanInProgress)
+    {
+        if (CA_STATUS_OK != CALEGattStartDeviceScanning())
+        {
+            OIC_LOG(ERROR, TAG, "Could not start device scanning");
+        }
+    }
+    oc_mutex_unlock(g_scanMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+
+exit:
+    oc_mutex_lock(g_scanMutex);
+    if (g_isMulticastInProgress || g_isUnicastScanInProgress)
+    {
+        if (CA_STATUS_OK != CALEGattStartDeviceScanning())
+        {
+            OIC_LOG(ERROR, TAG, "Could not start device scanning");
+        }
+    }
+    oc_mutex_unlock(g_scanMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_FAILED;
+}
+
+void CADiscoverLEServicesThread(void *remoteAddress)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -987,50 +1207,13 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
     VERIFY_NON_NULL_RET(remoteAddress, TAG,
                         "remote address is NULL", CA_STATUS_FAILED);
 
-    LEServerInfo *leServerInfo = NULL;
-    CAResult_t result =  CA_STATUS_FAILED;
-
-    oc_mutex_lock(g_LEServerListMutex);
-    result = CAGetLEServerInfo(g_LEServerList, remoteAddress, &leServerInfo);
-    oc_mutex_unlock(g_LEServerListMutex);
-
-    if (CA_STATUS_OK == result)
-    {
-        OIC_LOG_V(INFO, TAG, "Device[%s] is already discovered", leServerInfo->remoteAddress);
-
-        // Send the data of pending multicast data list if any.
-        if (g_multicastDataList)
-        {
-            oc_mutex_lock(g_multicastDataListMutex);
-            uint32_t arrayLength = u_arraylist_length(g_multicastDataList);
-            for (uint32_t i = 0; i < arrayLength; i++)
-            {
-                CALEData_t *multicastData = u_arraylist_get(g_multicastDataList, i);
-                if (NULL == multicastData)
-                {
-                    OIC_LOG(DEBUG, TAG, "multicastData is NULL");
-                    continue;
-                }
-                CAUpdateCharacteristicsToGattServer(remoteAddress, multicastData->data,
-                                                    multicastData->dataLen, LE_UNICAST, 0);
-            }
-            oc_mutex_unlock(g_multicastDataListMutex);
-        }
-
-        OIC_LOG(DEBUG, TAG, "OUT");
-        return CA_STATUS_OK;
-    }
-    else
-    {
-        OIC_LOG_V(INFO, TAG, "CAGetLEServerInfo [%s] is failed, %d", remoteAddress, result);
-    }
-
     bt_gatt_client_h clientHandle = NULL;
     int32_t ret = bt_gatt_client_create(remoteAddress, &clientHandle);
     if (BT_ERROR_NONE != ret || NULL == clientHandle)
     {
         OIC_LOG_V(ERROR, TAG,
                   "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
+        CALEGattDisConnect(remoteAddress);
         return CA_STATUS_FAILED;
     }
 
@@ -1041,13 +1224,14 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
         OIC_LOG_V(ERROR, TAG,
                   "bt_gatt_client_get_service Failed with ret value [%s] ", CALEGetErrorMsg(ret));
         bt_gatt_client_destroy(clientHandle);
+        CALEGattDisConnect(remoteAddress);
         return CA_STATUS_FAILED;
     }
 
     // Server will read data on this characteristic.
     bt_gatt_h writeChrHandle = NULL;
     ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_REQUEST_CHRC_UUID,
-                                             &writeChrHandle);
+            &writeChrHandle);
     if (BT_ERROR_NONE != ret || NULL == writeChrHandle)
     {
         OIC_LOG_V(ERROR, TAG,
@@ -1061,7 +1245,7 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
     // Server will notify data on this characteristic.
     bt_gatt_h readChrHandle = NULL;
     ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_RESPONSE_CHRC_UUID,
-                                             &readChrHandle);
+            &readChrHandle);
     if (BT_ERROR_NONE != ret || NULL == readChrHandle)
     {
         OIC_LOG_V(ERROR, TAG,
@@ -1084,8 +1268,8 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
     }
 
     ret = bt_gatt_client_set_characteristic_value_changed_cb(readChrHandle,
-                                                             CALEGattCharacteristicChangedCb,
-                                                             (void *)addr);
+            CALEGattCharacteristicChangedCb,
+            (void *)addr);
     if (BT_ERROR_NONE != ret)
     {
         OIC_LOG_V(ERROR, TAG,
@@ -1096,72 +1280,46 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
         return CA_STATUS_FAILED;
     }
 
-    LEServerInfo *serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
-    if (NULL == serverInfo)
-    {
-        OIC_LOG(ERROR, TAG, "Malloc failed");
-        CALEGattDisConnect(remoteAddress);
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-    serverInfo->clientHandle = clientHandle;
-    serverInfo->serviceHandle = serviceHandle;
-    serverInfo->readChar = readChrHandle;
-    serverInfo->writeChar = writeChrHandle;
-    serverInfo->remoteAddress = OICStrdup(remoteAddress);
-
+    LEServerInfo *serverInfo = NULL;
     oc_mutex_lock(g_LEServerListMutex);
-    result = CAAddLEServerInfoToList(&g_LEServerList, serverInfo);
-    if (CA_STATUS_OK != result)
+    if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
     {
-        OIC_LOG(ERROR, TAG, "CAAddLEServerInfoToList failed");
+        oc_mutex_unlock(g_LEServerListMutex);
+        OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
         bt_gatt_client_destroy(clientHandle);
         CALEGattDisConnect(remoteAddress);
         return CA_STATUS_FAILED;
     }
-    oc_mutex_unlock(g_LEServerListMutex);
 
-    oc_mutex_lock(g_deviceDiscoveredListMutex);
-    // Add the the device Discovered list.
-    if (NULL == g_deviceDiscoveredList)
-    {
-        g_deviceDiscoveredList = u_arraylist_create();
-    }
-    char *deviceAddr = OICStrdup(remoteAddress);
-    if (NULL == deviceAddr)
-    {
-        OIC_LOG_V(ERROR, TAG, "Device address is NULL");
-        oc_mutex_unlock(g_deviceDiscoveredListMutex);
-        return CA_STATUS_FAILED;
-    }
-    u_arraylist_add(g_deviceDiscoveredList, (void *) deviceAddr);
-    oc_mutex_unlock(g_deviceDiscoveredListMutex);
+    serverInfo->clientHandle = clientHandle;
+    serverInfo->serviceHandle = serviceHandle;
+    serverInfo->readChar = readChrHandle;
+    serverInfo->writeChar = writeChrHandle;
+    serverInfo->status = LE_STATUS_SERVICES_DISCOVERED;
 
-    // Send the data of pending multicast data list if any.
-    if (g_multicastDataList)
+    while (serverInfo->pendingDataList)
     {
-        oc_mutex_lock(g_multicastDataListMutex);
-        uint32_t arrayLength = u_arraylist_length(g_multicastDataList);
-        for (uint32_t i = 0; i < arrayLength; i++)
+        LEData *leData = serverInfo->pendingDataList->data;
+        if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(
+                serverInfo, leData->data, leData->dataLength))
         {
-            CALEData_t *multicastData = u_arraylist_get(g_multicastDataList, i);
-            if (NULL == multicastData)
-            {
-                OIC_LOG(DEBUG, TAG, "multicastData is NULL");
-                continue;
-            }
-            CAUpdateCharacteristicsToGattServer(remoteAddress, multicastData->data,
-                                                multicastData->dataLen, LE_UNICAST, 0);
+            OIC_LOG_V(ERROR, TAG, "Failed to send pending data to [%s]",
+                      serverInfo->remoteAddress);
+
+            CADestroyLEDataList(&serverInfo->pendingDataList);
+            break;
         }
-        oc_mutex_unlock(g_multicastDataListMutex);
+        CARemoveLEDataFromList(&serverInfo->pendingDataList);
     }
+    oc_mutex_unlock(g_LEServerListMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
-                                                const uint8_t *data, const uint32_t dataLen,
-                                                CALETransferType_t type, const int32_t position)
+CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
+        const uint8_t *data, const uint32_t dataLen,
+        CALETransferType_t type, const int32_t position)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -1173,71 +1331,123 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
         return CA_STATUS_INVALID_PARAM;
     }
 
-    LEServerInfo *leServerInfo = NULL;
-    CAResult_t ret =  CA_STATUS_FAILED;
-
+    LEServerInfo *serverInfo = NULL;
     oc_mutex_lock(g_LEServerListMutex);
     if (LE_UNICAST == type)
     {
-        ret = CAGetLEServerInfo(g_LEServerList, remoteAddress, &leServerInfo);
-    }
-    else if (LE_MULTICAST == type)
-    {
-        ret = CAGetLEServerInfoByPosition(g_LEServerList, position, &leServerInfo);
-    }
-    oc_mutex_unlock(g_LEServerListMutex);
+        if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
+        {
+            OIC_LOG_V(DEBUG, TAG,
+                      "Device with address [%s] not yet found, initiating scan",
+                      remoteAddress);
 
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, TAG, "CAGetBLEServiceInfoByPosition is failed");
-        return CA_STATUS_FAILED;
-    }
+            char *addr = OICStrdup(remoteAddress);
+            if (NULL == addr)
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Device address is NULL");
+                return CA_STATUS_FAILED;
+            }
 
-    VERIFY_NON_NULL(leServerInfo, TAG, "bleServiceInfo is NULL");
+            serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
+            if (NULL == serverInfo)
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Calloc failed");
+                OICFree(addr);
+                return CA_STATUS_FAILED;
+            }
 
-    OIC_LOG_V(DEBUG, TAG, "Updating the data of length [%d] to [%s] ", dataLen,
-              leServerInfo->remoteAddress);
+            serverInfo->remoteAddress = addr;
+            serverInfo->status = LE_STATUS_UNICAST_PENDING;
 
-    int result = bt_gatt_set_value(leServerInfo->writeChar, (char *)data, dataLen);
+            if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", serverInfo->remoteAddress);
+                CAFreeLEServerInfo(serverInfo);
+                return CA_STATUS_FAILED;
+            }
 
-    if (BT_ERROR_NONE != result)
-    {
-        OIC_LOG_V(ERROR, TAG,
-                  "bt_gatt_set_value Failed with return val [%s]",
-                  CALEGetErrorMsg(result));
-        return CA_STATUS_FAILED;
-    }
+            if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Could not add data to pending list");
+                return CA_STATUS_FAILED;
+            }
 
-    result = bt_gatt_client_write_value(leServerInfo->writeChar, CALEGattCharacteristicWriteCb,
-                                        NULL);
-    if (BT_ERROR_NONE != result)
-    {
-        OIC_LOG_V(ERROR, TAG,
-                  "bt_gatt_client_write_value Failed with return val [%s]",
-                  CALEGetErrorMsg(result));
-        return CA_STATUS_FAILED;
-    }
+            oc_mutex_unlock(g_LEServerListMutex);
 
-    // wait for callback for write Characteristic with success to sent data
-    OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
-    oc_mutex_lock(g_threadWriteCharacteristicMutex);
-    if (!g_isSignalSetFlag)
-    {
-        OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
-        if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
-                                  g_threadWriteCharacteristicMutex,
-                                  WAIT_TIME_WRITE_CHARACTERISTIC))
+            oc_mutex_lock(g_scanMutex);
+            if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
+            {
+                CAResult_t result = CALEGattStartDeviceScanning();
+                if (CA_STATUS_OK != result)
+                {
+                    oc_mutex_unlock(g_scanMutex);
+                    OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning failed");
+                    return CA_STATUS_FAILED;
+                }
+                g_isUnicastScanInProgress = true;
+                // Start Timer
+                oc_cond_signal(g_startTimerCond);
+            }
+            else
+            {
+                g_isUnicastScanInProgress = true;
+                // Reset Timer
+                oc_cond_signal(g_scanningTimeCond);
+            }
+            oc_mutex_unlock(g_scanMutex);
+
+            OIC_LOG(DEBUG, TAG, "OUT");
+            return CA_STATUS_OK;
+        }
+
+        if (serverInfo->status == LE_STATUS_DISCOVERED)
         {
-            OIC_LOG(ERROR, TAG, "there is no response. write has failed");
-            g_isSignalSetFlag = false;
-            oc_mutex_unlock(g_threadWriteCharacteristicMutex);
-            return CA_SEND_FAILED;
+            if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Could not add data to pending list");
+                return CA_STATUS_FAILED;
+            }
+
+            serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
+            if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
+            {
+                OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
+                serverInfo->status = LE_STATUS_DISCOVERED;
+                CADestroyLEDataList(&serverInfo->pendingDataList);
+                oc_mutex_unlock(g_LEServerListMutex);
+                return CA_STATUS_FAILED;
+            }
+        }
+        else if (serverInfo->status < LE_STATUS_SERVICES_DISCOVERED)
+        {
+            if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Could not add data to pending list");
+                return CA_STATUS_FAILED;
+            }
+        }
+        else
+        {
+            if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
+            {
+                OIC_LOG_V(ERROR, TAG, "Could not update characteristic to gatt server [%s]",
+                          serverInfo->remoteAddress);
+                oc_mutex_unlock(g_LEServerListMutex);
+                return CA_STATUS_FAILED;
+            }
         }
     }
-    // reset flag set by writeCharacteristic Callback
-    g_isSignalSetFlag = false;
-    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
-
+    else if (LE_MULTICAST == type)
+    {
+        OIC_LOG(ERROR, TAG, "LE_MULTICAST type Not used");
+    }
+    oc_mutex_unlock(g_LEServerListMutex);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -1254,26 +1464,32 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t
         return CA_STATUS_INVALID_PARAM;
     }
 
-    int numOfServersConnected = CAGetRegisteredServiceCount();
-
-    // Send data to already connected devices.
-    for (int32_t pos = 0; pos < numOfServersConnected; pos++)
+    oc_mutex_lock(g_LEServerListMutex);
+    LEServerInfoList *curNode = g_LEServerList;
+    while (curNode)
     {
-        /*remoteAddress will be NULL.
-          Since we have to send to all destinations. pos will be used for getting remote address.
-         */
-        int32_t ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, LE_MULTICAST, pos);
-
-        if (CA_STATUS_OK != ret)
+        LEServerInfo *serverInfo = curNode->serverInfo;
+        if (serverInfo->status == LE_STATUS_SERVICES_DISCOVERED)
         {
-            OIC_LOG_V(ERROR, TAG,
-                      "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret);
-            g_clientErrorCallback(NULL, data, dataLen, ret);
+            if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
+            {
+                OIC_LOG_V(ERROR, TAG, "Failed to update characteristics to gatt server [%s]",
+                          serverInfo->remoteAddress);
+            }
         }
+        else if (serverInfo->status != LE_STATUS_INVALID)
+        {
+            if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
+            {
+                OIC_LOG(ERROR, TAG, "Failed to add to pending list");
+            }
+        }
+        curNode = curNode->next;
     }
+    oc_mutex_unlock(g_LEServerListMutex);
 
     // Add the data to pending list.
-    CALEData_t *multicastData = (CALEData_t *)OICCalloc(1, sizeof(CALEData_t));
+    LEData *multicastData = (LEData *)OICCalloc(1, sizeof(LEData));
     if (NULL == multicastData)
     {
         OIC_LOG(ERROR, TAG, "Calloc failed");
@@ -1286,7 +1502,7 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t
         goto exit;
     }
     memcpy(multicastData->data, data, dataLen);
-    multicastData->dataLen = dataLen;
+    multicastData->dataLength = dataLen;
 
     oc_mutex_lock(g_multicastDataListMutex);
     if (NULL == g_multicastDataList)
@@ -1296,51 +1512,30 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t
     u_arraylist_add(g_multicastDataList, (void *)multicastData);
     oc_mutex_unlock(g_multicastDataListMutex);
 
-    // Start the scanning.
-    CAResult_t result = CALEGattStartDeviceScanning();
-    if (CA_STATUS_OK != result)
+    // Start the scanning, if not started, else reset timer
+    oc_mutex_lock(g_scanMutex);
+    if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
     {
-        OIC_LOG(ERROR, TAG, "CALEGattStartDeviceDiscovery Failed");
-        goto exit;
+        CAResult_t result = CALEGattStartDeviceScanning();
+        if (CA_STATUS_OK != result)
+        {
+            oc_mutex_unlock(g_scanMutex);
+            OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning Failed");
+            goto exit;
+        }
+        g_isMulticastInProgress = true;
+        // Start the timer by signalling it
+        oc_cond_signal(g_startTimerCond);
     }
-
-    // Start the timer by signalling it.
-    oc_cond_signal(g_startTimerCond);
+    else
+    {
+        g_isMulticastInProgress = true;
+        // Reset timer
+        oc_cond_signal(g_scanningTimeCond);
+    }
+    oc_mutex_unlock(g_scanMutex);
 
 exit:
     OIC_LOG(DEBUG, TAG, "OUT ");
     return CA_STATUS_OK;
 }
-
-bool CALEClientIsConnected(const char* address)
-{
-    (void)address;
-    //@Todo
-    return true;
-}
-
-uint16_t CALEClientGetMtuSize(const char* address)
-{
-    VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
-    //@Todo
-    //it should be implemented after update Tizen 3.0
-    return CA_DEFAULT_BLE_MTU_SIZE;
-}
-
-CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize)
-{
-    (void)mtuSize;
-
-    VERIFY_NON_NULL(address, TAG, "address is null");
-    //@Todo
-    //it should be implemented after update Tizen 3.0
-    return CA_NOT_SUPPORTED;
-}
-
-CAResult_t CALEClientSendNegotiationMessage(const char* address)
-{
-    OIC_LOG_V(DEBUG, TAG, "CALEClientSendNegotiationMessage(%s)", address);
-    //@Todo
-    //it will be implemented when tizen public 3.0 is released.
-    return CA_NOT_SUPPORTED;
-}
index 1b5bfc0..9c74caf 100644 (file)
@@ -27,6 +27,7 @@
 #include "oic_string.h"
 #include "oic_malloc.h"
 #include "caleutil.h"
+#include <glib.h>
 
 /**
  * Logging tag for module name
@@ -163,7 +164,7 @@ void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddr
     }
 }
 
-void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
+void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
                                   bt_gatt_h characteristic, bool completed, void *user_data)
 {
     OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
@@ -648,8 +649,9 @@ CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
     return CA_STATUS_OK;
 }
 
-void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
-                                         bt_gatt_h charPath, int offset, char *charValue,
+void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
+                                         bt_gatt_server_h server, bt_gatt_h charPath,
+                                         bool response_needed, int offset, const char *charValue,
                                          int charValueLen, void *userData)
 {
     OIC_LOG(INFO, TAG, "IN - WriteCharCB");
@@ -687,6 +689,16 @@ void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h s
                                     &sentLength);
     oc_mutex_unlock(g_leReqRespCbMutex);
     OICFree(data);
+
+    OIC_LOG_V(INFO, TAG, "response needed flag: %d", response_needed);
+    if (response_needed)
+    {
+        OIC_LOG(INFO, TAG, "send response to remote client");
+        bt_gatt_server_send_response(request_id,
+                                     BT_GATT_REQUEST_TYPE_WRITE, offset,
+                                     BT_ERROR_NONE, NULL, 0);
+    }
+
     OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
 }
 
@@ -706,12 +718,20 @@ CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
         return CA_STATUS_FAILED;
     }
 
-    ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
-                                              CALEGattRemoteCharacteristicWriteCb, NULL);
+    ret = bt_gatt_server_start();
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
+                                                      CALEGattRemoteCharacteristicWriteCb, NULL);
 
     if (0 != ret)
     {
-        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_write_value_requested_cb failed with ret[%s]",
                   CALEGetErrorMsg(ret));
         return CA_STATUS_FAILED;
     }
@@ -754,11 +774,13 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
 
     if (read)
     {
-        ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
+        ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
+                                                                             CALENotificationCb,
+                                                                             NULL);
         if (0 != ret)
         {
             OIC_LOG_V(ERROR, TAG,
-                      "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
+                      "bt_gatt_server_set_characteristic_notification_state_change_cb  failed with ret[%s]",
                       CALEGetErrorMsg(ret));
             return CA_STATUS_FAILED;
         }
@@ -843,12 +865,13 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_
         return CA_STATUS_FAILED;
     }
 
-    ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
-                                NULL);
+    ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
+                                                             CALEServerNotificationSentCB,
+                                                             address, NULL);
     if (0 != ret)
     {
         OIC_LOG_V(ERROR, TAG,
-                  "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
+                  "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]", CALEGetErrorMsg(ret));
         oc_mutex_unlock(g_leCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
@@ -882,12 +905,13 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uin
         return CA_STATUS_FAILED;
     }
 
-    ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
-                                NULL);
+    ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
+                                                             CALEServerNotificationSentCB,
+                                                             NULL, NULL);
     if (0 != ret)
     {
         OIC_LOG_V(ERROR, TAG,
-                  "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
+                  "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]", CALEGetErrorMsg(ret));
         oc_mutex_unlock(g_leCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
@@ -930,4 +954,3 @@ uint16_t CALEServerGetMtuSize(const char* address)
             "bt_device_get_att_mtu is not supported");
     return CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE;
 }
-
index bc96a97..19b38c9 100644 (file)
@@ -181,16 +181,10 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
  * @param[in] len            The length of @a value
  * @param[in] user_data      The user data passed from the registration function
  */
-#ifdef BLE_TIZEN_30
 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
                                          bt_gatt_server_h server, bt_gatt_h gatt_handle,
                                          bool response_needed, int offset, const char *charValue,
                                          int charLen, void *userData);
-#else
-void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
-                                         bt_gatt_h gatt_handle, int offset, char *charValue,
-                                         int charLen, void *userData);
-#endif
 
 /**
  * Setting the connection state changed callback.
index d64c925..a4c4561 100644 (file)
  */
 static int32_t g_numberOfServiceConnected = 0;
 
-void CAIncrementRegisteredServiceCount()
+/*void CAIncrementRegisteredServiceCount()
 {
     g_numberOfServiceConnected++;
+}*/
+
+CAResult_t CAAddLEDataToList(LEDataList **dataList, const void *data, uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(dataList, TAG, "Data list is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    if (0 == dataLength)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid input: data length is zero!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    LEDataList *pending_data = (LEDataList *) OICMalloc(sizeof(LEDataList));
+    if (NULL == pending_data)
+    {
+        OIC_LOG(ERROR, TAG, "OICMalloc failed (data list)!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    pending_data->data = (LEData *) OICMalloc(sizeof(LEData));
+    if (NULL == pending_data->data)
+    {
+        OIC_LOG(ERROR, TAG, "OICMalloc failed (data node)!");
+        OICFree(pending_data);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    pending_data->next = NULL;
+    pending_data->data->data = (void *) OICMalloc(dataLength); //data
+    if (NULL == pending_data->data->data)
+    {
+        OIC_LOG(ERROR, TAG, "OICMalloc failed (data)!");
+        OICFree(pending_data->data);
+        OICFree(pending_data);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    memcpy(pending_data->data->data, data, dataLength);
+    pending_data->data->dataLength = dataLength;
+
+    if (NULL == *dataList)
+    {
+        *dataList = pending_data;
+    }
+    else
+    {
+        LEDataList *curNode = *dataList;
+        while (curNode->next != NULL)
+        {
+            curNode = curNode->next;
+        }
+        curNode->next = pending_data;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-void CADecrementRegisteredServiceCount()
+
+void CARemoveLEDataFromList(LEDataList **dataList)
 {
-    g_numberOfServiceConnected--;
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(dataList, TAG, "Data list is null");
+
+    if (*dataList)
+    {
+        LEDataList *curNode = *dataList;
+        *dataList = (*dataList)->next;
+
+        //Delete the first node
+        CADestroyLEData(curNode->data);
+        OICFree(curNode);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-void CAResetRegisteredServiceCount()
+void CADestroyLEDataList(LEDataList **dataList)
 {
-    g_numberOfServiceConnected = 0;
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL_VOID(dataList, TAG, "Data list is null");
+
+    while (*dataList)
+    {
+        LEDataList *curNode = *dataList;
+        *dataList = (*dataList)->next;
+
+        CADestroyLEData(curNode->data);
+        OICFree(curNode);
+    }
+
+    *dataList = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-int32_t  CAGetRegisteredServiceCount()
+void CADestroyLEData(LEData *data)
 {
-    return g_numberOfServiceConnected ;
+    if (data)
+    {
+        OICFree(data->data);
+        OICFree(data);
+    }
 }
 
 CAResult_t CAAddLEServerInfoToList(LEServerInfoList **serverList,
@@ -75,7 +168,7 @@ CAResult_t CAAddLEServerInfoToList(LEServerInfoList **serverList,
     LEServerInfoList *node = (LEServerInfoList *) OICCalloc(1, sizeof(LEServerInfoList));
     if (NULL == node)
     {
-        OIC_LOG(ERROR, TAG, "Malloc failed!");
+        OIC_LOG(ERROR, TAG, "Calloc failed!");
         return CA_STATUS_FAILED;
     }
 
@@ -92,8 +185,6 @@ CAResult_t CAAddLEServerInfoToList(LEServerInfoList **serverList,
         *serverList = node;
     }
 
-    CAIncrementRegisteredServiceCount();
-
     OIC_LOG_V(DEBUG, TAG, "Device [%s] added to list",
               leServerInfo->remoteAddress);
 
@@ -123,10 +214,8 @@ void CARemoveLEServerInfoFromList(LEServerInfoList **serverList,
             {
                 prev->next = temp->next;
             }
-            CADecrementRegisteredServiceCount();
-            bt_gatt_client_destroy(temp->serverInfo->clientHandle);
-            OICFree(temp->serverInfo->remoteAddress);
-            OICFree(temp->serverInfo);
+            
+            CAFreeLEServerInfo(temp->serverInfo);
             OICFree(temp);
             OIC_LOG_V(DEBUG, TAG, "Device [%s] removed from list", remoteAddress);
             break;
@@ -144,10 +233,15 @@ CAResult_t CAGetLEServerInfo(LEServerInfoList *serverList, const char *leAddress
 
     OIC_LOG(DEBUG, TAG, "IN");
 
-    VERIFY_NON_NULL(serverList, TAG, "clientList");
     VERIFY_NON_NULL(leServerInfo, TAG, "leClientInfo");
     VERIFY_NON_NULL(leAddress, TAG, "leAddress");
 
+    if (NULL == serverList)
+    {
+        OIC_LOG(DEBUG, TAG, "Server list is empty");
+        return CA_STATUS_FAILED;
+    }
+
     LEServerInfoList *cur = serverList;
     *leServerInfo = NULL;
     while (cur != NULL)
@@ -166,37 +260,7 @@ CAResult_t CAGetLEServerInfo(LEServerInfoList *serverList, const char *leAddress
     return CA_STATUS_FAILED;
 }
 
-CAResult_t CAGetLEServerInfoByPosition(LEServerInfoList *serverList, int32_t position,
-                                       LEServerInfo **leServerInfo)
-{
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    VERIFY_NON_NULL(serverList, TAG, "clientList");
-    VERIFY_NON_NULL(leServerInfo, TAG, "leClientInfo");
-
-    if (0 > position)
-    {
-        OIC_LOG(ERROR, TAG, "Position Invalid input !");
-        return CA_STATUS_INVALID_PARAM;
-    }
 
-    *leServerInfo = NULL;
-    int32_t count = 0;
-    LEServerInfoList *cur = serverList;
-    while (cur != NULL)
-    {
-        if (position == count)
-        {
-            *leServerInfo = cur->serverInfo;
-            OIC_LOG(DEBUG, TAG, "OUT");
-            return CA_STATUS_OK;
-        }
-        count++;
-        cur = cur->next;
-    }
-    OIC_LOG(DEBUG, TAG, "Client info not found for the position");
-    return CA_STATUS_FAILED;
-}
 
 void CAFreeLEServerList(LEServerInfoList *serverList)
 {
@@ -216,10 +280,18 @@ void CAFreeLEServerInfo(LEServerInfo *leServerInfo)
     OIC_LOG(DEBUG, TAG, "IN");
     if (leServerInfo)
     {
-        if (leServerInfo->remoteAddress)
+        if (leServerInfo->clientHandle)
         {
             bt_gatt_client_destroy(leServerInfo->clientHandle);
-            int32_t ret = bt_gatt_disconnect(leServerInfo->remoteAddress);
+        }
+
+        if (leServerInfo->pendingDataList)
+        {
+            CADestroyLEDataList(&(leServerInfo->pendingDataList));
+        }
+
+        if (leServerInfo->status > LE_STATUS_CONNECTED)
+        {    int32_t ret = bt_gatt_disconnect(leServerInfo->remoteAddress);
 
             if (BT_ERROR_NONE != ret)
             {
@@ -228,8 +300,8 @@ void CAFreeLEServerInfo(LEServerInfo *leServerInfo)
                           ret);
                 return;
             }
-            OICFree(leServerInfo->remoteAddress);
         }
+        OICFree(leServerInfo->remoteAddress);
         OICFree(leServerInfo);
     }
     OIC_LOG(DEBUG, TAG, "OUT");
index 3b3daa0..fbfc7db 100644 (file)
 
 typedef struct
 {
+    void *data;
+    uint32_t dataLength;
+} LEData;
+
+typedef struct _LEDataList
+{
+    LEData *data;
+    struct _LEDataList *next;
+} LEDataList;
+
+typedef enum
+{
+    LE_STATUS_INVALID = 0,
+    LE_STATUS_UNICAST_PENDING,
+    LE_STATUS_DISCOVERED,
+    LE_STATUS_CONNECTION_INITIATED,
+    LE_STATUS_CONNECTED,
+    LE_STATUS_SERVICES_DISCOVERED
+} LEDeviceStatus;
+
+
+typedef struct
+{
     bt_gatt_client_h clientHandle;
     bt_gatt_h serviceHandle;
     bt_gatt_h readChar;
     bt_gatt_h writeChar;
     char *remoteAddress;
+    LEDataList *pendingDataList;
+    LEDeviceStatus status;
 } LEServerInfo;
 
 typedef struct _LEServerInfoList
 {
     LEServerInfo *serverInfo;
     struct _LEServerInfoList *next;
-}LEServerInfoList;
+} LEServerInfoList;
 
 typedef struct _LEClientInfoList
 {
@@ -73,24 +98,23 @@ typedef enum
 /**
  * Used to increment the registered service count.
  */
-void CAIncrementRegisteredServiceCount();
-
+CAResult_t CAAddLEDataToList(LEDataList **dataList, const void *data, uint32_t dataLength);
 /**
  * Used to decrement the registered service count.
  */
-void CADecrementRegisteredServiceCount();
 
+void CARemoveLEDataFromList(LEDataList **dataList);
 /**
  * Used to reset the registered service count.
  */
-void CAResetRegisteredServiceCount();
 
+void CADestroyLEDataList(LEDataList **dataList);
 /**
  * Used to get the total registered service count.
  * @return  Total registered service count.
  */
-int32_t  CAGetRegisteredServiceCount();
 
+void CADestroyLEData(LEData *data);
 /**
  * Used to add the serverListInfo structure to the Server List.
  *
@@ -145,8 +169,7 @@ CAResult_t CAGetLEServerInfo(LEServerInfoList *serverList, const char *leAddress
  * @retval ::CA_STATUS_INVALID_PARAM  Invalid input arguments.
  * @retval ::CA_STATUS_FAILED Operation failed.
  */
-CAResult_t CAGetLEServerInfoByPosition(LEServerInfoList *serverList, int32_t position,
-                                       LEServerInfo **leServerInfo);
+
 
 /**
  * Used to clear BLE service list.
index 24a0aa0..f49ad4f 100755 (executable)
@@ -56,7 +56,7 @@ rd_env.PrependUnique(LIBS = ['octbstack', 'oc', 'oc_logger'])
 if target_os not in ['windows']:
     rd_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x'])
 
-if target_os in ['linux']:
+if target_os in ['linux', 'tizen']:
     rd_env.AppendUnique(LIBS = ['pthread'])
 
 if target_os == 'android':
index d04f96a..a2f27fa 100644 (file)
@@ -46,8 +46,13 @@ print "Given Transport is %s" % transport
 print "Given OS is %s" % target_os
 print "Given MQ is %s" % with_mq
 
+gbs_command_prefix = ""
+if (('BLE' in transport) or ('ALL' in transport)):
+       print "Tizen BLE requires tizen 3.0 profile"
+       gbs_command_prefix += "gbsprofile=tizen_4_0_unified_armv7l "
+
 if target_os == 'tizen':
-       command = "sh resource/csdk/stack/samples/tizen/build/gbsbuild.sh %s %s %s %s %s %s %s %s %s" % (transport, secured, buildsample, release_mode, logging, routing, with_tcp, with_proxy, with_mq)
+       command = gbs_command_prefix + "./resource/csdk/stack/samples/tizen/build/gbsbuild.sh %s %s %s %s %s %s %s %s %s" % (transport, secured, buildsample, release_mode, logging, routing, with_tcp, with_proxy, with_mq)
        print "Created Command is %s" % command
        gbs_script = env.Command('gbs_build', None, command)
-       AlwaysBuild ('gbs_script')
\ No newline at end of file
+       AlwaysBuild ('gbs_script')
index bde1850..8d761f0 100755 (executable)
@@ -7,6 +7,7 @@ name=`echo $name|cut -d" " -f 1`
 version=`echo $version|cut -d" " -f 1`
 
 name=oicri
+gbsarch=${gbsarch:=armv7l}
 
 echo $1
 export TARGET_TRANSPORT=$1
@@ -103,8 +104,13 @@ if [ ! -d .git ]; then
    git commit -m "Initial commit"
 fi
 
+gbsprofile=${gbsprofile:=profile.tizen}
+gbscommand_prefix="gbs build -A ${gbsarch} -P ${gbsprofile} "
+nproc=$(expr 1 + $(expr `nproc --ignore=1` / 2 ) )
+gbscommand_prefix=${gbscommand_prefix}" --define '_smp_mflags -j${nproc}'"
+
 echo "Calling core gbs build command"
-gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-RI-OIC --include-all --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --define 'ROUTING $6' --define 'WITH_TCP $7' --define 'WITH_PROXY $8' --define 'WITH_MQ $9'"
+gbscommand=${gbscommand_prefix}" -B ~/GBS-ROOT-RI-OIC --include-all --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --define 'ROUTING $6' --define 'WITH_TCP $7' --define 'WITH_PROXY $8' --define 'WITH_MQ $9'"
 echo $gbscommand
 if eval $gbscommand; then
    echo "Core build is successful"
@@ -127,7 +133,7 @@ if echo $BUILD_SAMPLE|grep -qi '^ON$'; then
       git commit -m "Initial commit"
    fi
    echo "Calling sample gbs build command"
-   gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-RI-OIC --include-all --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --define 'ROUTING $6' --define 'WITH_TCP $7' --define 'WITH_PROXY $8' --define 'WITH_MQ $9'"
+   gbscommand=${gbscommand_prefix}" -B ~/GBS-ROOT-RI-OIC --include-all --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --define 'ROUTING $6' --define 'WITH_TCP $7' --define 'WITH_PROXY $8' --define 'WITH_MQ $9'"
    echo $gbscommand
    if eval $gbscommand; then
       echo "Sample build is successful"
index 90d704d..1d1ef43 100755 (executable)
@@ -9,6 +9,29 @@ url = https://168.219.241.169/api
 user = obs_viewer
 passwd = obs_viewer_169
 
+#{ Tizen 4.0
+[profile.tizen_4_0_unified_armv7l]
+repos=repo.tizen_4_0_base_armv7l, repo.tizen_4_0_unified_armv7l
+buildroot=~/tmp/gbs/tmp-GBS-tizen_4_0_unified_armv7l/
+
+[repo.tizen_4_0_unified_armv7l]
+url=http://cdn.download.tizen.org/releases/milestone/tizen/4.0.m1/tizen-unified_20170529.1/repos/standard/packages/
+
+[repo.tizen_4_0_base_armv7l]
+url=http://cdn.download.tizen.org/releases/milestone/tizen/4.0.m1/tizen-base_20170520.1/repos/arm/packages/
+#}
+
+#{ Tizen:3.0
+[profile.tizen_3_0]
+repos=repo.tizen_3_0_base, repo.tizen_3_0
+buildroot=~/tmp/gbs/tmp-GBS-tizen_3_0
+
+[repo.tizen_3_0]
+url=http://download.tizen.org/snapshots/tizen/3.0-mobile/latest/repos/target-TM1/packages/
+
+[repo.tizen_3_0_base]
+url=http://download.tizen.org/releases/daily/tizen/3.0-base/latest/repos/arm/packages/
+#}
 
 ############################################################################################
 [repo.base_Main2017]