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;
110 * Mutex to synchronize input stream.
112 static ca_mutex g_mutexInputStream = NULL;
114 typedef struct send_data
122 * Thread context information for unicast, multicast and secured unicast server.
127 CAAdapterServerType_t type;
128 } CAAdapterReceiveThreadContext_t;
133 } CAAdapterAcceptThreadContext_t;
136 * Maintains the callback to be notified when data received from remote
139 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
141 static void CAReceiveHandler(void *data)
143 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
145 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
147 bool isAttached = false;
149 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
152 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
153 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
157 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
163 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
165 while (true != *(ctx->stopFlag))
167 // if new socket object is added in socket list after below logic is ran.
168 // new socket will be started to read after next while loop
169 uint32_t length = CAEDRGetSocketListLength();
172 OIC_LOG(DEBUG, TAG, "socket list is empty");
177 for (idx = 0; idx < length; idx++)
179 OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
180 CAEDRNativeReadData(env, idx, ctx->type);
187 (*g_jvm)->DetachCurrentThread(g_jvm);
192 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
195 static void CAAcceptHandler(void *data)
199 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
203 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
205 bool isAttached = false;
207 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
210 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
211 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
215 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
221 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
222 if (!jni_obj_BTServerSocket)
224 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
228 (*g_jvm)->DetachCurrentThread(g_jvm);
234 ca_mutex_lock(g_mutexServerSocket);
235 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
236 ca_mutex_unlock(g_mutexServerSocket);
238 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
242 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null");
245 (*g_jvm)->DetachCurrentThread(g_jvm);
250 // it should be initialized for restart accept thread
251 ca_mutex_lock(g_mutexAcceptServer);
252 g_stopAccept = false;
253 ca_mutex_unlock(g_mutexAcceptServer);
255 while (true != *(ctx->stopFlag))
257 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
259 // when BT state is changed with Off. its thread will be stopped
260 if (!CAEDRNativeIsEnableBTAdapter(env))
262 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
263 ca_mutex_lock(g_mutexAcceptServer);
265 ca_mutex_unlock(g_mutexAcceptServer);
266 ca_mutex_lock(g_mutexServerSocket);
267 g_serverSocket = NULL;
268 ca_mutex_unlock(g_mutexServerSocket);
272 CAEDRNativeAccept(env, g_serverSocket);
278 (*g_jvm)->DetachCurrentThread(g_jvm);
283 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
289 * implement for adapter common method.
291 CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, ca_thread_pool_t handle)
293 OIC_LOG(DEBUG, TAG, "IN");
294 CAEDRServerInitialize(handle);
295 CAResult_t res = CAEDRStartUnicastServer(false);
296 if (CA_STATUS_OK != res)
298 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
299 return CA_STATUS_FAILED;
303 OIC_LOG(DEBUG, TAG, "OUT");
307 CAResult_t CAEDRServerStop(int serverFD)
309 OIC_LOG(DEBUG, TAG, "IN");
310 CAEDRStopUnicastServer(-1);
311 CAEDRStopMulticastServer(-1);
313 ca_mutex_lock(g_mutexAcceptServer);
315 ca_mutex_unlock(g_mutexAcceptServer);
319 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
320 return CA_STATUS_FAILED;
323 bool isAttached = false;
325 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
328 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
329 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
333 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
334 return CA_STATUS_FAILED;
339 CAEDRNatvieCloseServerTask(env);
343 (*g_jvm)->DetachCurrentThread(g_jvm);
346 OIC_LOG(DEBUG, TAG, "OUT");
350 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
352 g_edrPacketReceivedCallback = packetReceivedCallback;
358 static void CAEDRServerDestroyMutex()
360 OIC_LOG(DEBUG, TAG, "IN");
362 if (g_mutexUnicastServer)
364 ca_mutex_free(g_mutexUnicastServer);
365 g_mutexUnicastServer = NULL;
368 if (g_mutexMulticastServer)
370 ca_mutex_free(g_mutexMulticastServer);
371 g_mutexMulticastServer = NULL;
374 if (g_mutexSocketListManager)
376 ca_mutex_free(g_mutexSocketListManager);
377 g_mutexSocketListManager = NULL;
380 if (g_mutexAcceptServer)
382 ca_mutex_free(g_mutexAcceptServer);
383 g_mutexAcceptServer = NULL;
386 if (g_mutexServerSocket)
388 ca_mutex_free(g_mutexServerSocket);
389 g_mutexServerSocket = NULL;
392 if (g_mutexStateList)
394 ca_mutex_free(g_mutexStateList);
395 g_mutexStateList = NULL;
398 if (g_mutexObjectList)
400 ca_mutex_free(g_mutexObjectList);
401 g_mutexObjectList = NULL;
404 if (g_mutexInputStream)
406 ca_mutex_free(g_mutexInputStream);
407 g_mutexInputStream = NULL;
410 OIC_LOG(DEBUG, TAG, "OUT");
416 static CAResult_t CAEDRServerCreateMutex()
418 OIC_LOG(DEBUG, TAG, "IN");
420 g_mutexUnicastServer = ca_mutex_new();
421 if (!g_mutexUnicastServer)
423 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
424 return CA_STATUS_FAILED;
427 g_mutexMulticastServer = ca_mutex_new();
428 if (!g_mutexMulticastServer)
430 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
432 CAEDRServerDestroyMutex();
433 return CA_STATUS_FAILED;
436 g_mutexSocketListManager = ca_mutex_new();
437 if (!g_mutexSocketListManager)
439 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
441 CAEDRServerDestroyMutex();
442 return CA_STATUS_FAILED;
445 g_mutexAcceptServer = ca_mutex_new();
446 if (!g_mutexAcceptServer)
448 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
450 CAEDRServerDestroyMutex();
451 return CA_STATUS_FAILED;
454 g_mutexServerSocket = ca_mutex_new();
455 if (!g_mutexServerSocket)
457 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
459 CAEDRServerDestroyMutex();
460 return CA_STATUS_FAILED;
463 g_mutexStateList = ca_mutex_new();
464 if (!g_mutexStateList)
466 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
468 CAEDRServerDestroyMutex();
469 return CA_STATUS_FAILED;
472 g_mutexObjectList = ca_mutex_new();
473 if (!g_mutexObjectList)
475 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
477 CAEDRServerDestroyMutex();
478 return CA_STATUS_FAILED;
481 g_mutexInputStream = ca_mutex_new();
482 if (!g_mutexInputStream)
484 OIC_LOG(ERROR, TAG, "Failed to created g_mutexInputStream.");
486 CAEDRServerDestroyMutex();
487 return CA_STATUS_FAILED;
490 OIC_LOG(DEBUG, TAG, "OUT");
494 void CAEDRServerJniInit()
496 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
497 g_jvm = CANativeJNIGetJavaVM();
500 void CAEDRServerInitialize(ca_thread_pool_t handle)
502 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
504 g_threadPoolHandle = handle;
506 CAEDRServerStartAcceptThread();
508 OIC_LOG(DEBUG, TAG, "OUT");
511 void CAEDRServerStartAcceptThread()
513 CAEDRServerJniInit();
516 CAEDRServerCreateMutex();
518 bool isAttached = false;
520 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
523 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
524 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
528 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
534 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
537 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
538 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
539 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
542 ca_mutex_lock(g_mutexStateList);
543 CAEDRNativeCreateDeviceStateList();
544 ca_mutex_unlock(g_mutexStateList);
546 ca_mutex_lock(g_mutexObjectList);
547 CAEDRNativeCreateDeviceSocketList();
548 ca_mutex_unlock(g_mutexObjectList);
552 (*g_jvm)->DetachCurrentThread(g_jvm);
555 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
556 sizeof(CAAdapterReceiveThreadContext_t));
559 OIC_LOG(ERROR, TAG, "Out of memory!");
563 ctx->stopFlag = &g_stopAccept;
564 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
566 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
567 OICFree((void *) ctx);
571 OIC_LOG(DEBUG, TAG, "OUT");
574 void CAEDRServerTerminate()
576 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
582 bool isAttached = false;
584 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
587 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
588 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
592 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
598 CAEDRNativeSocketCloseToAll(env);
602 (*g_jvm)->DetachCurrentThread(g_jvm);
605 CAEDRNativeRemoveAllDeviceState();
606 CAEDRNativeRemoveAllDeviceSocket(env);
609 CAEDRServerDestroyMutex();
612 CAResult_t CAEDRStartUnicastServer(bool isSecured)
614 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
616 ca_mutex_lock(g_mutexUnicastServer);
619 * The task to listen for data from unicast is added to the thread pool.
620 * This is a blocking call is made where we try to receive some data..
621 * We will keep waiting until some data is received.
622 * This task will be terminated when thread pool is freed on stopping the adapters.
623 * Thread context will be freed by thread on exit.
625 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
626 sizeof(CAAdapterReceiveThreadContext_t));
629 OIC_LOG(ERROR, TAG, "Out of memory!");
630 ca_mutex_unlock(g_mutexUnicastServer);
631 return CA_MEMORY_ALLOC_FAILED;
634 ctx->stopFlag = &g_stopUnicast;
635 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
636 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
638 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
639 ca_mutex_unlock(g_mutexUnicastServer);
640 OICFree((void *) ctx);
641 return CA_STATUS_FAILED;
643 ca_mutex_unlock(g_mutexUnicastServer);
645 OIC_LOG(DEBUG, TAG, "OUT");
649 CAResult_t CAEDRStartMulticastServer()
651 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
653 ca_mutex_lock(g_mutexMulticastServer);
656 * The task to listen to data from multicast socket is added to the thread pool.
657 * This is a blocking call is made where we try to receive some data.
658 * We will keep waiting until some data is received.
659 * This task will be terminated when thread pool is freed on stopping the adapters.
660 * Thread context will be freed by thread on exit.
662 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
663 sizeof(CAAdapterReceiveThreadContext_t));
666 OIC_LOG(ERROR, TAG, "Out of memory!");
667 ca_mutex_unlock(g_mutexMulticastServer);
669 return CA_MEMORY_ALLOC_FAILED;
672 ctx->stopFlag = &g_stopMulticast;
673 ctx->type = CA_MULTICAST_SERVER;
675 g_stopMulticast = false;
676 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
678 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
680 g_stopMulticast = true;
681 ca_mutex_unlock(g_mutexMulticastServer);
682 OICFree((void *) ctx);
684 return CA_STATUS_FAILED;
686 ca_mutex_unlock(g_mutexMulticastServer);
688 OIC_LOG(DEBUG, TAG, "OUT");
692 CAResult_t CAEDRStopUnicastServer()
694 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
696 ca_mutex_lock(g_mutexUnicastServer);
697 g_stopUnicast = true;
698 ca_mutex_unlock(g_mutexUnicastServer);
703 CAResult_t CAEDRStopMulticastServer()
705 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
707 ca_mutex_lock(g_mutexMulticastServer);
708 g_stopMulticast = true;
709 ca_mutex_unlock(g_mutexMulticastServer);
711 OIC_LOG(INFO, TAG, "Multicast server stopped");
716 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
718 if (!CAEDRNativeIsEnableBTAdapter(env))
720 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
721 return CA_STATUS_INVALID_PARAM;
724 if (!((*env)->ExceptionCheck(env)))
726 // check whether this socket object is connected or not.
727 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
730 return CA_STATUS_INVALID_PARAM;
733 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
734 if (!jni_str_address)
736 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
737 return CA_STATUS_FAILED;
739 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
741 // check it whether is still connected or not through google api
742 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
745 OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket");
748 // check it whether is still connected or not through socket state list
749 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
751 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet..");
753 // remove socket to list
754 // this code is related to below read fail exception code
755 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
756 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
758 (*env)->DeleteLocalRef(env, jni_str_address);
760 return CA_STATUS_FAILED;
763 // start to read through InputStream
764 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
765 if (!jni_cid_BTsocket)
767 (*env)->DeleteLocalRef(env, jni_str_address);
769 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
770 return CA_STATUS_FAILED;
772 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
774 "()Ljava/io/InputStream;");
775 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
779 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
780 (*env)->DeleteLocalRef(env, jni_str_address);
782 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
783 return CA_STATUS_FAILED;
786 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
787 jni_mid_getInputStream);
788 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
790 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
791 if (!jni_cid_InputStream)
793 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
794 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
795 (*env)->DeleteLocalRef(env, jni_str_address);
797 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
798 return CA_STATUS_FAILED;
800 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
802 jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
806 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
807 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
808 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
809 (*env)->DeleteLocalRef(env, jni_str_address);
811 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
812 return CA_STATUS_FAILED;
815 ca_mutex_lock(g_mutexInputStream);
818 g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
821 jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
823 ca_mutex_unlock(g_mutexInputStream);
825 OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
829 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
830 (*env)->DeleteLocalRef(env, jbuf);
831 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
832 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
833 (*env)->DeleteLocalRef(env, jni_str_address);
835 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
836 return CA_STATUS_FAILED;
839 if ((*env)->ExceptionCheck(env))
841 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
842 (*env)->ExceptionDescribe(env);
843 (*env)->ExceptionClear(env);
845 // update state to disconnect
846 // the socket will be close next read thread routine
847 ca_mutex_lock(g_mutexStateList);
848 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
849 ca_mutex_unlock(g_mutexStateList);
850 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
852 (*env)->DeleteLocalRef(env, jbuf);
853 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
854 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
855 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
856 (*env)->DeleteLocalRef(env, jni_str_address);
858 return CA_STATUS_FAILED;
861 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
862 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
865 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
866 (*env)->DeleteLocalRef(env, jbuf);
867 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
868 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
869 (*env)->DeleteLocalRef(env, jni_str_address);
871 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
872 return CA_STATUS_FAILED;
875 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
877 char responseData[MAX_PDU_BUFFER] = { 0 };
878 memcpy(responseData, (const char*) buf, length);
882 case CA_UNICAST_SERVER:
883 case CA_MULTICAST_SERVER:
884 // Notify data to upper layer
885 if (g_edrPacketReceivedCallback)
887 uint32_t sentLength = 0;
888 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
889 %s, %d", responseData, length);
890 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
895 // Should never occur
896 OIC_LOG(ERROR, TAG, "Invalid server type");
897 return CA_STATUS_FAILED;
899 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
900 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
902 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
903 (*env)->DeleteLocalRef(env, jbuf);
904 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
905 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
906 (*env)->DeleteLocalRef(env, jni_str_address);
910 (*env)->ExceptionDescribe(env);
911 (*env)->ExceptionClear(env);
912 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
913 return CA_STATUS_FAILED;
919 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
921 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
923 if (!CAEDRNativeIsEnableBTAdapter(env))
925 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
931 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
935 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
936 if (!jni_cid_BTsocket)
938 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
942 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
944 if (!jni_mid_isConnected)
946 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
948 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
949 - jni_mid_isConnected is null.");
953 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
955 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
957 return jni_isConnected;
960 void CANativeStartListenTask(JNIEnv *env)
962 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
963 if (!jni_obj_BTServerSocket)
965 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
969 ca_mutex_lock(g_mutexServerSocket);
970 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
971 ca_mutex_unlock(g_mutexServerSocket);
974 jobject CAEDRNativeListen(JNIEnv *env)
976 if (!CAEDRNativeIsEnableBTAdapter(env))
978 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
982 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
984 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
985 if (!jni_cid_BTAdapter)
987 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
992 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
994 METHODID_OBJECTNONPARAM);
995 if (!jni_cid_BTAdapter)
997 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
1001 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1002 jni_mid_getDefaultAdapter);
1003 if (!jni_obj_BTAdapter)
1005 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
1009 // get listen method ID
1010 jmethodID jni_mid_listen = (*env)->GetMethodID(
1011 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
1012 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
1013 if (!jni_mid_listen)
1015 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
1018 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
1020 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1023 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
1027 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
1028 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
1029 if (!jni_mid_fromString)
1031 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
1035 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
1038 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
1041 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1045 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
1050 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
1053 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
1056 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
1057 jni_name, jni_obj_uuid);
1058 if (!jni_obj_BTServerSocket)
1060 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1064 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1066 return jni_obj_BTServerSocket;
1069 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1071 if (NULL != serverSocketObject)
1073 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1074 env, "android/bluetooth/BluetoothServerSocket");
1075 if (!jni_cid_BTServerSocket)
1077 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1081 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1082 "()Landroid/bluetooth/BluetoothSocket;");
1083 if (!jni_mid_accept)
1085 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1089 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1091 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1093 if (!jni_obj_BTSocket)
1095 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1097 if ((*env)->ExceptionCheck(env))
1099 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1100 (*env)->ExceptionDescribe(env);
1101 (*env)->ExceptionClear(env);
1106 // get remote address
1107 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1110 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1114 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1115 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1117 // set socket to list
1118 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1119 ca_mutex_lock(g_mutexObjectList);
1120 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1121 ca_mutex_unlock(g_mutexObjectList);
1123 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1126 ca_mutex_lock(g_mutexStateList);
1127 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1128 ca_mutex_unlock(g_mutexStateList);
1129 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1133 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1138 * InputStream & BluetoothServerSocket will be close for Terminating.
1140 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1144 OIC_LOG(DEBUG, TAG, "InputStream will be close");
1145 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1146 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1147 (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1148 (*env)->DeleteGlobalRef(env, g_inputStream);
1153 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1155 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1156 env, "android/bluetooth/BluetoothServerSocket");
1157 if (!jni_cid_BTServerSocket)
1159 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1163 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1164 if (!jni_mid_accept)
1166 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1169 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1170 (*env)->DeleteGlobalRef(env, g_serverSocket);
1172 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");