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 ******************************************************************/
25 #include "caedrinterface.h"
26 #include "caedrutils.h"
27 #include "caedrserver.h"
29 #include "oic_malloc.h"
30 #include "cathreadpool.h" /* for thread pool */
32 #include "uarraylist.h"
33 #include "caadapterutils.h"
34 #include "org_iotivity_ca_CaEdrInterface.h"
35 #include "oic_string.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 * Mutex to synchronize socket list update.
52 static ca_mutex g_mutexSocketListManager;
55 * server socket instance.
57 static jobject g_serverSocketObject = NULL;
60 * Mutex to synchronize unicast server.
62 static ca_mutex g_mutexUnicastServer = NULL;
65 * Flag to control the Receive Unicast Data Thread.
67 static bool g_stopUnicast = false;
70 * Mutex to synchronize secure multicast server.
72 static ca_mutex g_mutexMulticastServer = NULL;
75 * Flag to control the Receive Multicast Data Thread.
77 static bool g_stopMulticast = false;
80 * Mutex to synchronize accept server.
82 static ca_mutex g_mutexAcceptServer = NULL;
85 * Flag to control the Accept Thread.
87 static bool g_stopAccept = false;
89 static jobject g_inputStream = NULL;
92 * Mutex to synchronize server socket.
94 static ca_mutex g_mutexServerSocket = NULL;
96 static jobject g_serverSocket = NULL;
99 * Mutex to synchronize device state list.
101 static ca_mutex g_mutexStateList = NULL;
104 * Mutex to synchronize device object list.
106 static ca_mutex g_mutexObjectList = NULL;
109 * Mutex to synchronize input stream.
111 static ca_mutex g_mutexInputStream = NULL;
113 typedef struct send_data
121 * Thread context information for unicast, multicast and secured unicast server.
126 CAAdapterServerType_t type;
127 } CAAdapterReceiveThreadContext_t;
132 } CAAdapterAcceptThreadContext_t;
135 * Maintains the callback to be notified when data received from remote
138 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
140 static void CAReceiveHandler(void *data)
142 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
144 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
146 bool isAttached = false;
148 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
151 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
152 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
156 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
162 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
164 while (true != *(ctx->stopFlag))
166 // if new socket object is added in socket list after below logic is ran.
167 // new socket will be started to read after next while loop
168 uint32_t length = CAEDRGetSocketListLength();
171 for (uint32_t idx = 0; idx < length; idx++)
173 OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
174 CAEDRNativeReadData(env, idx, ctx->type);
181 (*g_jvm)->DetachCurrentThread(g_jvm);
186 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
189 static void CAAcceptHandler(void *data)
193 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
197 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
199 bool isAttached = false;
201 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
204 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
205 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
209 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
215 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
216 if (!jni_obj_BTServerSocket)
218 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
222 (*g_jvm)->DetachCurrentThread(g_jvm);
228 ca_mutex_lock(g_mutexServerSocket);
229 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
230 ca_mutex_unlock(g_mutexServerSocket);
232 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
234 // it should be initialized for restart accept thread
235 ca_mutex_lock(g_mutexAcceptServer);
236 g_stopAccept = false;
237 ca_mutex_unlock(g_mutexAcceptServer);
239 while (true != *(ctx->stopFlag))
241 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
243 // when BT state is changed with Off. its thread will be stopped
244 if (!CAEDRNativeIsEnableBTAdapter(env))
246 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
247 ca_mutex_lock(g_mutexAcceptServer);
249 ca_mutex_unlock(g_mutexAcceptServer);
250 ca_mutex_lock(g_mutexServerSocket);
251 g_serverSocket = NULL;
252 ca_mutex_unlock(g_mutexServerSocket);
256 CAEDRNativeAccept(env, g_serverSocket);
262 (*g_jvm)->DetachCurrentThread(g_jvm);
267 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
273 * implement for adapter common method.
275 CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
277 OIC_LOG(DEBUG, TAG, "IN");
278 CAEDRServerInitialize(handle);
279 CAResult_t res = CAEDRStartUnicastServer(false);
280 if (CA_STATUS_OK != res)
282 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
283 return CA_STATUS_FAILED;
286 OIC_LOG(DEBUG, TAG, "OUT");
290 CAResult_t CAEDRServerStop()
292 OIC_LOG(DEBUG, TAG, "IN");
293 CAEDRStopUnicastServer();
294 CAEDRStopMulticastServer();
296 ca_mutex_lock(g_mutexAcceptServer);
298 ca_mutex_unlock(g_mutexAcceptServer);
302 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
303 return CA_STATUS_FAILED;
306 bool isAttached = false;
308 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
311 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
312 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
316 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
317 return CA_STATUS_FAILED;
322 CAEDRNatvieCloseServerTask(env);
326 (*g_jvm)->DetachCurrentThread(g_jvm);
329 OIC_LOG(DEBUG, TAG, "OUT");
333 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
335 g_edrPacketReceivedCallback = packetReceivedCallback;
341 static void CAEDRServerDestroyMutex()
343 OIC_LOG(DEBUG, TAG, "IN");
345 if (g_mutexUnicastServer)
347 ca_mutex_free(g_mutexUnicastServer);
348 g_mutexUnicastServer = NULL;
351 if (g_mutexMulticastServer)
353 ca_mutex_free(g_mutexMulticastServer);
354 g_mutexMulticastServer = NULL;
357 if (g_mutexSocketListManager)
359 ca_mutex_free(g_mutexSocketListManager);
360 g_mutexSocketListManager = NULL;
363 if (g_mutexAcceptServer)
365 ca_mutex_free(g_mutexAcceptServer);
366 g_mutexAcceptServer = NULL;
369 if (g_mutexServerSocket)
371 ca_mutex_free(g_mutexServerSocket);
372 g_mutexServerSocket = NULL;
375 if (g_mutexStateList)
377 ca_mutex_free(g_mutexStateList);
378 g_mutexStateList = NULL;
381 if (g_mutexObjectList)
383 ca_mutex_free(g_mutexObjectList);
384 g_mutexObjectList = NULL;
387 if (g_mutexInputStream)
389 ca_mutex_free(g_mutexInputStream);
390 g_mutexInputStream = NULL;
393 OIC_LOG(DEBUG, TAG, "OUT");
399 static CAResult_t CAEDRServerCreateMutex()
401 OIC_LOG(DEBUG, TAG, "IN");
403 g_mutexUnicastServer = ca_mutex_new();
404 if (!g_mutexUnicastServer)
406 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
407 return CA_STATUS_FAILED;
410 g_mutexMulticastServer = ca_mutex_new();
411 if (!g_mutexMulticastServer)
413 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
415 CAEDRServerDestroyMutex();
416 return CA_STATUS_FAILED;
419 g_mutexSocketListManager = ca_mutex_new();
420 if (!g_mutexSocketListManager)
422 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
424 CAEDRServerDestroyMutex();
425 return CA_STATUS_FAILED;
428 g_mutexAcceptServer = ca_mutex_new();
429 if (!g_mutexAcceptServer)
431 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
433 CAEDRServerDestroyMutex();
434 return CA_STATUS_FAILED;
437 g_mutexServerSocket = ca_mutex_new();
438 if (!g_mutexServerSocket)
440 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
442 CAEDRServerDestroyMutex();
443 return CA_STATUS_FAILED;
446 g_mutexStateList = ca_mutex_new();
447 if (!g_mutexStateList)
449 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
451 CAEDRServerDestroyMutex();
452 return CA_STATUS_FAILED;
455 g_mutexObjectList = ca_mutex_new();
456 if (!g_mutexObjectList)
458 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
460 CAEDRServerDestroyMutex();
461 return CA_STATUS_FAILED;
464 g_mutexInputStream = ca_mutex_new();
465 if (!g_mutexInputStream)
467 OIC_LOG(ERROR, TAG, "Failed to created g_mutexInputStream.");
469 CAEDRServerDestroyMutex();
470 return CA_STATUS_FAILED;
473 OIC_LOG(DEBUG, TAG, "OUT");
477 void CAEDRServerJniInit()
479 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
480 g_jvm = CANativeJNIGetJavaVM();
483 void CAEDRServerInitialize(ca_thread_pool_t handle)
485 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
487 g_threadPoolHandle = handle;
489 CAEDRServerStartAcceptThread();
491 OIC_LOG(DEBUG, TAG, "OUT");
494 void CAEDRServerStartAcceptThread()
496 CAEDRServerJniInit();
499 CAEDRServerCreateMutex();
501 bool isAttached = false;
503 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
506 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
507 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
511 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
517 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
520 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
521 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
522 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
525 ca_mutex_lock(g_mutexStateList);
526 CAEDRNativeCreateDeviceStateList();
527 ca_mutex_unlock(g_mutexStateList);
529 ca_mutex_lock(g_mutexObjectList);
530 CAEDRNativeCreateDeviceSocketList();
531 ca_mutex_unlock(g_mutexObjectList);
535 (*g_jvm)->DetachCurrentThread(g_jvm);
538 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
539 sizeof(CAAdapterReceiveThreadContext_t));
542 OIC_LOG(ERROR, TAG, "Out of memory!");
546 ctx->stopFlag = &g_stopAccept;
547 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
549 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
550 OICFree((void *) ctx);
554 OIC_LOG(DEBUG, TAG, "OUT");
557 void CAEDRServerTerminate()
559 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
565 bool isAttached = false;
567 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
570 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
571 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
575 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
581 CAEDRNativeSocketCloseToAll(env);
585 (*g_jvm)->DetachCurrentThread(g_jvm);
588 CAEDRNativeRemoveAllDeviceState();
589 CAEDRNativeRemoveAllDeviceSocket(env);
592 CAEDRServerDestroyMutex();
595 CAResult_t CAEDRStartUnicastServer(bool isSecured)
597 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
599 ca_mutex_lock(g_mutexUnicastServer);
602 * The task to listen for data from unicast is added to the thread pool.
603 * This is a blocking call is made where we try to receive some data..
604 * We will keep waiting until some data is received.
605 * This task will be terminated when thread pool is freed on stopping the adapters.
606 * Thread context will be freed by thread on exit.
608 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
609 sizeof(CAAdapterReceiveThreadContext_t));
612 OIC_LOG(ERROR, TAG, "Out of memory!");
613 ca_mutex_unlock(g_mutexUnicastServer);
614 return CA_MEMORY_ALLOC_FAILED;
617 ctx->stopFlag = &g_stopUnicast;
618 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
619 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
621 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
622 ca_mutex_unlock(g_mutexUnicastServer);
623 OICFree((void *) ctx);
624 return CA_STATUS_FAILED;
626 ca_mutex_unlock(g_mutexUnicastServer);
628 OIC_LOG(DEBUG, TAG, "OUT");
632 CAResult_t CAEDRStartMulticastServer()
634 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
636 ca_mutex_lock(g_mutexMulticastServer);
639 * The task to listen to data from multicast socket is added to the thread pool.
640 * This is a blocking call is made where we try to receive some data.
641 * We will keep waiting until some data is received.
642 * This task will be terminated when thread pool is freed on stopping the adapters.
643 * Thread context will be freed by thread on exit.
645 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
646 sizeof(CAAdapterReceiveThreadContext_t));
649 OIC_LOG(ERROR, TAG, "Out of memory!");
650 ca_mutex_unlock(g_mutexMulticastServer);
652 return CA_MEMORY_ALLOC_FAILED;
655 ctx->stopFlag = &g_stopMulticast;
656 ctx->type = CA_MULTICAST_SERVER;
658 g_stopMulticast = false;
659 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
661 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
663 g_stopMulticast = true;
664 ca_mutex_unlock(g_mutexMulticastServer);
665 OICFree((void *) ctx);
667 return CA_STATUS_FAILED;
669 ca_mutex_unlock(g_mutexMulticastServer);
671 OIC_LOG(DEBUG, TAG, "OUT");
675 CAResult_t CAEDRStopUnicastServer()
677 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
679 ca_mutex_lock(g_mutexUnicastServer);
680 g_stopUnicast = true;
681 ca_mutex_unlock(g_mutexUnicastServer);
686 CAResult_t CAEDRStopMulticastServer()
688 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
690 ca_mutex_lock(g_mutexMulticastServer);
691 g_stopMulticast = true;
692 ca_mutex_unlock(g_mutexMulticastServer);
694 OIC_LOG(INFO, TAG, "Multicast server stopped");
699 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
701 if (!CAEDRNativeIsEnableBTAdapter(env))
703 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
704 return CA_STATUS_INVALID_PARAM;
707 if (!((*env)->ExceptionCheck(env)))
709 // check whether this socket object is connected or not.
710 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
713 return CA_STATUS_INVALID_PARAM;
716 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
717 if (!jni_str_address)
719 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
720 return CA_STATUS_FAILED;
722 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
724 // check it whether is still connected or not through google api
725 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
728 OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket");
731 // check it whether is still connected or not through socket state list
732 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
734 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet..");
736 // remove socket to list
737 // this code is related to below read fail exception code
738 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
739 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
741 (*env)->DeleteLocalRef(env, jni_str_address);
743 return CA_STATUS_FAILED;
746 // start to read through InputStream
747 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
748 if (!jni_cid_BTsocket)
750 (*env)->DeleteLocalRef(env, jni_str_address);
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);
760 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
761 jni_mid_getInputStream);
762 if (!jni_obj_inputStream)
764 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
765 (*env)->DeleteLocalRef(env, jni_str_address);
767 OIC_LOG(ERROR, TAG, "[EDR] btReadData: jni_obj_inputStream is null");
768 return CA_STATUS_FAILED;
771 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
773 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
774 if (!jni_cid_InputStream)
776 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
777 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
778 (*env)->DeleteLocalRef(env, jni_str_address);
780 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
781 return CA_STATUS_FAILED;
783 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
785 jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
787 ca_mutex_lock(g_mutexInputStream);
790 g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
793 jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
795 ca_mutex_unlock(g_mutexInputStream);
797 OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
801 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
802 (*env)->DeleteLocalRef(env, jbuf);
803 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
804 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
805 (*env)->DeleteLocalRef(env, jni_str_address);
807 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
808 return CA_STATUS_FAILED;
811 if ((*env)->ExceptionCheck(env))
813 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
814 (*env)->ExceptionDescribe(env);
815 (*env)->ExceptionClear(env);
817 // update state to disconnect
818 // the socket will be close next read thread routine
819 ca_mutex_lock(g_mutexStateList);
820 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
821 ca_mutex_unlock(g_mutexStateList);
822 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
824 (*env)->DeleteLocalRef(env, jbuf);
825 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
826 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
827 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
828 (*env)->DeleteLocalRef(env, jni_str_address);
830 return CA_STATUS_FAILED;
833 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
834 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
837 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
838 (*env)->DeleteLocalRef(env, jbuf);
839 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
840 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
841 (*env)->DeleteLocalRef(env, jni_str_address);
843 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
844 return CA_STATUS_FAILED;
847 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
849 char responseData[MAX_PDU_BUFFER] = { 0 };
850 memcpy(responseData, (const char*) buf, length);
854 case CA_UNICAST_SERVER:
855 case CA_MULTICAST_SERVER:
856 // Notify data to upper layer
857 if (g_edrPacketReceivedCallback)
859 uint32_t sentLength = 0;
860 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
861 %s, %d", responseData, length);
862 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
867 // Should never occur
868 OIC_LOG(ERROR, TAG, "Invalid server type");
869 return CA_STATUS_FAILED;
871 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
872 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
874 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
875 (*env)->DeleteLocalRef(env, jbuf);
876 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
877 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
878 (*env)->DeleteLocalRef(env, jni_str_address);
882 (*env)->ExceptionDescribe(env);
883 (*env)->ExceptionClear(env);
884 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
885 return CA_STATUS_FAILED;
891 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
893 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
895 if (!CAEDRNativeIsEnableBTAdapter(env))
897 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
903 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
907 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
908 if (!jni_cid_BTsocket)
910 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
914 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
916 if (!jni_mid_isConnected)
918 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
920 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
921 - jni_mid_isConnected is null.");
925 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
927 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
929 return jni_isConnected;
932 void CANativeStartListenTask(JNIEnv *env)
934 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
935 if (!jni_obj_BTServerSocket)
937 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
941 ca_mutex_lock(g_mutexServerSocket);
942 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
943 ca_mutex_unlock(g_mutexServerSocket);
946 jobject CAEDRNativeListen(JNIEnv *env)
948 if (!CAEDRNativeIsEnableBTAdapter(env))
950 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
954 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
956 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
957 if (!jni_cid_BTAdapter)
959 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
964 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
966 METHODID_OBJECTNONPARAM);
967 if (!jni_mid_getDefaultAdapter)
969 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_getDefaultAdapter is null");
973 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
974 jni_mid_getDefaultAdapter);
975 if (!jni_obj_BTAdapter)
977 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
981 // get listen method ID
982 jmethodID jni_mid_listen = (*env)->GetMethodID(
983 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
984 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
987 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
990 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
992 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
995 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
999 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
1000 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
1001 if (!jni_mid_fromString)
1003 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
1007 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
1010 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
1013 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1017 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
1022 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
1025 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
1028 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
1029 jni_name, jni_obj_uuid);
1030 if (!jni_obj_BTServerSocket)
1032 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1036 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1038 return jni_obj_BTServerSocket;
1041 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1043 if (NULL != serverSocketObject)
1045 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1046 env, "android/bluetooth/BluetoothServerSocket");
1047 if (!jni_cid_BTServerSocket)
1049 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1053 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1054 "()Landroid/bluetooth/BluetoothSocket;");
1055 if (!jni_mid_accept)
1057 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1061 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1063 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1065 if (!jni_obj_BTSocket)
1067 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1069 if ((*env)->ExceptionCheck(env))
1071 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1072 (*env)->ExceptionDescribe(env);
1073 (*env)->ExceptionClear(env);
1078 // get remote address
1079 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1082 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1086 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1087 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1089 // set socket to list
1090 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1091 ca_mutex_lock(g_mutexObjectList);
1092 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1093 ca_mutex_unlock(g_mutexObjectList);
1095 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1098 ca_mutex_lock(g_mutexStateList);
1099 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1100 ca_mutex_unlock(g_mutexStateList);
1101 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1105 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1110 * InputStream & BluetoothServerSocket will be close for Terminating.
1112 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1116 OIC_LOG(DEBUG, TAG, "InputStream will be close");
1117 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1118 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1119 (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1120 (*env)->DeleteGlobalRef(env, g_inputStream);
1121 g_inputStream = NULL;
1126 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1128 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1129 env, "android/bluetooth/BluetoothServerSocket");
1130 if (!jni_cid_BTServerSocket)
1132 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1136 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1137 if (!jni_mid_accept)
1139 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1142 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1143 (*env)->DeleteGlobalRef(env, g_serverSocket);
1144 g_serverSocket = NULL;
1146 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");