From 6432287d35c256929a4d3c04d64865bd2f3b87d5 Mon Sep 17 00:00:00 2001 From: "jihwan.seo" Date: Tue, 18 Oct 2016 16:27:43 +0900 Subject: [PATCH] [IOT-1458] fix to handle unexpected disconnected state for BLE Change-Id: I83ba76e61eb57fce91c42d32c434a3b2735d2aa3 Signed-off-by: jihwan.seo Reviewed-on: https://gerrit.iotivity.org/gerrit/13371 Tested-by: jenkins-iotivity Reviewed-by: Ashok Babu Channa --- .../src/bt_le_adapter/android/caleclient.c | 72 ++++++++++++++++++++-- .../src/bt_le_adapter/android/caleclient.h | 14 +++++ 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c index e5af799..09d294a 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c @@ -945,7 +945,7 @@ CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* { OIC_LOG(DEBUG, TAG, "waiting send finish signal"); oc_cond_wait(g_threadCond, g_threadMutex); - OIC_LOG(DEBUG, TAG, "the data was sent"); + OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast"); } oc_mutex_unlock(g_threadMutex); @@ -959,10 +959,12 @@ CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_SUCCESS)) { + OIC_LOG(INFO, TAG, "send success"); ret = CA_STATUS_OK; } else { + OIC_LOG(ERROR, TAG, "send failure"); ret = CA_SEND_FAILED; } @@ -1050,7 +1052,7 @@ CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data, { OIC_LOG(DEBUG, TAG, "waiting send finish signal"); oc_cond_wait(g_threadCond, g_threadMutex); - OIC_LOG(DEBUG, TAG, "the data was sent"); + OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast"); } oc_mutex_unlock(g_threadMutex); oc_mutex_unlock(g_threadSendMutex); @@ -1087,6 +1089,22 @@ CAResult_t CALEClientSendData(JNIEnv *env, jobject device) oc_mutex_unlock(g_deviceStateListMutex); } + // Since disconnect event can be caused from BT stack while connection step is running. + // DeviceState has to have current status for processing send failure. + OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING"); + CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device, + CA_LE_SEND_STATE, + STATE_SEND_PREPARING); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed"); + if (address) + { + (*env)->ReleaseStringUTFChars(env, jni_address, address); + } + return CA_STATUS_FAILED; + } + if (!state) { OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE"); @@ -3387,13 +3405,48 @@ jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice) /** * BT State List */ +CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env, + jobject device, + uint16_t state_type, + uint16_t target_state) +{ + VERIFY_NON_NULL(device, TAG, "device is null"); + + // get Bluetooth Address + jstring jni_Address = CALEGetAddressFromBTDevice(env, device); + if (!jni_Address) + { + OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed"); + return CA_STATUS_FAILED; + } + + const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL); + if (!address) + { + OIC_LOG(ERROR, TAG, "targetAddress is not available"); + return CA_STATUS_FAILED; + } + + if (CALEClientIsValidState(address, state_type, target_state)) + { + return CA_STATUS_OK; + } + + CAResult_t res = CALEClientUpdateDeviceState(address, state_type, + target_state); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); + } + (*env)->ReleaseStringUTFChars(env, jni_Address, address); + + return res; +} CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type, uint16_t target_state) { VERIFY_NON_NULL(address, TAG, "address is null"); - VERIFY_NON_NULL(address, TAG, "state_type is null"); - VERIFY_NON_NULL(address, TAG, "target_state is null"); if (!g_deviceStateList) { @@ -4207,6 +4260,17 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J { OIC_LOG(DEBUG, TAG, "LE is disconnected"); + if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING)) + { + OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING"); + CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE, + STATE_SEND_FAIL); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); + } + } + CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_DISCONNECTED); diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h index eb61cf4..51631c5 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h +++ b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h @@ -41,6 +41,7 @@ static const uint16_t STATE_SEND_NONE = 1; static const uint16_t STATE_SEND_SUCCESS = 2; static const uint16_t STATE_SEND_FAIL = 3; static const uint16_t STATE_SENDING = 4; +static const uint16_t STATE_SEND_PREPARING = 5; typedef struct le_state_info { @@ -499,6 +500,19 @@ CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr); jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice); /** + * update new state information by Bluetooth device object. + * @param[in] env JNI interface pointer. + * @param[in] device Bluetooth device. + * @param[in] state_type state type. + * @param[in] target_state state index to update. + * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h). + */ +CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env, + jobject device, + uint16_t state_type, + uint16_t target_state); + +/** * update new state information. * @param[in] address remote address. * @param[in] state_type state type. -- 2.7.4