X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fconnectivity%2Fsrc%2Fbt_edr_adapter%2Fandroid%2Fcaedrserver.c;h=ad36e2f3dae2e9d038296ab37bf185fa7eb54acc;hb=c01ee6a8bbe7aff16e7a371de4875898234aee20;hp=d5533ea9fb1cf9d79699ee8c3c20398370c8b882;hpb=ed03b2f2d711027561c18956826580e1e81b84ec;p=platform%2Fupstream%2Fiotivity.git 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 d5533ea..ad36e2f 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,7 +19,6 @@ ******************************************************************/ #include -#include #include #include @@ -36,7 +35,7 @@ #include "oic_string.h" //#define DEBUG_MODE -#define TAG PCF("CA_EDR_SERVER") +#define TAG PCF("OIC_CA_EDR_SERVER") #define MAX_PDU_BUFFER (1024) static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;"; @@ -48,81 +47,65 @@ static ca_thread_pool_t g_threadPoolHandle = NULL; static JavaVM *g_jvm; /** - * @var g_mMutexSocketListManager - * @brief Mutex to synchronize socket list update + * Maximum CoAP over TCP header length + * to know the total data length. */ -static ca_mutex g_mutexSocketListManager; +#define EDR_MAX_HEADER_LEN 6 -// server socket instance +/** + * server socket instance. + */ static jobject g_serverSocketObject = NULL; /** - * @var g_mutexUnicastServer - * @brief Mutex to synchronize unicast server + * Mutex to synchronize unicast server. */ static ca_mutex g_mutexUnicastServer = NULL; /** - * @var g_stopUnicast - * @brief Flag to control the Receive Unicast Data Thread + * Flag to control the Receive Unicast Data Thread. */ static bool g_stopUnicast = false; /** - * @var g_mutexMulticastServer - * @brief Mutex to synchronize secure multicast server + * Mutex to synchronize secure multicast server. */ static ca_mutex g_mutexMulticastServer = NULL; /** - * @var g_stopMulticast - * @brief Flag to control the Receive Multicast Data Thread + * Flag to control the Receive Multicast Data Thread. */ static bool g_stopMulticast = false; /** - * @var g_mutexAcceptServer - * @brief Mutex to synchronize accept server + * Mutex to synchronize accept server. */ static ca_mutex g_mutexAcceptServer = NULL; /** - * @var g_stopAccept - * @brief Flag to control the Accept Thread + * Flag to control the Accept Thread. */ static bool g_stopAccept = false; -static jobject g_inputStream = NULL; - /** - * @var g_mutexServerSocket - * @brief Mutex to synchronize server socket + * Mutex to synchronize server socket. */ static ca_mutex g_mutexServerSocket = NULL; static jobject g_serverSocket = NULL; /** - * @var g_mutexStateList - * @brief Mutex to synchronize device state list + * Mutex to synchronize device state list. */ static ca_mutex g_mutexStateList = NULL; /** - * @var g_mutexObjectList - * @brief Mutex to synchronize device object list + * Mutex to synchronize device object list. */ static ca_mutex g_mutexObjectList = NULL; -typedef struct send_data -{ - char* address; - char* data; - uint32_t id; -} data_t; - /** - @brief Thread context information for unicast, multicast and secured unicast server + * Thread context information for unicast, multicast and secured unicast server. */ typedef struct { @@ -136,8 +119,8 @@ typedef struct } CAAdapterAcceptThreadContext_t; /** - * @var g_edrPacketReceivedCallback - * @brief Maintains the callback to be notified when data received from remote Bluetooth device + * Maintains the callback to be notified when data received from remote + * Bluetooth device. */ static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL; @@ -167,21 +150,21 @@ static void CAReceiveHandler(void *data) while (true != *(ctx->stopFlag)) { - // if new socket object is added in socket list after below logic is ran. - // new socket will be started to read after next while loop - uint32_t length = CAEDRGetSocketListLength(); - if (0 == length) + if (!CAEDRNativeIsEnableBTAdapter(env)) { - OIC_LOG(DEBUG, TAG, "socket list is empty"); - sleep(1); + OIC_LOG(ERROR, TAG, "BT adpater is not enable"); + break; } - uint32_t idx; - for (idx = 0; idx < length; idx++) + // if new socket object is added in socket list after below logic is ran. + // new socket will be started to read after next while loop + uint32_t length = CAEDRGetSocketListLength(); + if (0 != length) { - OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData"); - CAEDRNativeReadData(env, idx, ctx->type); - sleep(1); + for (uint32_t idx = 0; idx < length; idx++) + { + CAEDRNativeReadData(env, idx); + } } } @@ -197,13 +180,9 @@ static void CAReceiveHandler(void *data) static void CAAcceptHandler(void *data) { - if (!data) - { - OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null"); - return; - } + OIC_LOG(DEBUG, TAG, "AcceptThread start"); - OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start"); + VERIFY_NON_NULL_VOID(data, TAG, "CAAcceptHandler: data is null"); bool isAttached = false; JNIEnv* env; @@ -224,7 +203,7 @@ static void CAAcceptHandler(void *data) jobject jni_obj_BTServerSocket = CAEDRNativeListen(env); if (!jni_obj_BTServerSocket) { - OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null"); + OIC_LOG(ERROR, TAG, "AcceptThread: jni_obj_BTServerSocket is null"); if (isAttached) { @@ -240,16 +219,6 @@ static void CAAcceptHandler(void *data) CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data; - if (NULL == ctx) - { - OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null"); - if (isAttached) - { - (*g_jvm)->DetachCurrentThread(g_jvm); - } - return; - } - // it should be initialized for restart accept thread ca_mutex_lock(g_mutexAcceptServer); g_stopAccept = false; @@ -257,7 +226,7 @@ static void CAAcceptHandler(void *data) while (true != *(ctx->stopFlag)) { - OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running"); + OIC_LOG(DEBUG, TAG, "AcceptThread running"); // when BT state is changed with Off. its thread will be stopped if (!CAEDRNativeIsEnableBTAdapter(env)) @@ -283,35 +252,37 @@ static void CAAcceptHandler(void *data) OICFree(ctx); - OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish"); + OIC_LOG(DEBUG, TAG, "AcceptThread finish"); return; } /** - * implement for adapter common method + * implement for adapter common method. */ -CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, ca_thread_pool_t handle) +CAResult_t CAEDRServerStart() { - OIC_LOG(DEBUG, TAG, "IN"); - CAEDRServerInitialize(handle); + if (!g_threadPoolHandle) + { + return CA_STATUS_NOT_INITIALIZED; + } + + CAEDRServerStartAcceptThread(); CAResult_t res = CAEDRStartUnicastServer(false); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed"); + CAEDRServerStop(); return CA_STATUS_FAILED; } - *serverFD = 1; - OIC_LOG(DEBUG, TAG, "OUT"); - return CA_STATUS_OK; + return res; } -CAResult_t CAEDRServerStop(int serverFD) +CAResult_t CAEDRServerStop() { - OIC_LOG(DEBUG, TAG, "IN"); - CAEDRStopUnicastServer(-1); - CAEDRStopMulticastServer(-1); + CAEDRStopUnicastServer(); + CAEDRStopMulticastServer(); ca_mutex_lock(g_mutexAcceptServer); g_stopAccept = true; @@ -319,7 +290,7 @@ CAResult_t CAEDRServerStop(int serverFD) if (!g_jvm) { - OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null"); + OIC_LOG(DEBUG, TAG, "g_jvm is null"); return CA_STATUS_FAILED; } @@ -328,7 +299,7 @@ CAResult_t CAEDRServerStop(int serverFD) jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer"); + OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); if (JNI_OK != res) @@ -346,7 +317,6 @@ CAResult_t CAEDRServerStop(int serverFD) (*g_jvm)->DetachCurrentThread(g_jvm); } - OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } @@ -355,13 +325,8 @@ void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCall g_edrPacketReceivedCallback = packetReceivedCallback; } -/** - * Destroy Mutex - */ static void CAEDRServerDestroyMutex() { - OIC_LOG(DEBUG, TAG, "IN"); - if (g_mutexUnicastServer) { ca_mutex_free(g_mutexUnicastServer); @@ -374,12 +339,6 @@ static void CAEDRServerDestroyMutex() g_mutexMulticastServer = NULL; } - if (g_mutexSocketListManager) - { - ca_mutex_free(g_mutexSocketListManager); - g_mutexSocketListManager = NULL; - } - if (g_mutexAcceptServer) { ca_mutex_free(g_mutexAcceptServer); @@ -403,17 +362,10 @@ static void CAEDRServerDestroyMutex() ca_mutex_free(g_mutexObjectList); g_mutexObjectList = NULL; } - - OIC_LOG(DEBUG, TAG, "OUT"); } -/* - * Create Mutex - */ static CAResult_t CAEDRServerCreateMutex() { - OIC_LOG(DEBUG, TAG, "IN"); - g_mutexUnicastServer = ca_mutex_new(); if (!g_mutexUnicastServer) { @@ -430,15 +382,6 @@ static CAResult_t CAEDRServerCreateMutex() return CA_STATUS_FAILED; } - g_mutexSocketListManager = ca_mutex_new(); - if (!g_mutexSocketListManager) - { - OIC_LOG(ERROR, TAG, "Failed to created mutex!"); - - CAEDRServerDestroyMutex(); - return CA_STATUS_FAILED; - } - g_mutexAcceptServer = ca_mutex_new(); if (!g_mutexAcceptServer) { @@ -475,7 +418,6 @@ static CAResult_t CAEDRServerCreateMutex() return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } @@ -485,36 +427,32 @@ void CAEDRServerJniInit() g_jvm = CANativeJNIGetJavaVM(); } -void CAEDRServerInitialize(ca_thread_pool_t handle) +CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle) { OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize"); - + VERIFY_NON_NULL(handle, TAG, "handle is NULL"); g_threadPoolHandle = handle; - - CAEDRServerStartAcceptThread(); - - OIC_LOG(DEBUG, TAG, "OUT"); -} - -void CAEDRServerStartAcceptThread() -{ CAEDRServerJniInit(); // init mutex - CAEDRServerCreateMutex(); + CAResult_t result = CAEDRServerCreateMutex(); + return result; +} +CAResult_t CAEDRServerStartAcceptThread() +{ bool isAttached = false; JNIEnv* env; jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer"); + OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); if (JNI_OK != res) { OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); - return; + return CA_STATUS_FAILED; } isAttached = true; } @@ -545,7 +483,7 @@ void CAEDRServerStartAcceptThread() if (!ctx) { OIC_LOG(ERROR, TAG, "Out of memory!"); - return; + return CA_MEMORY_ALLOC_FAILED; } ctx->stopFlag = &g_stopAccept; @@ -553,10 +491,10 @@ void CAEDRServerStartAcceptThread() { OIC_LOG(ERROR, TAG, "Failed to create read thread!"); OICFree((void *) ctx); - return; + return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, TAG, "OUT"); + return CA_STATUS_OK; } void CAEDRServerTerminate() @@ -572,7 +510,7 @@ void CAEDRServerTerminate() jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); if (JNI_OK != res) { - OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer"); + OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); if (JNI_OK != res) @@ -634,7 +572,7 @@ CAResult_t CAEDRStartUnicastServer(bool isSecured) return CA_STATUS_OK; } -CAResult_t CAEDRStartMulticastServer(bool isSecured) +CAResult_t CAEDRStartMulticastServer() { OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer"); @@ -677,7 +615,7 @@ CAResult_t CAEDRStartMulticastServer(bool isSecured) return CA_STATUS_OK; } -CAResult_t CAEDRStopUnicastServer(int32_t serverID) +CAResult_t CAEDRStopUnicastServer() { OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer"); @@ -688,7 +626,7 @@ CAResult_t CAEDRStopUnicastServer(int32_t serverID) return CA_STATUS_OK; } -CAResult_t CAEDRStopMulticastServer(int32_t serverID) +CAResult_t CAEDRStopMulticastServer() { OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer"); @@ -701,183 +639,226 @@ CAResult_t CAEDRStopMulticastServer(int32_t serverID) return CA_STATUS_OK; } -CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type) +CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id) { - if (!CAEDRNativeIsEnableBTAdapter(env)) + if ((*env)->ExceptionCheck(env)) { - OIC_LOG(ERROR, TAG, "BT adpater is not enable"); - return CA_STATUS_INVALID_PARAM; + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + OIC_LOG(ERROR, TAG, "env error!!"); + return CA_STATUS_FAILED; } - if (!((*env)->ExceptionCheck(env))) + // check whether this socket object is connected or not. + jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id); + if (!jni_obj_socket) { - // check whether this socket object is connected or not. - jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id); - if (!jni_obj_socket) - { - return CA_STATUS_INVALID_PARAM; - } + return CA_STATUS_INVALID_PARAM; + } - jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket); - if (!jni_str_address) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null"); - return CA_STATUS_FAILED; - } - const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL); + jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket); + if (!jni_str_address) + { + OIC_LOG(ERROR, TAG, "jni_str_address is null"); + return CA_STATUS_FAILED; + } + const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL); - // check it whether is still connected or not through google api - 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 google api + jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket); + if (!ret) + { + OIC_LOG(ERROR, TAG, "it is not connected yet."); - // 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.."); + // remove socket to list + CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket); + (*env)->ReleaseStringUTFChars(env, jni_str_address, address); + (*env)->DeleteLocalRef(env, jni_str_address); - // 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); + return CA_STATUS_FAILED; + } - return CA_STATUS_FAILED; - } + // start to read through InputStream + jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); + if (!jni_cid_BTsocket) + { + OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null"); + (*env)->DeleteLocalRef(env, jni_str_address); + return CA_STATUS_FAILED; + } + jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, + "getInputStream", + "()Ljava/io/InputStream;"); - // start to read through InputStream - jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); - if (!jni_cid_BTsocket) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null"); - return CA_STATUS_FAILED; - } - 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); + if (!jni_obj_inputStream) + { + OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null"); + (*env)->DeleteLocalRef(env, jni_cid_BTsocket); + (*env)->DeleteLocalRef(env, jni_str_address); + return CA_STATUS_FAILED; + } - if (!jni_obj_socket) - { - OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore.."); - return CA_STATUS_FAILED; - } + jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream"); + if (!jni_cid_InputStream) + { + OIC_LOG(ERROR, TAG, "jni_cid_InputStream is null"); + goto exit; + } - jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket, - jni_mid_getInputStream); - OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream.."); + jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream, + "available", "()I"); + if (!jni_mid_available) + { + OIC_LOG(ERROR, TAG, "jni_mid_available is null"); + goto exit; + } - g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream); + jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available); - jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream"); - if (!jni_cid_InputStream) + CAConnectedDeviceInfo_t *deviceInfo = NULL; + if (0 < available) + { + OIC_LOG_V(DEBUG, TAG, "get InputStream..%d, %s", id, address); + jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, + "read", "([BII)I"); + if (!jni_mid_read) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null"); - return CA_STATUS_FAILED; + OIC_LOG(ERROR, TAG, "jni_mid_read is null"); + goto exit; } - jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I"); - - jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER); - if (!jni_obj_socket) + deviceInfo = (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address); + if (!deviceInfo) { - OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..."); - return CA_STATUS_FAILED; + OIC_LOG(ERROR, TAG, "failed to get device info from list"); + goto exit; } - jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0, - MAX_PDU_BUFFER); - - OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream"); - - if (-1 == length) + jint bufSize = (deviceInfo->totalDataLen == 0) ? + EDR_MAX_HEADER_LEN : deviceInfo->totalDataLen; + if (!deviceInfo->recvData) { - OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty..."); - return CA_STATUS_FAILED; + deviceInfo->recvData = OICCalloc(1, bufSize); + if (!deviceInfo->recvData) + { + OIC_LOG(ERROR, TAG, "out of memory"); + goto exit; + } } - if ((*env)->ExceptionCheck(env)) + jbyteArray jbuf = (*env)->NewByteArray(env, (jint) bufSize - deviceInfo->recvDataLen); + jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read, + jbuf, (jint) 0, + (jint) bufSize - deviceInfo->recvDataLen); + if (-1 == recvLen) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!"); - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - - // update state to disconnect - // the socket will be close next read thread routine - ca_mutex_lock(g_mutexStateList); - CAEDRUpdateDeviceState(STATE_DISCONNECTED, address); - ca_mutex_unlock(g_mutexStateList); - (*env)->ReleaseStringUTFChars(env, jni_str_address, address); - return CA_STATUS_FAILED; + (*env)->DeleteLocalRef(env, jbuf); + goto exit; } - OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading"); jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL); - if (NULL == buf) + if (!buf) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null"); - return CA_STATUS_FAILED; + (*env)->DeleteLocalRef(env, jbuf); + goto exit; } + memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen); + deviceInfo->recvDataLen += recvLen; - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length); - - char responseData[MAX_PDU_BUFFER] = { 0 }; - OICStrcpy(responseData, sizeof(responseData), buf, length); + OIC_LOG(DEBUG, TAG, "read something from InputStream"); - switch (type) + if (!deviceInfo->totalDataLen) { - case CA_UNICAST_SERVER: - case CA_MULTICAST_SERVER: - // Notify data to upper layer - if (g_edrPacketReceivedCallback) + coap_transport_type transport = coap_get_tcp_header_type_from_initbyte( + ((unsigned char *) deviceInfo->recvData)[0] >> 4); + size_t headerLen = coap_get_tcp_header_length_for_transport(transport); + if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen) + { + deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData, + deviceInfo->recvDataLen); + OIC_LOG_V(DEBUG, TAG, "total data length [%d] bytes", deviceInfo->totalDataLen); + + uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen); + if (!newBuf) { - uint32_t sentLength = 0; - OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \ - %s, %d", responseData, length); - g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength); + OIC_LOG(ERROR, TAG, "out of memory"); + (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0); + (*env)->DeleteLocalRef(env, jbuf); + goto exit; } - break; + deviceInfo->recvData = newBuf; + } + } - default: - // Should never occur - OIC_LOG(ERROR, TAG, "Invalid server type"); - return CA_STATUS_FAILED; + if (deviceInfo->totalDataLen == deviceInfo->recvDataLen) + { + if ((*env)->ExceptionCheck(env)) + { + OIC_LOG(ERROR, TAG, "read Error!!!"); + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + + // update state to disconnect + // the socket will be close next read thread routine + ca_mutex_lock(g_mutexStateList); + CAEDRUpdateDeviceState(STATE_DISCONNECTED, address); + ca_mutex_unlock(g_mutexStateList); + + (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0); + (*env)->DeleteLocalRef(env, jbuf); + goto exit; + } + + if (g_edrPacketReceivedCallback) + { + OIC_LOG_V(DEBUG, TAG,"data will be sent to callback routine: \ + %s, %d", deviceInfo->recvData, deviceInfo->recvDataLen); + + uint32_t sentLength = 0; + g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData, + deviceInfo->recvDataLen, &sentLength); + + OICFree(deviceInfo->recvData); + deviceInfo->recvData = NULL; + deviceInfo->recvDataLen = 0; + deviceInfo->totalDataLen = 0; + } } (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0); - (*env)->ReleaseStringUTFChars(env, jni_str_address, address); - } - else - { - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!"); - return CA_STATUS_FAILED; + (*env)->DeleteLocalRef(env, jbuf); } + (*env)->DeleteLocalRef(env, jni_obj_inputStream); + (*env)->DeleteLocalRef(env, jni_cid_InputStream); + (*env)->DeleteLocalRef(env, jni_cid_BTsocket); + (*env)->ReleaseStringUTFChars(env, jni_str_address, address); + (*env)->DeleteLocalRef(env, jni_str_address); return CA_STATUS_OK; + +exit: + (*env)->DeleteLocalRef(env, jni_obj_inputStream); + (*env)->DeleteLocalRef(env, jni_cid_InputStream); + (*env)->DeleteLocalRef(env, jni_cid_BTsocket); + (*env)->ReleaseStringUTFChars(env, jni_str_address, address); + (*env)->DeleteLocalRef(env, jni_str_address); + + return CA_STATUS_FAILED; } 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"); + OIC_LOG(ERROR, TAG, "socket is null"); return JNI_FALSE; } jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket"); if (!jni_cid_BTsocket) { - OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null"); + OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null"); return JNI_FALSE; } @@ -885,13 +866,15 @@ jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket) "()Z"); if (!jni_mid_isConnected) { - OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \ - - jni_mid_isConnected is null."); + OIC_LOG(ERROR, TAG, "jni_mid_isConnected is null."); + (*env)->DeleteLocalRef(env, jni_cid_BTsocket); return JNI_FALSE; } jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected); + (*env)->DeleteLocalRef(env, jni_cid_BTsocket); + return jni_isConnected; } @@ -900,7 +883,7 @@ void CANativeStartListenTask(JNIEnv *env) jobject jni_obj_BTServerSocket = CAEDRNativeListen(env); if (!jni_obj_BTServerSocket) { - OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null"); + OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null"); return; } @@ -911,18 +894,18 @@ void CANativeStartListenTask(JNIEnv *env) jobject CAEDRNativeListen(JNIEnv *env) { + OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - IN"); + if (!CAEDRNativeIsEnableBTAdapter(env)) { OIC_LOG(ERROR, TAG, "BT adpater is not enable"); return NULL; } - OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen"); - jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); if (!jni_cid_BTAdapter) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null"); + OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null"); return NULL; } @@ -930,9 +913,9 @@ jobject CAEDRNativeListen(JNIEnv *env) jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM); - if (!jni_cid_BTAdapter) + if (!jni_mid_getDefaultAdapter) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null"); + OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null"); return NULL; } @@ -940,7 +923,7 @@ jobject CAEDRNativeListen(JNIEnv *env) jni_mid_getDefaultAdapter); if (!jni_obj_BTAdapter) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null"); + OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null"); return NULL; } @@ -950,7 +933,7 @@ jobject CAEDRNativeListen(JNIEnv *env) "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;"); if (!jni_mid_listen) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null"); + OIC_LOG(ERROR, TAG, "jni_mid_listen is null"); return NULL; } // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord @@ -958,7 +941,7 @@ jobject CAEDRNativeListen(JNIEnv *env) jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID); if (!jni_cid_uuid) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null"); + OIC_LOG(ERROR, TAG, "jni_mid_listen is null"); return NULL; } @@ -966,21 +949,21 @@ jobject CAEDRNativeListen(JNIEnv *env) env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;"); if (!jni_mid_fromString) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null"); + OIC_LOG(ERROR, TAG, "jni_mid_fromString is null"); return NULL; } jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID); if (!jni_uuid) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null"); + OIC_LOG(ERROR, TAG, "jni_uuid is null"); return NULL; } jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid); if (!jni_obj_uuid) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null"); + OIC_LOG(ERROR, TAG, "jni_obj_uuid is null"); return NULL; } @@ -988,31 +971,35 @@ jobject CAEDRNativeListen(JNIEnv *env) jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure"); if (!jni_name) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null"); + OIC_LOG(ERROR, TAG, "jni_name is null"); return NULL; } jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen, jni_name, jni_obj_uuid); if (!jni_obj_BTServerSocket) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null"); + OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null"); return NULL; } g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket); + OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT"); + return jni_obj_BTServerSocket; } void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject) { + OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - IN"); + if (NULL != serverSocketObject) { jclass jni_cid_BTServerSocket = (*env)->FindClass( env, "android/bluetooth/BluetoothServerSocket"); if (!jni_cid_BTServerSocket) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null"); + OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null"); return; } @@ -1020,21 +1007,21 @@ void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject) "()Landroid/bluetooth/BluetoothSocket;"); if (!jni_mid_accept) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null"); + OIC_LOG(ERROR, TAG, "jni_mid_accept is null"); return; } - OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept..."); + OIC_LOG(DEBUG, TAG, "initiating accept..."); jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject, jni_mid_accept); if (!jni_obj_BTSocket) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null"); + OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null"); if ((*env)->ExceptionCheck(env)) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!"); + OIC_LOG(ERROR, TAG, "socket might closed or timeout!!!"); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); return; @@ -1045,12 +1032,12 @@ void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject) jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket); if (!j_str_address) { - OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null"); + OIC_LOG(ERROR, TAG, "j_str_address is null"); return; } const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL); - OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address); + OIC_LOG_V(DEBUG, TAG, "address is %s", address); // set socket to list jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket); @@ -1058,56 +1045,51 @@ void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject) CAEDRNativeAddDeviceSocketToList(env, jni_socket); ca_mutex_unlock(g_mutexObjectList); - OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!"); + OIC_LOG(DEBUG, TAG, "Accepted!!"); // update state ca_mutex_lock(g_mutexStateList); CAEDRUpdateDeviceState(STATE_CONNECTED, address); ca_mutex_unlock(g_mutexStateList); + (*env)->ReleaseStringUTFChars(env, j_str_address, address); + (*env)->DeleteLocalRef(env, j_str_address); } else { - OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously"); + OIC_LOG(DEBUG, TAG, "serverSocket is close previously"); } + + OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - OUT"); } /** - * InputStream & BluetoothServerSocket will be close for Terminating + * InputStream & BluetoothServerSocket will be close for Terminating. */ 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); - } - if (g_serverSocket) { - OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close"); + OIC_LOG(DEBUG, TAG, "Accept Resource will be close"); jclass jni_cid_BTServerSocket = (*env)->FindClass( env, "android/bluetooth/BluetoothServerSocket"); if (!jni_cid_BTServerSocket) { - OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null"); + OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null"); return; } jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V"); if (!jni_mid_accept) { - OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null"); + OIC_LOG(ERROR, TAG, "jni_mid_accept is null"); return; } (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept); (*env)->DeleteGlobalRef(env, g_serverSocket); + g_serverSocket = NULL; - OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj"); + OIC_LOG(DEBUG, TAG, "close accept obj"); } } -