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 * Mutex to synchronize socket list update.
53 static ca_mutex g_mutexSocketListManager;
56 * server socket instance.
58 static jobject g_serverSocketObject = NULL;
61 * Mutex to synchronize unicast server.
63 static ca_mutex g_mutexUnicastServer = NULL;
66 * Flag to control the Receive Unicast Data Thread.
68 static bool g_stopUnicast = false;
71 * Mutex to synchronize secure multicast server.
73 static ca_mutex g_mutexMulticastServer = NULL;
76 * Flag to control the Receive Multicast Data Thread.
78 static bool g_stopMulticast = false;
81 * Mutex to synchronize accept server.
83 static ca_mutex g_mutexAcceptServer = NULL;
86 * Flag to control the Accept Thread.
88 static bool g_stopAccept = false;
90 static jobject g_inputStream = NULL;
93 * Mutex to synchronize server socket.
95 static ca_mutex g_mutexServerSocket = NULL;
97 static jobject g_serverSocket = NULL;
100 * Mutex to synchronize device state list.
102 static ca_mutex g_mutexStateList = NULL;
105 * Mutex to synchronize device object list.
107 static ca_mutex g_mutexObjectList = NULL;
109 typedef struct send_data
117 * Thread context information for unicast, multicast and secured unicast server.
122 CAAdapterServerType_t type;
123 } CAAdapterReceiveThreadContext_t;
128 } CAAdapterAcceptThreadContext_t;
131 * Maintains the callback to be notified when data received from remote
134 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
136 static void CAReceiveHandler(void *data)
138 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
140 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
142 bool isAttached = false;
144 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
147 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
148 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
152 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
158 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
160 while (true != *(ctx->stopFlag))
162 // if new socket object is added in socket list after below logic is ran.
163 // new socket will be started to read after next while loop
164 uint32_t length = CAEDRGetSocketListLength();
167 OIC_LOG(DEBUG, TAG, "socket list is empty");
172 for (idx = 0; idx < length; idx++)
174 OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
175 CAEDRNativeReadData(env, idx, ctx->type);
182 (*g_jvm)->DetachCurrentThread(g_jvm);
187 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
190 static void CAAcceptHandler(void *data)
194 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
198 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
200 bool isAttached = false;
202 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
205 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
206 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
210 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
216 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
217 if (!jni_obj_BTServerSocket)
219 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
223 (*g_jvm)->DetachCurrentThread(g_jvm);
229 ca_mutex_lock(g_mutexServerSocket);
230 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
231 ca_mutex_unlock(g_mutexServerSocket);
233 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
237 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null");
240 (*g_jvm)->DetachCurrentThread(g_jvm);
245 // it should be initialized for restart accept thread
246 ca_mutex_lock(g_mutexAcceptServer);
247 g_stopAccept = false;
248 ca_mutex_unlock(g_mutexAcceptServer);
250 while (true != *(ctx->stopFlag))
252 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
254 // when BT state is changed with Off. its thread will be stopped
255 if (!CAEDRNativeIsEnableBTAdapter(env))
257 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
258 ca_mutex_lock(g_mutexAcceptServer);
260 ca_mutex_unlock(g_mutexAcceptServer);
261 ca_mutex_lock(g_mutexServerSocket);
262 g_serverSocket = NULL;
263 ca_mutex_unlock(g_mutexServerSocket);
267 CAEDRNativeAccept(env, g_serverSocket);
273 (*g_jvm)->DetachCurrentThread(g_jvm);
278 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
284 * implement for adapter common method.
286 CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, ca_thread_pool_t handle)
288 OIC_LOG(DEBUG, TAG, "IN");
289 CAEDRServerInitialize(handle);
290 CAResult_t res = CAEDRStartUnicastServer(false);
291 if (CA_STATUS_OK != res)
293 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
294 return CA_STATUS_FAILED;
298 OIC_LOG(DEBUG, TAG, "OUT");
302 CAResult_t CAEDRServerStop(int serverFD)
304 OIC_LOG(DEBUG, TAG, "IN");
305 CAEDRStopUnicastServer(-1);
306 CAEDRStopMulticastServer(-1);
308 ca_mutex_lock(g_mutexAcceptServer);
310 ca_mutex_unlock(g_mutexAcceptServer);
314 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
315 return CA_STATUS_FAILED;
318 bool isAttached = false;
320 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
323 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
324 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
328 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
329 return CA_STATUS_FAILED;
334 CAEDRNatvieCloseServerTask(env);
338 (*g_jvm)->DetachCurrentThread(g_jvm);
341 OIC_LOG(DEBUG, TAG, "OUT");
345 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
347 g_edrPacketReceivedCallback = packetReceivedCallback;
353 static void CAEDRServerDestroyMutex()
355 OIC_LOG(DEBUG, TAG, "IN");
357 if (g_mutexUnicastServer)
359 ca_mutex_free(g_mutexUnicastServer);
360 g_mutexUnicastServer = NULL;
363 if (g_mutexMulticastServer)
365 ca_mutex_free(g_mutexMulticastServer);
366 g_mutexMulticastServer = NULL;
369 if (g_mutexSocketListManager)
371 ca_mutex_free(g_mutexSocketListManager);
372 g_mutexSocketListManager = NULL;
375 if (g_mutexAcceptServer)
377 ca_mutex_free(g_mutexAcceptServer);
378 g_mutexAcceptServer = NULL;
381 if (g_mutexServerSocket)
383 ca_mutex_free(g_mutexServerSocket);
384 g_mutexServerSocket = NULL;
387 if (g_mutexStateList)
389 ca_mutex_free(g_mutexStateList);
390 g_mutexStateList = NULL;
393 if (g_mutexObjectList)
395 ca_mutex_free(g_mutexObjectList);
396 g_mutexObjectList = NULL;
399 OIC_LOG(DEBUG, TAG, "OUT");
405 static CAResult_t CAEDRServerCreateMutex()
407 OIC_LOG(DEBUG, TAG, "IN");
409 g_mutexUnicastServer = ca_mutex_new();
410 if (!g_mutexUnicastServer)
412 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
413 return CA_STATUS_FAILED;
416 g_mutexMulticastServer = ca_mutex_new();
417 if (!g_mutexMulticastServer)
419 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
421 CAEDRServerDestroyMutex();
422 return CA_STATUS_FAILED;
425 g_mutexSocketListManager = ca_mutex_new();
426 if (!g_mutexSocketListManager)
428 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
430 CAEDRServerDestroyMutex();
431 return CA_STATUS_FAILED;
434 g_mutexAcceptServer = ca_mutex_new();
435 if (!g_mutexAcceptServer)
437 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
439 CAEDRServerDestroyMutex();
440 return CA_STATUS_FAILED;
443 g_mutexServerSocket = ca_mutex_new();
444 if (!g_mutexServerSocket)
446 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
448 CAEDRServerDestroyMutex();
449 return CA_STATUS_FAILED;
452 g_mutexStateList = ca_mutex_new();
453 if (!g_mutexStateList)
455 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
457 CAEDRServerDestroyMutex();
458 return CA_STATUS_FAILED;
461 g_mutexObjectList = ca_mutex_new();
462 if (!g_mutexObjectList)
464 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
466 CAEDRServerDestroyMutex();
467 return CA_STATUS_FAILED;
470 OIC_LOG(DEBUG, TAG, "OUT");
474 void CAEDRServerJniInit()
476 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
477 g_jvm = CANativeJNIGetJavaVM();
480 void CAEDRServerInitialize(ca_thread_pool_t handle)
482 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
484 g_threadPoolHandle = handle;
486 CAEDRServerStartAcceptThread();
488 OIC_LOG(DEBUG, TAG, "OUT");
491 void CAEDRServerStartAcceptThread()
493 CAEDRServerJniInit();
496 CAEDRServerCreateMutex();
498 bool isAttached = false;
500 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
503 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
504 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
508 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
514 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
517 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
518 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
519 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
522 ca_mutex_lock(g_mutexStateList);
523 CAEDRNativeCreateDeviceStateList();
524 ca_mutex_unlock(g_mutexStateList);
526 ca_mutex_lock(g_mutexObjectList);
527 CAEDRNativeCreateDeviceSocketList();
528 ca_mutex_unlock(g_mutexObjectList);
532 (*g_jvm)->DetachCurrentThread(g_jvm);
535 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
536 sizeof(CAAdapterReceiveThreadContext_t));
539 OIC_LOG(ERROR, TAG, "Out of memory!");
543 ctx->stopFlag = &g_stopAccept;
544 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
546 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
547 OICFree((void *) ctx);
551 OIC_LOG(DEBUG, TAG, "OUT");
554 void CAEDRServerTerminate()
556 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
562 bool isAttached = false;
564 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
567 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
568 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
572 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
578 CAEDRNativeSocketCloseToAll(env);
582 (*g_jvm)->DetachCurrentThread(g_jvm);
585 CAEDRNativeRemoveAllDeviceState();
586 CAEDRNativeRemoveAllDeviceSocket(env);
589 CAEDRServerDestroyMutex();
592 CAResult_t CAEDRStartUnicastServer(bool isSecured)
594 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
596 ca_mutex_lock(g_mutexUnicastServer);
599 * The task to listen for data from unicast is added to the thread pool.
600 * This is a blocking call is made where we try to receive some data..
601 * We will keep waiting until some data is received.
602 * This task will be terminated when thread pool is freed on stopping the adapters.
603 * Thread context will be freed by thread on exit.
605 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
606 sizeof(CAAdapterReceiveThreadContext_t));
609 OIC_LOG(ERROR, TAG, "Out of memory!");
610 ca_mutex_unlock(g_mutexUnicastServer);
611 return CA_MEMORY_ALLOC_FAILED;
614 ctx->stopFlag = &g_stopUnicast;
615 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
616 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
618 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
619 ca_mutex_unlock(g_mutexUnicastServer);
620 OICFree((void *) ctx);
621 return CA_STATUS_FAILED;
623 ca_mutex_unlock(g_mutexUnicastServer);
625 OIC_LOG(DEBUG, TAG, "OUT");
629 CAResult_t CAEDRStartMulticastServer(bool isSecured)
631 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
633 ca_mutex_lock(g_mutexMulticastServer);
636 * The task to listen to data from multicast socket is added to the thread pool.
637 * This is a blocking call is made where we try to receive some data.
638 * We will keep waiting until some data is received.
639 * This task will be terminated when thread pool is freed on stopping the adapters.
640 * Thread context will be freed by thread on exit.
642 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
643 sizeof(CAAdapterReceiveThreadContext_t));
646 OIC_LOG(ERROR, TAG, "Out of memory!");
647 ca_mutex_unlock(g_mutexMulticastServer);
649 return CA_MEMORY_ALLOC_FAILED;
652 ctx->stopFlag = &g_stopMulticast;
653 ctx->type = CA_MULTICAST_SERVER;
655 g_stopMulticast = false;
656 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
658 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
660 g_stopMulticast = true;
661 ca_mutex_unlock(g_mutexMulticastServer);
662 OICFree((void *) ctx);
664 return CA_STATUS_FAILED;
666 ca_mutex_unlock(g_mutexMulticastServer);
668 OIC_LOG(DEBUG, TAG, "OUT");
672 CAResult_t CAEDRStopUnicastServer(int32_t serverID)
674 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
676 ca_mutex_lock(g_mutexUnicastServer);
677 g_stopUnicast = true;
678 ca_mutex_unlock(g_mutexUnicastServer);
683 CAResult_t CAEDRStopMulticastServer(int32_t serverID)
685 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
687 ca_mutex_lock(g_mutexMulticastServer);
688 g_stopMulticast = true;
689 ca_mutex_unlock(g_mutexMulticastServer);
691 OIC_LOG(INFO, TAG, "Multicast server stopped");
696 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
698 if (!CAEDRNativeIsEnableBTAdapter(env))
700 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
701 return CA_STATUS_INVALID_PARAM;
704 if (!((*env)->ExceptionCheck(env)))
706 // check whether this socket object is connected or not.
707 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
710 return CA_STATUS_INVALID_PARAM;
713 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
714 if (!jni_str_address)
716 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
717 return CA_STATUS_FAILED;
719 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
721 // check it whether is still connected or not through google api
722 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
725 OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket");
728 // check it whether is still connected or not through socket state list
729 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
731 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet..");
733 // remove socket to list
734 // this code is related to below read fail exception code
735 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
736 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
738 return CA_STATUS_FAILED;
741 // start to read through InputStream
742 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
743 if (!jni_cid_BTsocket)
745 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
746 return CA_STATUS_FAILED;
748 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
750 "()Ljava/io/InputStream;");
751 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
755 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
756 return CA_STATUS_FAILED;
759 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
760 jni_mid_getInputStream);
761 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
763 g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
765 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
766 if (!jni_cid_InputStream)
768 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
769 return CA_STATUS_FAILED;
771 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
773 jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
777 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
778 return CA_STATUS_FAILED;
781 jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
784 OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
788 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
789 return CA_STATUS_FAILED;
792 if ((*env)->ExceptionCheck(env))
794 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
795 (*env)->ExceptionDescribe(env);
796 (*env)->ExceptionClear(env);
798 // update state to disconnect
799 // the socket will be close next read thread routine
800 ca_mutex_lock(g_mutexStateList);
801 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
802 ca_mutex_unlock(g_mutexStateList);
803 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
804 return CA_STATUS_FAILED;
807 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
808 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
811 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
812 return CA_STATUS_FAILED;
815 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
817 char responseData[MAX_PDU_BUFFER] = { 0 };
818 memcpy(responseData, (const char*) buf, length);
822 case CA_UNICAST_SERVER:
823 case CA_MULTICAST_SERVER:
824 // Notify data to upper layer
825 if (g_edrPacketReceivedCallback)
827 uint32_t sentLength = 0;
828 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
829 %s, %d", responseData, length);
830 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
835 // Should never occur
836 OIC_LOG(ERROR, TAG, "Invalid server type");
837 return CA_STATUS_FAILED;
839 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
840 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
844 (*env)->ExceptionDescribe(env);
845 (*env)->ExceptionClear(env);
846 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
847 return CA_STATUS_FAILED;
853 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
855 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
857 if (!CAEDRNativeIsEnableBTAdapter(env))
859 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
865 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
869 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
870 if (!jni_cid_BTsocket)
872 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
876 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
878 if (!jni_mid_isConnected)
880 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
881 - jni_mid_isConnected is null.");
885 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
887 return jni_isConnected;
890 void CANativeStartListenTask(JNIEnv *env)
892 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
893 if (!jni_obj_BTServerSocket)
895 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
899 ca_mutex_lock(g_mutexServerSocket);
900 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
901 ca_mutex_unlock(g_mutexServerSocket);
904 jobject CAEDRNativeListen(JNIEnv *env)
906 if (!CAEDRNativeIsEnableBTAdapter(env))
908 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
912 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
914 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
915 if (!jni_cid_BTAdapter)
917 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
922 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
924 METHODID_OBJECTNONPARAM);
925 if (!jni_cid_BTAdapter)
927 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
931 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
932 jni_mid_getDefaultAdapter);
933 if (!jni_obj_BTAdapter)
935 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
939 // get listen method ID
940 jmethodID jni_mid_listen = (*env)->GetMethodID(
941 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
942 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
945 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
948 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
950 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
953 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
957 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
958 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
959 if (!jni_mid_fromString)
961 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
965 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
968 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
971 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
975 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
980 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
983 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
986 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
987 jni_name, jni_obj_uuid);
988 if (!jni_obj_BTServerSocket)
990 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
994 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
996 return jni_obj_BTServerSocket;
999 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1001 if (NULL != serverSocketObject)
1003 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1004 env, "android/bluetooth/BluetoothServerSocket");
1005 if (!jni_cid_BTServerSocket)
1007 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1011 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1012 "()Landroid/bluetooth/BluetoothSocket;");
1013 if (!jni_mid_accept)
1015 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1019 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1021 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1023 if (!jni_obj_BTSocket)
1025 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1027 if ((*env)->ExceptionCheck(env))
1029 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1030 (*env)->ExceptionDescribe(env);
1031 (*env)->ExceptionClear(env);
1036 // get remote address
1037 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1040 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1044 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1045 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1047 // set socket to list
1048 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1049 ca_mutex_lock(g_mutexObjectList);
1050 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1051 ca_mutex_unlock(g_mutexObjectList);
1053 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1056 ca_mutex_lock(g_mutexStateList);
1057 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1058 ca_mutex_unlock(g_mutexStateList);
1059 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1063 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1068 * InputStream & BluetoothServerSocket will be close for Terminating.
1070 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1074 OIC_LOG(DEBUG, TAG, "InputStream will be close");
1075 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1076 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1077 (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1078 (*env)->DeleteGlobalRef(env, g_inputStream);
1083 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1085 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1086 env, "android/bluetooth/BluetoothServerSocket");
1087 if (!jni_cid_BTServerSocket)
1089 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1093 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1094 if (!jni_mid_accept)
1096 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1099 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1100 (*env)->DeleteGlobalRef(env, g_serverSocket);
1102 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");