From 88e5f2dbb60c84a43c8edea64bb15321677ec2ee Mon Sep 17 00:00:00 2001 From: Jaehong Jo Date: Thu, 19 Nov 2015 11:45:50 +0900 Subject: [PATCH] Enable multiple EDR connection in Android. Using Available API before using blocking EDR read function. Bluetooth read function is a blocking function which makes other connection to wait. So added checking the packet availability before making blocking read. Change-Id: I794a4010ae6ad3e21c63f3a9e3e9d3fc0d89cad5 Signed-off-by: Jaehong Jo Reviewed-on: https://gerrit.iotivity.org/gerrit/4277 Tested-by: jenkins-iotivity Reviewed-by: Jon A. Cruz --- .../src/bt_edr_adapter/android/caedrserver.c | 108 ++++++++------------- .../src/bt_edr_adapter/android/caedrutils.c | 5 - 2 files changed, 40 insertions(+), 73 deletions(-) diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c index de09553..f9fd054 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c @@ -86,8 +86,6 @@ static ca_mutex g_mutexAcceptServer = NULL; */ static bool g_stopAccept = false; -static jobject g_inputStream = NULL; - /** * Mutex to synchronize server socket. */ @@ -105,11 +103,6 @@ static ca_mutex g_mutexStateList = NULL; */ static ca_mutex g_mutexObjectList = NULL; -/** - * Mutex to synchronize input stream. - */ -static ca_mutex g_mutexInputStream = NULL; - typedef struct send_data { char* address; @@ -170,7 +163,6 @@ static void CAReceiveHandler(void *data) { for (uint32_t idx = 0; idx < length; idx++) { - OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData"); CAEDRNativeReadData(env, idx, ctx->type); } } @@ -384,12 +376,6 @@ static void CAEDRServerDestroyMutex() g_mutexObjectList = NULL; } - if (g_mutexInputStream) - { - ca_mutex_free(g_mutexInputStream); - g_mutexInputStream = NULL; - } - OIC_LOG(DEBUG, TAG, "OUT"); } @@ -461,15 +447,6 @@ static CAResult_t CAEDRServerCreateMutex() return CA_STATUS_FAILED; } - g_mutexInputStream = ca_mutex_new(); - if (!g_mutexInputStream) - { - OIC_LOG(ERROR, TAG, "Failed to created g_mutexInputStream."); - - CAEDRServerDestroyMutex(); - return CA_STATUS_FAILED; - } - OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } @@ -725,16 +702,9 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket); if (!ret) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket"); - } - - // check it whether is still connected or not through socket state list - if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address)) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet.."); + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet."); // remove socket to list - // this code is related to below read fail exception code CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket); (*env)->ReleaseStringUTFChars(env, jni_str_address, address); @@ -755,7 +725,6 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, "getInputStream", "()Ljava/io/InputStream;"); - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address); jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket, jni_mid_getInputStream); @@ -768,8 +737,6 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream.."); - jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream"); if (!jni_cid_InputStream) { @@ -780,31 +747,57 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null"); return CA_STATUS_FAILED; } - jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I"); - jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER); + jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream, + "available", "()I"); + if (!jni_mid_available) { + (*env)->DeleteLocalRef(env, jni_obj_inputStream); + (*env)->DeleteLocalRef(env, jni_cid_InputStream); + (*env)->DeleteLocalRef(env, jni_cid_BTsocket); + (*env)->DeleteLocalRef(env, jni_str_address); - ca_mutex_lock(g_mutexInputStream); - if (!g_inputStream) - { - g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream); + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_mid_available is null"); + return CA_STATUS_FAILED; } - jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0, - MAX_PDU_BUFFER); - ca_mutex_unlock(g_mutexInputStream); + jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available); + + jbyteArray jbuf = NULL; + jint length = -1; + if (0 < available) + { + OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address); + jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, + "read", "([BII)I"); + if (!jni_mid_read) { + (*env)->DeleteLocalRef(env, jni_obj_inputStream); + (*env)->DeleteLocalRef(env, jni_cid_InputStream); + (*env)->DeleteLocalRef(env, jni_cid_BTsocket); + (*env)->DeleteLocalRef(env, jni_str_address); + + OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_mid_read is null"); + return CA_STATUS_FAILED; + } - OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream"); + jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER); + length = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read, jbuf, (jint) 0, + MAX_PDU_BUFFER); + OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: read something from InputStream"); + } + + (*env)->DeleteLocalRef(env, jni_obj_inputStream); if (-1 == length) { (*env)->DeleteLocalRef(env, jni_cid_InputStream); - (*env)->DeleteLocalRef(env, jbuf); - (*env)->DeleteLocalRef(env, jni_obj_inputStream); + if (jbuf) + { + OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty..."); + (*env)->DeleteLocalRef(env, jbuf); + } (*env)->DeleteLocalRef(env, jni_cid_BTsocket); (*env)->DeleteLocalRef(env, jni_str_address); - OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty..."); return CA_STATUS_FAILED; } @@ -823,7 +816,6 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t (*env)->DeleteLocalRef(env, jbuf); (*env)->DeleteLocalRef(env, jni_cid_InputStream); - (*env)->DeleteLocalRef(env, jni_obj_inputStream); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); (*env)->DeleteLocalRef(env, jni_str_address); @@ -836,7 +828,6 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t { (*env)->DeleteLocalRef(env, jni_cid_InputStream); (*env)->DeleteLocalRef(env, jbuf); - (*env)->DeleteLocalRef(env, jni_obj_inputStream); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); (*env)->DeleteLocalRef(env, jni_str_address); @@ -873,7 +864,6 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t (*env)->DeleteLocalRef(env, jni_cid_InputStream); (*env)->DeleteLocalRef(env, jbuf); - (*env)->DeleteLocalRef(env, jni_obj_inputStream); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); (*env)->DeleteLocalRef(env, jni_str_address); } @@ -890,14 +880,6 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket..."); - - if (!CAEDRNativeIsEnableBTAdapter(env)) - { - OIC_LOG(ERROR, TAG, "BT adpater is not enable"); - return JNI_FALSE; - } - if (!socket) { OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null"); @@ -1111,16 +1093,6 @@ void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject) */ void CAEDRNatvieCloseServerTask(JNIEnv* env) { - if (g_inputStream) - { - OIC_LOG(DEBUG, TAG, "InputStream will be close"); - jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream"); - jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V"); - (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close); - (*env)->DeleteGlobalRef(env, g_inputStream); - g_inputStream = NULL; - } - if (g_serverSocket) { OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close"); diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c index bd40b31..773eed9 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c @@ -338,7 +338,6 @@ jboolean CAEDRNativeIsEnableBTAdapter(JNIEnv *env) } jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable); - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] adapter state is %d", jni_isEnable); (*env)->DeleteLocalRef(env, jni_obj_BTAdapter); (*env)->DeleteLocalRef(env, jni_cid_BTAdapter); @@ -565,8 +564,6 @@ CAConnectedState_t CAEDRIsConnectedDevice(const char *remoteAddress) if (!strcmp((const char*) state->address, remoteAddress)) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] check whether it is connected or not"); - return state->state; } } @@ -857,8 +854,6 @@ void CAEDRNativeRemoveDeviceSocketBaseAddr(JNIEnv *env, jstring address) jobject CAEDRNativeGetDeviceSocket(uint32_t idx) { - OIC_LOG(DEBUG, TAG, "CAEDRNativeGetDeviceSocket"); - if (!g_deviceObjectList) { OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null"); -- 2.7.4