1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "caedrinterface.h"
27 #include "caedrutils.h"
28 #include "caedrserver.h"
30 #include "oic_malloc.h"
31 #include "cathreadpool.h" /* for thread pool */
33 #include "uarraylist.h"
34 #include "caadapterutils.h"
35 #include "org_iotivity_jar_caedrinterface.h"
38 #define TAG PCF("CA_EDR_SERVER")
39 #define MAX_PDU_BUFFER (1024)
41 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
42 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
43 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
45 static ca_thread_pool_t g_threadPoolHandle = NULL;
50 * @var g_mMutexSocketListManager
51 * @brief Mutex to synchronize socket list update
53 static ca_mutex g_mutexSocketListManager;
55 // server socket instance
56 static jobject g_serverSocketObject = NULL;
59 * @var g_mutexUnicastServer
60 * @brief Mutex to synchronize unicast server
62 static ca_mutex g_mutexUnicastServer = NULL;
66 * @brief Flag to control the Receive Unicast Data Thread
68 static bool g_stopUnicast = false;
71 * @var g_mutexMulticastServer
72 * @brief Mutex to synchronize secure multicast server
74 static ca_mutex g_mutexMulticastServer = NULL;
77 * @var g_stopMulticast
78 * @brief Flag to control the Receive Multicast Data Thread
80 static bool g_stopMulticast = false;
83 * @var g_mutexAcceptServer
84 * @brief Mutex to synchronize accept server
86 static ca_mutex g_mutexAcceptServer = NULL;
90 * @brief Flag to control the Accept Thread
92 static bool g_stopAccept = false;
94 static jobject g_inputStream = NULL;
97 * @var g_mutexServerSocket
98 * @brief Mutex to synchronize server socket
100 static ca_mutex g_mutexServerSocket = NULL;
102 static jobject g_serverSocket = NULL;
105 * @var g_mutexStateList
106 * @brief Mutex to synchronize device state list
108 static ca_mutex g_mutexStateList = NULL;
111 * @var g_mutexObjectList
112 * @brief Mutex to synchronize device object list
114 static ca_mutex g_mutexObjectList = NULL;
116 typedef struct send_data
124 @brief Thread context information for unicast, multicast and secured unicast server
129 CAAdapterServerType_t type;
130 } CAAdapterReceiveThreadContext_t;
135 } CAAdapterAcceptThreadContext_t;
138 * @var g_edrPacketReceivedCallback
139 * @brief Maintains the callback to be notified when data received from remote Bluetooth device
141 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
143 static void CAReceiveHandler(void *data)
145 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
147 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
149 bool isAttached = false;
151 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
154 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
155 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
159 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
165 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
167 while (true != *(ctx->stopFlag))
169 // if new socket object is added in socket list after below logic is ran.
170 // new socket will be started to read after next while loop
171 uint32_t length = CAEDRGetSocketListLength();
174 OIC_LOG(DEBUG, TAG, "socket list is empty");
179 for (idx = 0; idx < length; idx++)
181 OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
182 CAEDRNativeReadData(env, idx, ctx->type);
189 (*g_jvm)->DetachCurrentThread(g_jvm);
194 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
197 static void CAAcceptHandler(void *data)
201 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
205 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
207 bool isAttached = false;
209 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
212 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
213 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
217 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
223 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
224 if (!jni_obj_BTServerSocket)
226 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
230 (*g_jvm)->DetachCurrentThread(g_jvm);
236 ca_mutex_lock(g_mutexServerSocket);
237 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
238 ca_mutex_unlock(g_mutexServerSocket);
240 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
244 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null");
247 (*g_jvm)->DetachCurrentThread(g_jvm);
252 // it should be initialized for restart accept thread
253 ca_mutex_lock(g_mutexAcceptServer);
254 g_stopAccept = false;
255 ca_mutex_unlock(g_mutexAcceptServer);
257 while (true != *(ctx->stopFlag))
259 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
261 // when BT state is changed with Off. its thread will be stopped
262 if (!CAEDRNativeIsEnableBTAdapter(env))
264 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
265 ca_mutex_lock(g_mutexAcceptServer);
267 ca_mutex_unlock(g_mutexAcceptServer);
268 ca_mutex_lock(g_mutexServerSocket);
269 g_serverSocket = NULL;
270 ca_mutex_unlock(g_mutexServerSocket);
274 CAEDRNativeAccept(env, g_serverSocket);
280 (*g_jvm)->DetachCurrentThread(g_jvm);
285 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
291 * implement for adapter common method
293 CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, ca_thread_pool_t handle)
295 OIC_LOG(DEBUG, TAG, "IN");
296 CAEDRServerInitialize(handle);
297 CAResult_t res = CAEDRStartUnicastServer(false);
298 if (CA_STATUS_OK != res)
300 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
301 return CA_STATUS_FAILED;
305 OIC_LOG(DEBUG, TAG, "OUT");
309 CAResult_t CAEDRServerStop(int serverFD)
311 OIC_LOG(DEBUG, TAG, "IN");
312 CAEDRStopUnicastServer(-1);
313 CAEDRStopMulticastServer(-1);
315 ca_mutex_lock(g_mutexAcceptServer);
317 ca_mutex_unlock(g_mutexAcceptServer);
321 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
322 return CA_STATUS_FAILED;
325 bool isAttached = false;
327 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
330 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
331 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
335 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
336 return CA_STATUS_FAILED;
341 CAEDRNatvieCloseServerTask(env);
345 (*g_jvm)->DetachCurrentThread(g_jvm);
348 OIC_LOG(DEBUG, TAG, "OUT");
352 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
354 g_edrPacketReceivedCallback = packetReceivedCallback;
360 static void CAEDRServerDestroyMutex()
362 OIC_LOG(DEBUG, TAG, "IN");
364 if (g_mutexUnicastServer)
366 ca_mutex_free(g_mutexUnicastServer);
367 g_mutexUnicastServer = NULL;
370 if (g_mutexMulticastServer)
372 ca_mutex_free(g_mutexMulticastServer);
373 g_mutexMulticastServer = NULL;
376 if (g_mutexSocketListManager)
378 ca_mutex_free(g_mutexSocketListManager);
379 g_mutexSocketListManager = NULL;
382 if (g_mutexAcceptServer)
384 ca_mutex_free(g_mutexAcceptServer);
385 g_mutexAcceptServer = NULL;
388 if (g_mutexServerSocket)
390 ca_mutex_free(g_mutexServerSocket);
391 g_mutexServerSocket = NULL;
394 if (g_mutexStateList)
396 ca_mutex_free(g_mutexStateList);
397 g_mutexStateList = NULL;
400 if (g_mutexObjectList)
402 ca_mutex_free(g_mutexObjectList);
403 g_mutexObjectList = NULL;
406 OIC_LOG(DEBUG, TAG, "OUT");
412 static CAResult_t CAEDRServerCreateMutex()
414 OIC_LOG(DEBUG, TAG, "IN");
416 g_mutexUnicastServer = ca_mutex_new();
417 if (!g_mutexUnicastServer)
419 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
420 return CA_STATUS_FAILED;
423 g_mutexMulticastServer = ca_mutex_new();
424 if (!g_mutexMulticastServer)
426 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
428 CAEDRServerDestroyMutex();
429 return CA_STATUS_FAILED;
432 g_mutexSocketListManager = ca_mutex_new();
433 if (!g_mutexSocketListManager)
435 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
437 CAEDRServerDestroyMutex();
438 return CA_STATUS_FAILED;
441 g_mutexAcceptServer = ca_mutex_new();
442 if (!g_mutexAcceptServer)
444 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
446 CAEDRServerDestroyMutex();
447 return CA_STATUS_FAILED;
450 g_mutexServerSocket = ca_mutex_new();
451 if (!g_mutexServerSocket)
453 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
455 CAEDRServerDestroyMutex();
456 return CA_STATUS_FAILED;
459 g_mutexStateList = ca_mutex_new();
460 if (!g_mutexStateList)
462 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
464 CAEDRServerDestroyMutex();
465 return CA_STATUS_FAILED;
468 g_mutexObjectList = ca_mutex_new();
469 if (!g_mutexObjectList)
471 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
473 CAEDRServerDestroyMutex();
474 return CA_STATUS_FAILED;
477 OIC_LOG(DEBUG, TAG, "OUT");
481 void CAEDRServerJniInit()
483 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
484 g_jvm = CANativeJNIGetJavaVM();
487 void CAEDRServerInitialize(ca_thread_pool_t handle)
489 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
491 g_threadPoolHandle = handle;
493 CAEDRServerStartAcceptThread();
495 OIC_LOG(DEBUG, TAG, "OUT");
498 void CAEDRServerStartAcceptThread()
500 CAEDRServerJniInit();
503 CAEDRServerCreateMutex();
505 bool isAttached = false;
507 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
510 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
511 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
515 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
521 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
524 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
525 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
526 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
529 ca_mutex_lock(g_mutexStateList);
530 CAEDRNativeCreateDeviceStateList();
531 ca_mutex_unlock(g_mutexStateList);
533 ca_mutex_lock(g_mutexObjectList);
534 CAEDRNativeCreateDeviceSocketList();
535 ca_mutex_unlock(g_mutexObjectList);
539 (*g_jvm)->DetachCurrentThread(g_jvm);
542 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
543 sizeof(CAAdapterReceiveThreadContext_t));
546 OIC_LOG(ERROR, TAG, "Out of memory!");
550 ctx->stopFlag = &g_stopAccept;
551 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
553 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
554 OICFree((void *) ctx);
558 OIC_LOG(DEBUG, TAG, "OUT");
561 void CAEDRServerTerminate()
563 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
569 bool isAttached = false;
571 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
574 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
575 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
579 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
585 CAEDRNativeSocketCloseToAll(env);
589 (*g_jvm)->DetachCurrentThread(g_jvm);
592 CAEDRNativeRemoveAllDeviceState();
593 CAEDRNativeRemoveAllDeviceSocket(env);
596 CAEDRServerDestroyMutex();
599 CAResult_t CAEDRStartUnicastServer(bool isSecured)
601 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
603 ca_mutex_lock(g_mutexUnicastServer);
606 * The task to listen for data from unicast is added to the thread pool.
607 * This is a blocking call is made where we try to receive some data..
608 * We will keep waiting until some data is received.
609 * This task will be terminated when thread pool is freed on stopping the adapters.
610 * Thread context will be freed by thread on exit.
612 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
613 sizeof(CAAdapterReceiveThreadContext_t));
616 OIC_LOG(ERROR, TAG, "Out of memory!");
617 ca_mutex_unlock(g_mutexUnicastServer);
618 return CA_MEMORY_ALLOC_FAILED;
621 ctx->stopFlag = &g_stopUnicast;
622 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
623 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
625 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
626 ca_mutex_unlock(g_mutexUnicastServer);
627 OICFree((void *) ctx);
628 return CA_STATUS_FAILED;
630 ca_mutex_unlock(g_mutexUnicastServer);
632 OIC_LOG(DEBUG, TAG, "OUT");
636 CAResult_t CAEDRStartMulticastServer(bool isSecured)
638 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
640 ca_mutex_lock(g_mutexMulticastServer);
643 * The task to listen to data from multicast socket is added to the thread pool.
644 * This is a blocking call is made where we try to receive some data.
645 * We will keep waiting until some data is received.
646 * This task will be terminated when thread pool is freed on stopping the adapters.
647 * Thread context will be freed by thread on exit.
649 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
650 sizeof(CAAdapterReceiveThreadContext_t));
653 OIC_LOG(ERROR, TAG, "Out of memory!");
654 ca_mutex_unlock(g_mutexMulticastServer);
656 return CA_MEMORY_ALLOC_FAILED;
659 ctx->stopFlag = &g_stopMulticast;
660 ctx->type = CA_MULTICAST_SERVER;
662 g_stopMulticast = false;
663 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
665 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
667 g_stopMulticast = true;
668 ca_mutex_unlock(g_mutexMulticastServer);
669 OICFree((void *) ctx);
671 return CA_STATUS_FAILED;
673 ca_mutex_unlock(g_mutexMulticastServer);
675 OIC_LOG(DEBUG, TAG, "OUT");
679 CAResult_t CAEDRStopUnicastServer(int32_t serverID)
681 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
683 ca_mutex_lock(g_mutexUnicastServer);
684 g_stopUnicast = true;
685 ca_mutex_unlock(g_mutexUnicastServer);
690 CAResult_t CAEDRStopMulticastServer(int32_t serverID)
692 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
694 ca_mutex_lock(g_mutexMulticastServer);
695 g_stopMulticast = true;
696 ca_mutex_unlock(g_mutexMulticastServer);
698 OIC_LOG(INFO, TAG, "Multicast server stopped");
703 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
705 if (!CAEDRNativeIsEnableBTAdapter(env))
707 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
708 return CA_STATUS_INVALID_PARAM;
711 if (!((*env)->ExceptionCheck(env)))
713 // check whether this socket object is connected or not.
714 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
717 return CA_STATUS_INVALID_PARAM;
720 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
721 if (!jni_str_address)
723 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
724 return CA_STATUS_FAILED;
726 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
728 // check it whether is still connected or not through google api
729 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
732 OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket");
735 // check it whether is still connected or not through socket state list
736 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
738 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet..");
740 // remove socket to list
741 // this code is related to below read fail exception code
742 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
743 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
745 return CA_STATUS_FAILED;
748 // start to read through InputStream
749 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
750 if (!jni_cid_BTsocket)
752 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
753 return CA_STATUS_FAILED;
755 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
757 "()Ljava/io/InputStream;");
758 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
762 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
763 return CA_STATUS_FAILED;
766 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
767 jni_mid_getInputStream);
768 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
770 g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
772 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
773 if (!jni_cid_InputStream)
775 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
776 return CA_STATUS_FAILED;
778 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
780 jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
784 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
785 return CA_STATUS_FAILED;
788 jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
791 OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
795 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
796 return CA_STATUS_FAILED;
799 if ((*env)->ExceptionCheck(env))
801 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
802 (*env)->ExceptionDescribe(env);
803 (*env)->ExceptionClear(env);
805 // update state to disconnect
806 // the socket will be close next read thread routine
807 ca_mutex_lock(g_mutexStateList);
808 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
809 ca_mutex_unlock(g_mutexStateList);
810 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
811 return CA_STATUS_FAILED;
814 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
815 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
818 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
819 return CA_STATUS_FAILED;
822 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
824 char responseData[MAX_PDU_BUFFER] = { 0 };
825 memcpy(responseData, (const char*) buf, length);
829 case CA_UNICAST_SERVER:
830 case CA_MULTICAST_SERVER:
831 // Notify data to upper layer
832 if (g_edrPacketReceivedCallback)
834 uint32_t sentLength = 0;
835 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
836 %s, %d", responseData, length);
837 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
842 // Should never occur
843 OIC_LOG(ERROR, TAG, "Invalid server type");
844 return CA_STATUS_FAILED;
846 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
847 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
851 (*env)->ExceptionDescribe(env);
852 (*env)->ExceptionClear(env);
853 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
854 return CA_STATUS_FAILED;
860 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
862 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
864 if (!CAEDRNativeIsEnableBTAdapter(env))
866 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
872 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
876 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
877 if (!jni_cid_BTsocket)
879 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
883 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
885 if (!jni_mid_isConnected)
887 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
888 - jni_mid_isConnected is null.");
892 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
894 return jni_isConnected;
897 void CANativeStartListenTask(JNIEnv *env)
899 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
900 if (!jni_obj_BTServerSocket)
902 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
906 ca_mutex_lock(g_mutexServerSocket);
907 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
908 ca_mutex_unlock(g_mutexServerSocket);
911 jobject CAEDRNativeListen(JNIEnv *env)
913 if (!CAEDRNativeIsEnableBTAdapter(env))
915 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
919 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
921 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
922 if (!jni_cid_BTAdapter)
924 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
929 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
931 METHODID_OBJECTNONPARAM);
932 if (!jni_cid_BTAdapter)
934 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
938 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
939 jni_mid_getDefaultAdapter);
940 if (!jni_obj_BTAdapter)
942 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
946 // get listen method ID
947 jmethodID jni_mid_listen = (*env)->GetMethodID(
948 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
949 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
952 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
955 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
957 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
960 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
964 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
965 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
966 if (!jni_mid_fromString)
968 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
972 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
975 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
978 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
982 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
987 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
990 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
993 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
994 jni_name, jni_obj_uuid);
995 if (!jni_obj_BTServerSocket)
997 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1001 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1003 return jni_obj_BTServerSocket;
1006 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1008 if (NULL != serverSocketObject)
1010 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1011 env, "android/bluetooth/BluetoothServerSocket");
1012 if (!jni_cid_BTServerSocket)
1014 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1018 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1019 "()Landroid/bluetooth/BluetoothSocket;");
1020 if (!jni_mid_accept)
1022 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1026 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1028 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1030 if (!jni_obj_BTSocket)
1032 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1034 if ((*env)->ExceptionCheck(env))
1036 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1037 (*env)->ExceptionDescribe(env);
1038 (*env)->ExceptionClear(env);
1043 // get remote address
1044 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1047 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1051 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1052 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1054 // set socket to list
1055 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1056 ca_mutex_lock(g_mutexObjectList);
1057 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1058 ca_mutex_unlock(g_mutexObjectList);
1060 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1063 ca_mutex_lock(g_mutexStateList);
1064 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1065 ca_mutex_unlock(g_mutexStateList);
1066 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1070 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1075 * InputStream & BluetoothServerSocket will be close for Terminating
1077 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1081 OIC_LOG(DEBUG, TAG, "InputStream will be close");
1082 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1083 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1084 (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1085 (*env)->DeleteGlobalRef(env, g_inputStream);
1090 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1092 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1093 env, "android/bluetooth/BluetoothServerSocket");
1094 if (!jni_cid_BTServerSocket)
1096 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1100 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1101 if (!jni_mid_accept)
1103 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1106 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1107 (*env)->DeleteGlobalRef(env, g_serverSocket);
1109 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");