From f4dfe0020a8a48131cebeef8d0cc513d841aab16 Mon Sep 17 00:00:00 2001 From: Samanway Dey Date: Mon, 1 Jul 2019 19:40:17 +0530 Subject: [PATCH] Adding Retry logic for LUX disconnection issue -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 Signed-off-by: Sudipto --- .../src/bt_le_adapter/tizen/caleclient.c | 105 +++++++++++++++++++-- 1 file changed, 98 insertions(+), 7 deletions(-) diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c index df00ae1..a5851cb 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c @@ -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 @@ -50,12 +51,24 @@ #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, -- 2.7.4