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_ca_CaEdrInterface.h"
36 #include "oic_string.h"
39 #define TAG PCF("CA_EDR_SERVER")
40 #define MAX_PDU_BUFFER (1024)
42 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
43 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
44 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
46 static ca_thread_pool_t g_threadPoolHandle = NULL;
51 * @var g_mMutexSocketListManager
52 * @brief Mutex to synchronize socket list update
54 static ca_mutex g_mutexSocketListManager;
56 // server socket instance
57 static jobject g_serverSocketObject = NULL;
60 * @var g_mutexUnicastServer
61 * @brief Mutex to synchronize unicast server
63 static ca_mutex g_mutexUnicastServer = NULL;
67 * @brief Flag to control the Receive Unicast Data Thread
69 static bool g_stopUnicast = false;
72 * @var g_mutexMulticastServer
73 * @brief Mutex to synchronize secure multicast server
75 static ca_mutex g_mutexMulticastServer = NULL;
78 * @var g_stopMulticast
79 * @brief Flag to control the Receive Multicast Data Thread
81 static bool g_stopMulticast = false;
84 * @var g_mutexAcceptServer
85 * @brief Mutex to synchronize accept server
87 static ca_mutex g_mutexAcceptServer = NULL;
91 * @brief Flag to control the Accept Thread
93 static bool g_stopAccept = false;
95 static jobject g_inputStream = NULL;
98 * @var g_mutexServerSocket
99 * @brief Mutex to synchronize server socket
101 static ca_mutex g_mutexServerSocket = NULL;
103 static jobject g_serverSocket = NULL;
106 * @var g_mutexStateList
107 * @brief Mutex to synchronize device state list
109 static ca_mutex g_mutexStateList = NULL;
112 * @var g_mutexObjectList
113 * @brief Mutex to synchronize device object list
115 static ca_mutex g_mutexObjectList = NULL;
117 typedef struct send_data
125 @brief Thread context information for unicast, multicast and secured unicast server
130 CAAdapterServerType_t type;
131 } CAAdapterReceiveThreadContext_t;
136 } CAAdapterAcceptThreadContext_t;
139 * @var g_edrPacketReceivedCallback
140 * @brief Maintains the callback to be notified when data received from remote Bluetooth device
142 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
144 static void CAReceiveHandler(void *data)
146 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
148 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
150 bool isAttached = false;
152 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
155 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
156 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
160 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
166 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
168 while (true != *(ctx->stopFlag))
170 // if new socket object is added in socket list after below logic is ran.
171 // new socket will be started to read after next while loop
172 uint32_t length = CAEDRGetSocketListLength();
175 OIC_LOG(DEBUG, TAG, "socket list is empty");
180 for (idx = 0; idx < length; idx++)
182 OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
183 CAEDRNativeReadData(env, idx, ctx->type);
190 (*g_jvm)->DetachCurrentThread(g_jvm);
195 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
198 static void CAAcceptHandler(void *data)
202 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
206 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
208 bool isAttached = false;
210 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
213 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
214 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
218 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
224 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
225 if (!jni_obj_BTServerSocket)
227 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
231 (*g_jvm)->DetachCurrentThread(g_jvm);
237 ca_mutex_lock(g_mutexServerSocket);
238 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
239 ca_mutex_unlock(g_mutexServerSocket);
241 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
245 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null");
248 (*g_jvm)->DetachCurrentThread(g_jvm);
253 // it should be initialized for restart accept thread
254 ca_mutex_lock(g_mutexAcceptServer);
255 g_stopAccept = false;
256 ca_mutex_unlock(g_mutexAcceptServer);
258 while (true != *(ctx->stopFlag))
260 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
262 // when BT state is changed with Off. its thread will be stopped
263 if (!CAEDRNativeIsEnableBTAdapter(env))
265 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
266 ca_mutex_lock(g_mutexAcceptServer);
268 ca_mutex_unlock(g_mutexAcceptServer);
269 ca_mutex_lock(g_mutexServerSocket);
270 g_serverSocket = NULL;
271 ca_mutex_unlock(g_mutexServerSocket);
275 CAEDRNativeAccept(env, g_serverSocket);
281 (*g_jvm)->DetachCurrentThread(g_jvm);
286 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
292 * implement for adapter common method
294 CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, ca_thread_pool_t handle)
296 OIC_LOG(DEBUG, TAG, "IN");
297 CAEDRServerInitialize(handle);
298 CAResult_t res = CAEDRStartUnicastServer(false);
299 if (CA_STATUS_OK != res)
301 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
302 return CA_STATUS_FAILED;
306 OIC_LOG(DEBUG, TAG, "OUT");
310 CAResult_t CAEDRServerStop(int serverFD)
312 OIC_LOG(DEBUG, TAG, "IN");
313 CAEDRStopUnicastServer(-1);
314 CAEDRStopMulticastServer(-1);
316 ca_mutex_lock(g_mutexAcceptServer);
318 ca_mutex_unlock(g_mutexAcceptServer);
322 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
323 return CA_STATUS_FAILED;
326 bool isAttached = false;
328 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
331 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
332 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
336 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
337 return CA_STATUS_FAILED;
342 CAEDRNatvieCloseServerTask(env);
346 (*g_jvm)->DetachCurrentThread(g_jvm);
349 OIC_LOG(DEBUG, TAG, "OUT");
353 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
355 g_edrPacketReceivedCallback = packetReceivedCallback;
361 static void CAEDRServerDestroyMutex()
363 OIC_LOG(DEBUG, TAG, "IN");
365 if (g_mutexUnicastServer)
367 ca_mutex_free(g_mutexUnicastServer);
368 g_mutexUnicastServer = NULL;
371 if (g_mutexMulticastServer)
373 ca_mutex_free(g_mutexMulticastServer);
374 g_mutexMulticastServer = NULL;
377 if (g_mutexSocketListManager)
379 ca_mutex_free(g_mutexSocketListManager);
380 g_mutexSocketListManager = NULL;
383 if (g_mutexAcceptServer)
385 ca_mutex_free(g_mutexAcceptServer);
386 g_mutexAcceptServer = NULL;
389 if (g_mutexServerSocket)
391 ca_mutex_free(g_mutexServerSocket);
392 g_mutexServerSocket = NULL;
395 if (g_mutexStateList)
397 ca_mutex_free(g_mutexStateList);
398 g_mutexStateList = NULL;
401 if (g_mutexObjectList)
403 ca_mutex_free(g_mutexObjectList);
404 g_mutexObjectList = NULL;
407 OIC_LOG(DEBUG, TAG, "OUT");
413 static CAResult_t CAEDRServerCreateMutex()
415 OIC_LOG(DEBUG, TAG, "IN");
417 g_mutexUnicastServer = ca_mutex_new();
418 if (!g_mutexUnicastServer)
420 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
421 return CA_STATUS_FAILED;
424 g_mutexMulticastServer = ca_mutex_new();
425 if (!g_mutexMulticastServer)
427 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
429 CAEDRServerDestroyMutex();
430 return CA_STATUS_FAILED;
433 g_mutexSocketListManager = ca_mutex_new();
434 if (!g_mutexSocketListManager)
436 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
438 CAEDRServerDestroyMutex();
439 return CA_STATUS_FAILED;
442 g_mutexAcceptServer = ca_mutex_new();
443 if (!g_mutexAcceptServer)
445 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
447 CAEDRServerDestroyMutex();
448 return CA_STATUS_FAILED;
451 g_mutexServerSocket = ca_mutex_new();
452 if (!g_mutexServerSocket)
454 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
456 CAEDRServerDestroyMutex();
457 return CA_STATUS_FAILED;
460 g_mutexStateList = ca_mutex_new();
461 if (!g_mutexStateList)
463 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
465 CAEDRServerDestroyMutex();
466 return CA_STATUS_FAILED;
469 g_mutexObjectList = ca_mutex_new();
470 if (!g_mutexObjectList)
472 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
474 CAEDRServerDestroyMutex();
475 return CA_STATUS_FAILED;
478 OIC_LOG(DEBUG, TAG, "OUT");
482 void CAEDRServerJniInit()
484 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
485 g_jvm = CANativeJNIGetJavaVM();
488 void CAEDRServerInitialize(ca_thread_pool_t handle)
490 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
492 g_threadPoolHandle = handle;
494 CAEDRServerStartAcceptThread();
496 OIC_LOG(DEBUG, TAG, "OUT");
499 void CAEDRServerStartAcceptThread()
501 CAEDRServerJniInit();
504 CAEDRServerCreateMutex();
506 bool isAttached = false;
508 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
511 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
512 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
516 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
522 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
525 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
526 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
527 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
530 ca_mutex_lock(g_mutexStateList);
531 CAEDRNativeCreateDeviceStateList();
532 ca_mutex_unlock(g_mutexStateList);
534 ca_mutex_lock(g_mutexObjectList);
535 CAEDRNativeCreateDeviceSocketList();
536 ca_mutex_unlock(g_mutexObjectList);
540 (*g_jvm)->DetachCurrentThread(g_jvm);
543 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
544 sizeof(CAAdapterReceiveThreadContext_t));
547 OIC_LOG(ERROR, TAG, "Out of memory!");
551 ctx->stopFlag = &g_stopAccept;
552 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
554 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
555 OICFree((void *) ctx);
559 OIC_LOG(DEBUG, TAG, "OUT");
562 void CAEDRServerTerminate()
564 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
570 bool isAttached = false;
572 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
575 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
576 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
580 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
586 CAEDRNativeSocketCloseToAll(env);
590 (*g_jvm)->DetachCurrentThread(g_jvm);
593 CAEDRNativeRemoveAllDeviceState();
594 CAEDRNativeRemoveAllDeviceSocket(env);
597 CAEDRServerDestroyMutex();
600 CAResult_t CAEDRStartUnicastServer(bool isSecured)
602 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
604 ca_mutex_lock(g_mutexUnicastServer);
607 * The task to listen for data from unicast is added to the thread pool.
608 * This is a blocking call is made where we try to receive some data..
609 * We will keep waiting until some data is received.
610 * This task will be terminated when thread pool is freed on stopping the adapters.
611 * Thread context will be freed by thread on exit.
613 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
614 sizeof(CAAdapterReceiveThreadContext_t));
617 OIC_LOG(ERROR, TAG, "Out of memory!");
618 ca_mutex_unlock(g_mutexUnicastServer);
619 return CA_MEMORY_ALLOC_FAILED;
622 ctx->stopFlag = &g_stopUnicast;
623 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
624 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
626 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
627 ca_mutex_unlock(g_mutexUnicastServer);
628 OICFree((void *) ctx);
629 return CA_STATUS_FAILED;
631 ca_mutex_unlock(g_mutexUnicastServer);
633 OIC_LOG(DEBUG, TAG, "OUT");
637 CAResult_t CAEDRStartMulticastServer(bool isSecured)
639 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
641 ca_mutex_lock(g_mutexMulticastServer);
644 * The task to listen to data from multicast socket is added to the thread pool.
645 * This is a blocking call is made where we try to receive some data.
646 * We will keep waiting until some data is received.
647 * This task will be terminated when thread pool is freed on stopping the adapters.
648 * Thread context will be freed by thread on exit.
650 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
651 sizeof(CAAdapterReceiveThreadContext_t));
654 OIC_LOG(ERROR, TAG, "Out of memory!");
655 ca_mutex_unlock(g_mutexMulticastServer);
657 return CA_MEMORY_ALLOC_FAILED;
660 ctx->stopFlag = &g_stopMulticast;
661 ctx->type = CA_MULTICAST_SERVER;
663 g_stopMulticast = false;
664 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
666 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
668 g_stopMulticast = true;
669 ca_mutex_unlock(g_mutexMulticastServer);
670 OICFree((void *) ctx);
672 return CA_STATUS_FAILED;
674 ca_mutex_unlock(g_mutexMulticastServer);
676 OIC_LOG(DEBUG, TAG, "OUT");
680 CAResult_t CAEDRStopUnicastServer(int32_t serverID)
682 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
684 ca_mutex_lock(g_mutexUnicastServer);
685 g_stopUnicast = true;
686 ca_mutex_unlock(g_mutexUnicastServer);
691 CAResult_t CAEDRStopMulticastServer(int32_t serverID)
693 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
695 ca_mutex_lock(g_mutexMulticastServer);
696 g_stopMulticast = true;
697 ca_mutex_unlock(g_mutexMulticastServer);
699 OIC_LOG(INFO, TAG, "Multicast server stopped");
704 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
706 if (!CAEDRNativeIsEnableBTAdapter(env))
708 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
709 return CA_STATUS_INVALID_PARAM;
712 if (!((*env)->ExceptionCheck(env)))
714 // check whether this socket object is connected or not.
715 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
718 return CA_STATUS_INVALID_PARAM;
721 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
722 if (!jni_str_address)
724 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
725 return CA_STATUS_FAILED;
727 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
729 // check it whether is still connected or not through google api
730 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
733 OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket");
736 // check it whether is still connected or not through socket state list
737 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
739 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet..");
741 // remove socket to list
742 // this code is related to below read fail exception code
743 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
744 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
746 return CA_STATUS_FAILED;
749 // start to read through InputStream
750 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
751 if (!jni_cid_BTsocket)
753 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
754 return CA_STATUS_FAILED;
756 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
758 "()Ljava/io/InputStream;");
759 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
763 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
764 return CA_STATUS_FAILED;
767 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
768 jni_mid_getInputStream);
769 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
771 g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
773 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
774 if (!jni_cid_InputStream)
776 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
777 return CA_STATUS_FAILED;
779 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
781 jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
785 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
786 return CA_STATUS_FAILED;
789 jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
792 OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
796 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
797 return CA_STATUS_FAILED;
800 if ((*env)->ExceptionCheck(env))
802 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
803 (*env)->ExceptionDescribe(env);
804 (*env)->ExceptionClear(env);
806 // update state to disconnect
807 // the socket will be close next read thread routine
808 ca_mutex_lock(g_mutexStateList);
809 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
810 ca_mutex_unlock(g_mutexStateList);
811 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
812 return CA_STATUS_FAILED;
815 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
816 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
819 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
820 return CA_STATUS_FAILED;
823 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
825 char responseData[MAX_PDU_BUFFER] = { 0 };
826 OICStrcpyPartial(responseData, sizeof(responseData), buf, length);
830 case CA_UNICAST_SERVER:
831 case CA_MULTICAST_SERVER:
832 // Notify data to upper layer
833 if (g_edrPacketReceivedCallback)
835 uint32_t sentLength = 0;
836 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
837 %s, %d", responseData, length);
838 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
843 // Should never occur
844 OIC_LOG(ERROR, TAG, "Invalid server type");
845 return CA_STATUS_FAILED;
847 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
848 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
852 (*env)->ExceptionDescribe(env);
853 (*env)->ExceptionClear(env);
854 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
855 return CA_STATUS_FAILED;
861 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
863 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
865 if (!CAEDRNativeIsEnableBTAdapter(env))
867 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
873 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
877 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
878 if (!jni_cid_BTsocket)
880 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
884 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
886 if (!jni_mid_isConnected)
888 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
889 - jni_mid_isConnected is null.");
893 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
895 return jni_isConnected;
898 void CANativeStartListenTask(JNIEnv *env)
900 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
901 if (!jni_obj_BTServerSocket)
903 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
907 ca_mutex_lock(g_mutexServerSocket);
908 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
909 ca_mutex_unlock(g_mutexServerSocket);
912 jobject CAEDRNativeListen(JNIEnv *env)
914 if (!CAEDRNativeIsEnableBTAdapter(env))
916 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
920 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
922 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
923 if (!jni_cid_BTAdapter)
925 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
930 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
932 METHODID_OBJECTNONPARAM);
933 if (!jni_cid_BTAdapter)
935 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
939 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
940 jni_mid_getDefaultAdapter);
941 if (!jni_obj_BTAdapter)
943 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
947 // get listen method ID
948 jmethodID jni_mid_listen = (*env)->GetMethodID(
949 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
950 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
953 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
956 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
958 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
961 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
965 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
966 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
967 if (!jni_mid_fromString)
969 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
973 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
976 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
979 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
983 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
988 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
991 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
994 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
995 jni_name, jni_obj_uuid);
996 if (!jni_obj_BTServerSocket)
998 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1002 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1004 return jni_obj_BTServerSocket;
1007 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1009 if (NULL != serverSocketObject)
1011 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1012 env, "android/bluetooth/BluetoothServerSocket");
1013 if (!jni_cid_BTServerSocket)
1015 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1019 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1020 "()Landroid/bluetooth/BluetoothSocket;");
1021 if (!jni_mid_accept)
1023 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1027 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1029 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1031 if (!jni_obj_BTSocket)
1033 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1035 if ((*env)->ExceptionCheck(env))
1037 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1038 (*env)->ExceptionDescribe(env);
1039 (*env)->ExceptionClear(env);
1044 // get remote address
1045 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1048 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1052 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1053 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1055 // set socket to list
1056 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1057 ca_mutex_lock(g_mutexObjectList);
1058 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1059 ca_mutex_unlock(g_mutexObjectList);
1061 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1064 ca_mutex_lock(g_mutexStateList);
1065 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1066 ca_mutex_unlock(g_mutexStateList);
1067 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1071 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1076 * InputStream & BluetoothServerSocket will be close for Terminating
1078 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1082 OIC_LOG(DEBUG, TAG, "InputStream will be close");
1083 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1084 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1085 (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1086 (*env)->DeleteGlobalRef(env, g_inputStream);
1091 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1093 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1094 env, "android/bluetooth/BluetoothServerSocket");
1095 if (!jni_cid_BTServerSocket)
1097 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1101 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1102 if (!jni_mid_accept)
1104 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1107 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1108 (*env)->DeleteGlobalRef(env, g_serverSocket);
1110 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");