Adding Retry logic for LUX disconnection issue 81/214381/1
authorSamanway Dey <samanway.dey@samsung.com>
Mon, 1 Jul 2019 14:10:17 +0000 (19:40 +0530)
committerSudipto <sudipto.bal@samsung.com>
Fri, 20 Sep 2019 17:14:56 +0000 (22:44 +0530)
 -Added retry logic for LUX disconnection issue
 -There is a mutex unlock placed under wrong nested block,
which will be corrected in a separate commit

https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/530/commits/25ef240cc9978fa5945a26e72a8e763c436960db
(cherry-picked from 25ef240cc9978fa5945a26e72a8e763c436960db)

Change-Id: If2ff7023db999d4bf160501014af5ec559f5bd8d
Signed-off-by: Samanway Dey <samanway.dey@samsung.com>
Signed-off-by: Sudipto <sudipto.bal@samsung.com>
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c

index df00ae1..a5851cb 100644 (file)
@@ -43,6 +43,7 @@
  */
 #define TAG "OIC_CA_LE_CLIENT"
 
+#define RETRY_COUNT 1
 #define MICROSECS_PER_SEC 1000000
 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
 
 #define CA_GATT_CUSTOM_UUID "4209"
 #define CA_GATT_CUSTOM_UUID2 "4204"
 #define CUSTOM_UUID_LEN 4
+#define MICROSECS_PER_SEC 1000000
 
 static const int samsung_code = 117;
-
+static int g_retrycount = 0;
+static int retry_flag = 0;
 uint64_t const TIMEOUT = 30 * MICROSECS_PER_SEC;
 
 /**
+ * Mutex to call connect only after disconnect during retry
+ */
+static oc_mutex g_isDisconnectedMutex = NULL;
+
+/**
+ * Condition for calling connect during connection retry
+ */
+static oc_cond g_LEDisconnectedCond = NULL;
+
+/**
  * Flag to check if scanning is in progress
  */
 static bool g_isScanningInProgress = false;
@@ -275,6 +288,8 @@ CAResult_t CALEGattInitiateConnection(const char *remoteAddress)
         return CA_STATUS_FAILED;
     }
     g_isConnectionInProgress = true;
+    // Set gatt connect retry count
+    g_retrycount = RETRY_COUNT;
     oc_mutex_unlock(g_isConnectionInProgressMutex);
 
     // Pause the scanning
@@ -321,9 +336,19 @@ void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
     if (!connected)
     {
         OIC_LOG_V(DEBUG, TAG, "DisConnected from [%s] ", remoteAddress);
-        oc_mutex_lock(g_LEServerListMutex);
-        CARemoveLEServerInfoFromList(&g_LEServerList, remoteAddress);
-        oc_mutex_unlock(g_LEServerListMutex);
+        if(!retry_flag)
+        {
+            oc_mutex_lock(g_LEServerListMutex);
+            CARemoveLEServerInfoFromList(&g_LEServerList, remoteAddress);
+            oc_mutex_unlock(g_LEServerListMutex);
+        }
+        else
+        {
+            oc_mutex_lock(g_isDisconnectedMutex);
+            oc_cond_signal(g_LEDisconnectedCond);
+            oc_mutex_unlock(g_isDisconnectedMutex);
+        }
+        retry_flag = 0;
     }
     else
     {
@@ -344,7 +369,6 @@ void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
 
         serverInfo->status = LE_STATUS_CONNECTED;
         oc_mutex_unlock(g_LEServerListMutex);
-
         oc_mutex_lock(g_LEClientThreadPoolMutex);
         if (NULL == g_LEClientThreadPool)
         {
@@ -360,7 +384,6 @@ void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
             OIC_LOG(ERROR, TAG, "addr is NULL");
             return;
         }
-
         CAResult_t ret = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
                                                  addr, NULL);
         oc_mutex_unlock(g_LEClientThreadPoolMutex);
@@ -860,6 +883,26 @@ CAResult_t CAInitGattClientMutexVariables()
         }
     }
 
+    if (NULL == g_isDisconnectedMutex)
+    {
+        g_isDisconnectedMutex = oc_mutex_new();
+        if (NULL == g_isDisconnectedMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_LEDisconnectedCond)
+    {
+        g_LEDisconnectedCond = oc_cond_new();
+        if (NULL == g_LEDisconnectedCond)
+        {
+            OIC_LOG(ERROR, TAG, "oc_cond_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
     if (NULL == g_startTimerCond)
     {
         g_startTimerCond = oc_cond_new();
@@ -942,6 +985,12 @@ void CATerminateGattClientMutexVariables()
     oc_mutex_free(g_threadMTUChangedMutex);
     g_threadMTUChangedMutex = NULL;
 
+    oc_mutex_free(g_isDisconnectedMutex);
+    g_isDisconnectedMutex = NULL;
+
+    oc_cond_free(g_LEDisconnectedCond);
+    g_LEDisconnectedCond = NULL;
+
     oc_cond_free(g_startTimerCond);
     g_startTimerCond = NULL;
 
@@ -1206,6 +1255,29 @@ void CADiscoverLEServicesThread(void *remoteAddress)
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
+static int CALEWaittillDisconnect(oc_mutex mutex, oc_cond cv, int wait_seconds)
+{
+    OIC_LOG(DEBUG, TAG, "Waiting for server to be disconnected...");
+    oc_mutex_lock(mutex);
+    uint64_t wait_time = wait_seconds * MICROSECS_PER_SEC;
+    int ret = oc_cond_wait_for(cv, mutex, wait_time);
+    oc_mutex_unlock(mutex);
+    return ret;
+}
+
+static CAResult_t CALEGattConnectionRetry(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL")
+
+    CALEGattDisConnect(remoteAddress);
+    CALEWaittillDisconnect(g_isDisconnectedMutex, g_LEDisconnectedCond, 10);
+    CAResult_t result = CALEGattConnect(remoteAddress);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return result;
+}
+
 CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
 {
     OIC_LOG(DEBUG, TAG, "IN");
@@ -1230,9 +1302,28 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
     {
         OIC_LOG_V(ERROR, TAG,
                   "bt_gatt_client_get_service Failed with ret value [%s] ", CALEGetErrorMsg(ret));
-        goto error_exit;
+        if(g_retrycount)
+        {
+            OIC_LOG(DEBUG, TAG, "Retry will be attempted to connect Gatt Server");
+            g_retrycount--;
+            retry_flag = 1;
+            OIC_LOG_V(DEBUG, TAG, "Retry count left %d time(s)", g_retrycount);
+            CAResult_t result = CALEGattConnectionRetry(remoteAddress);
+            if(result == CA_STATUS_FAILED)
+            {
+                goto error_exit;
+            }
+            else
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+               OIC_LOG(ERROR, TAG, "Previous connection attempt failed, attempting to retry again");
+               OIC_LOG_V(DEBUG, TAG, "Retry count left %d time(s)", g_retrycount);
+                return CA_STATUS_FAILED;
+            }
+        }
     }
 
+    retry_flag = 0;
     // Server will read data on this characteristic.
     bt_gatt_h writeChrHandle = NULL;
     ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_REQUEST_CHRC_UUID,