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 OIC_LOG(DEBUG, TAG, "socket list is empty");
176 for (idx = 0; idx < length; idx++)
178 OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
179 CAEDRNativeReadData(env, idx, ctx->type);
186 (*g_jvm)->DetachCurrentThread(g_jvm);
191 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
194 static void CAAcceptHandler(void *data)
198 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
202 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
204 bool isAttached = false;
206 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
209 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
210 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
214 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
220 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
221 if (!jni_obj_BTServerSocket)
223 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
227 (*g_jvm)->DetachCurrentThread(g_jvm);
233 ca_mutex_lock(g_mutexServerSocket);
234 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
235 ca_mutex_unlock(g_mutexServerSocket);
237 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
241 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null");
244 (*g_jvm)->DetachCurrentThread(g_jvm);
249 // it should be initialized for restart accept thread
250 ca_mutex_lock(g_mutexAcceptServer);
251 g_stopAccept = false;
252 ca_mutex_unlock(g_mutexAcceptServer);
254 while (true != *(ctx->stopFlag))
256 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
258 // when BT state is changed with Off. its thread will be stopped
259 if (!CAEDRNativeIsEnableBTAdapter(env))
261 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
262 ca_mutex_lock(g_mutexAcceptServer);
264 ca_mutex_unlock(g_mutexAcceptServer);
265 ca_mutex_lock(g_mutexServerSocket);
266 g_serverSocket = NULL;
267 ca_mutex_unlock(g_mutexServerSocket);
271 CAEDRNativeAccept(env, g_serverSocket);
277 (*g_jvm)->DetachCurrentThread(g_jvm);
282 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
288 * implement for adapter common method.
290 CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
292 OIC_LOG(DEBUG, TAG, "IN");
293 CAEDRServerInitialize(handle);
294 CAResult_t res = CAEDRStartUnicastServer(false);
295 if (CA_STATUS_OK != res)
297 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
298 return CA_STATUS_FAILED;
301 OIC_LOG(DEBUG, TAG, "OUT");
305 CAResult_t CAEDRServerStop()
307 OIC_LOG(DEBUG, TAG, "IN");
308 CAEDRStopUnicastServer();
309 CAEDRStopMulticastServer();
311 ca_mutex_lock(g_mutexAcceptServer);
313 ca_mutex_unlock(g_mutexAcceptServer);
317 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
318 return CA_STATUS_FAILED;
321 bool isAttached = false;
323 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
326 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
327 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
331 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
332 return CA_STATUS_FAILED;
337 CAEDRNatvieCloseServerTask(env);
341 (*g_jvm)->DetachCurrentThread(g_jvm);
344 OIC_LOG(DEBUG, TAG, "OUT");
348 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
350 g_edrPacketReceivedCallback = packetReceivedCallback;
356 static void CAEDRServerDestroyMutex()
358 OIC_LOG(DEBUG, TAG, "IN");
360 if (g_mutexUnicastServer)
362 ca_mutex_free(g_mutexUnicastServer);
363 g_mutexUnicastServer = NULL;
366 if (g_mutexMulticastServer)
368 ca_mutex_free(g_mutexMulticastServer);
369 g_mutexMulticastServer = NULL;
372 if (g_mutexSocketListManager)
374 ca_mutex_free(g_mutexSocketListManager);
375 g_mutexSocketListManager = NULL;
378 if (g_mutexAcceptServer)
380 ca_mutex_free(g_mutexAcceptServer);
381 g_mutexAcceptServer = NULL;
384 if (g_mutexServerSocket)
386 ca_mutex_free(g_mutexServerSocket);
387 g_mutexServerSocket = NULL;
390 if (g_mutexStateList)
392 ca_mutex_free(g_mutexStateList);
393 g_mutexStateList = NULL;
396 if (g_mutexObjectList)
398 ca_mutex_free(g_mutexObjectList);
399 g_mutexObjectList = NULL;
402 if (g_mutexInputStream)
404 ca_mutex_free(g_mutexInputStream);
405 g_mutexInputStream = NULL;
408 OIC_LOG(DEBUG, TAG, "OUT");
414 static CAResult_t CAEDRServerCreateMutex()
416 OIC_LOG(DEBUG, TAG, "IN");
418 g_mutexUnicastServer = ca_mutex_new();
419 if (!g_mutexUnicastServer)
421 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
422 return CA_STATUS_FAILED;
425 g_mutexMulticastServer = ca_mutex_new();
426 if (!g_mutexMulticastServer)
428 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
430 CAEDRServerDestroyMutex();
431 return CA_STATUS_FAILED;
434 g_mutexSocketListManager = ca_mutex_new();
435 if (!g_mutexSocketListManager)
437 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
439 CAEDRServerDestroyMutex();
440 return CA_STATUS_FAILED;
443 g_mutexAcceptServer = ca_mutex_new();
444 if (!g_mutexAcceptServer)
446 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
448 CAEDRServerDestroyMutex();
449 return CA_STATUS_FAILED;
452 g_mutexServerSocket = ca_mutex_new();
453 if (!g_mutexServerSocket)
455 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
457 CAEDRServerDestroyMutex();
458 return CA_STATUS_FAILED;
461 g_mutexStateList = ca_mutex_new();
462 if (!g_mutexStateList)
464 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
466 CAEDRServerDestroyMutex();
467 return CA_STATUS_FAILED;
470 g_mutexObjectList = ca_mutex_new();
471 if (!g_mutexObjectList)
473 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
475 CAEDRServerDestroyMutex();
476 return CA_STATUS_FAILED;
479 g_mutexInputStream = ca_mutex_new();
480 if (!g_mutexInputStream)
482 OIC_LOG(ERROR, TAG, "Failed to created g_mutexInputStream.");
484 CAEDRServerDestroyMutex();
485 return CA_STATUS_FAILED;
488 OIC_LOG(DEBUG, TAG, "OUT");
492 void CAEDRServerJniInit()
494 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
495 g_jvm = CANativeJNIGetJavaVM();
498 void CAEDRServerInitialize(ca_thread_pool_t handle)
500 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
502 g_threadPoolHandle = handle;
504 CAEDRServerStartAcceptThread();
506 OIC_LOG(DEBUG, TAG, "OUT");
509 void CAEDRServerStartAcceptThread()
511 CAEDRServerJniInit();
514 CAEDRServerCreateMutex();
516 bool isAttached = false;
518 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
521 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
522 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
526 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
532 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
535 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
536 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
537 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
540 ca_mutex_lock(g_mutexStateList);
541 CAEDRNativeCreateDeviceStateList();
542 ca_mutex_unlock(g_mutexStateList);
544 ca_mutex_lock(g_mutexObjectList);
545 CAEDRNativeCreateDeviceSocketList();
546 ca_mutex_unlock(g_mutexObjectList);
550 (*g_jvm)->DetachCurrentThread(g_jvm);
553 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
554 sizeof(CAAdapterReceiveThreadContext_t));
557 OIC_LOG(ERROR, TAG, "Out of memory!");
561 ctx->stopFlag = &g_stopAccept;
562 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
564 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
565 OICFree((void *) ctx);
569 OIC_LOG(DEBUG, TAG, "OUT");
572 void CAEDRServerTerminate()
574 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
580 bool isAttached = false;
582 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
585 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
586 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
590 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
596 CAEDRNativeSocketCloseToAll(env);
600 (*g_jvm)->DetachCurrentThread(g_jvm);
603 CAEDRNativeRemoveAllDeviceState();
604 CAEDRNativeRemoveAllDeviceSocket(env);
607 CAEDRServerDestroyMutex();
610 CAResult_t CAEDRStartUnicastServer(bool isSecured)
612 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
614 ca_mutex_lock(g_mutexUnicastServer);
617 * The task to listen for data from unicast is added to the thread pool.
618 * This is a blocking call is made where we try to receive some data..
619 * We will keep waiting until some data is received.
620 * This task will be terminated when thread pool is freed on stopping the adapters.
621 * Thread context will be freed by thread on exit.
623 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
624 sizeof(CAAdapterReceiveThreadContext_t));
627 OIC_LOG(ERROR, TAG, "Out of memory!");
628 ca_mutex_unlock(g_mutexUnicastServer);
629 return CA_MEMORY_ALLOC_FAILED;
632 ctx->stopFlag = &g_stopUnicast;
633 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
634 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
636 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
637 ca_mutex_unlock(g_mutexUnicastServer);
638 OICFree((void *) ctx);
639 return CA_STATUS_FAILED;
641 ca_mutex_unlock(g_mutexUnicastServer);
643 OIC_LOG(DEBUG, TAG, "OUT");
647 CAResult_t CAEDRStartMulticastServer()
649 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
651 ca_mutex_lock(g_mutexMulticastServer);
654 * The task to listen to data from multicast socket is added to the thread pool.
655 * This is a blocking call is made where we try to receive some data.
656 * We will keep waiting until some data is received.
657 * This task will be terminated when thread pool is freed on stopping the adapters.
658 * Thread context will be freed by thread on exit.
660 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
661 sizeof(CAAdapterReceiveThreadContext_t));
664 OIC_LOG(ERROR, TAG, "Out of memory!");
665 ca_mutex_unlock(g_mutexMulticastServer);
667 return CA_MEMORY_ALLOC_FAILED;
670 ctx->stopFlag = &g_stopMulticast;
671 ctx->type = CA_MULTICAST_SERVER;
673 g_stopMulticast = false;
674 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
676 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
678 g_stopMulticast = true;
679 ca_mutex_unlock(g_mutexMulticastServer);
680 OICFree((void *) ctx);
682 return CA_STATUS_FAILED;
684 ca_mutex_unlock(g_mutexMulticastServer);
686 OIC_LOG(DEBUG, TAG, "OUT");
690 CAResult_t CAEDRStopUnicastServer()
692 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
694 ca_mutex_lock(g_mutexUnicastServer);
695 g_stopUnicast = true;
696 ca_mutex_unlock(g_mutexUnicastServer);
701 CAResult_t CAEDRStopMulticastServer()
703 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
705 ca_mutex_lock(g_mutexMulticastServer);
706 g_stopMulticast = true;
707 ca_mutex_unlock(g_mutexMulticastServer);
709 OIC_LOG(INFO, TAG, "Multicast server stopped");
714 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
716 if (!CAEDRNativeIsEnableBTAdapter(env))
718 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
719 return CA_STATUS_INVALID_PARAM;
722 if (!((*env)->ExceptionCheck(env)))
724 // check whether this socket object is connected or not.
725 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
728 return CA_STATUS_INVALID_PARAM;
731 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
732 if (!jni_str_address)
734 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
735 return CA_STATUS_FAILED;
737 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
739 // check it whether is still connected or not through google api
740 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
743 OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket");
746 // check it whether is still connected or not through socket state list
747 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
749 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet..");
751 // remove socket to list
752 // this code is related to below read fail exception code
753 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
754 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
756 (*env)->DeleteLocalRef(env, jni_str_address);
758 return CA_STATUS_FAILED;
761 // start to read through InputStream
762 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
763 if (!jni_cid_BTsocket)
765 (*env)->DeleteLocalRef(env, jni_str_address);
767 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
768 return CA_STATUS_FAILED;
770 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
772 "()Ljava/io/InputStream;");
773 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
777 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
778 (*env)->DeleteLocalRef(env, jni_str_address);
780 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
781 return CA_STATUS_FAILED;
784 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
785 jni_mid_getInputStream);
786 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
788 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
789 if (!jni_cid_InputStream)
791 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
792 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
793 (*env)->DeleteLocalRef(env, jni_str_address);
795 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
796 return CA_STATUS_FAILED;
798 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
800 jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
804 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
805 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
806 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
807 (*env)->DeleteLocalRef(env, jni_str_address);
809 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
810 return CA_STATUS_FAILED;
813 ca_mutex_lock(g_mutexInputStream);
816 g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
819 jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
821 ca_mutex_unlock(g_mutexInputStream);
823 OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
827 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
828 (*env)->DeleteLocalRef(env, jbuf);
829 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
830 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
831 (*env)->DeleteLocalRef(env, jni_str_address);
833 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
834 return CA_STATUS_FAILED;
837 if ((*env)->ExceptionCheck(env))
839 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
840 (*env)->ExceptionDescribe(env);
841 (*env)->ExceptionClear(env);
843 // update state to disconnect
844 // the socket will be close next read thread routine
845 ca_mutex_lock(g_mutexStateList);
846 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
847 ca_mutex_unlock(g_mutexStateList);
848 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
850 (*env)->DeleteLocalRef(env, jbuf);
851 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
852 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
853 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
854 (*env)->DeleteLocalRef(env, jni_str_address);
856 return CA_STATUS_FAILED;
859 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
860 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
863 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
864 (*env)->DeleteLocalRef(env, jbuf);
865 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
866 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
867 (*env)->DeleteLocalRef(env, jni_str_address);
869 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
870 return CA_STATUS_FAILED;
873 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
875 char responseData[MAX_PDU_BUFFER] = { 0 };
876 memcpy(responseData, (const char*) buf, length);
880 case CA_UNICAST_SERVER:
881 case CA_MULTICAST_SERVER:
882 // Notify data to upper layer
883 if (g_edrPacketReceivedCallback)
885 uint32_t sentLength = 0;
886 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
887 %s, %d", responseData, length);
888 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
893 // Should never occur
894 OIC_LOG(ERROR, TAG, "Invalid server type");
895 return CA_STATUS_FAILED;
897 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
898 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
900 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
901 (*env)->DeleteLocalRef(env, jbuf);
902 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
903 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
904 (*env)->DeleteLocalRef(env, jni_str_address);
908 (*env)->ExceptionDescribe(env);
909 (*env)->ExceptionClear(env);
910 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
911 return CA_STATUS_FAILED;
917 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
919 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
921 if (!CAEDRNativeIsEnableBTAdapter(env))
923 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
929 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
933 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
934 if (!jni_cid_BTsocket)
936 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
940 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
942 if (!jni_mid_isConnected)
944 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
946 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
947 - jni_mid_isConnected is null.");
951 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
953 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
955 return jni_isConnected;
958 void CANativeStartListenTask(JNIEnv *env)
960 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
961 if (!jni_obj_BTServerSocket)
963 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
967 ca_mutex_lock(g_mutexServerSocket);
968 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
969 ca_mutex_unlock(g_mutexServerSocket);
972 jobject CAEDRNativeListen(JNIEnv *env)
974 if (!CAEDRNativeIsEnableBTAdapter(env))
976 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
980 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
982 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
983 if (!jni_cid_BTAdapter)
985 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
990 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
992 METHODID_OBJECTNONPARAM);
993 if (!jni_cid_BTAdapter)
995 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
999 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1000 jni_mid_getDefaultAdapter);
1001 if (!jni_obj_BTAdapter)
1003 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
1007 // get listen method ID
1008 jmethodID jni_mid_listen = (*env)->GetMethodID(
1009 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
1010 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
1011 if (!jni_mid_listen)
1013 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
1016 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
1018 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1021 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
1025 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
1026 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
1027 if (!jni_mid_fromString)
1029 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
1033 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
1036 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
1039 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1043 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
1048 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
1051 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
1054 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
1055 jni_name, jni_obj_uuid);
1056 if (!jni_obj_BTServerSocket)
1058 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1062 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1064 return jni_obj_BTServerSocket;
1067 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1069 if (NULL != serverSocketObject)
1071 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1072 env, "android/bluetooth/BluetoothServerSocket");
1073 if (!jni_cid_BTServerSocket)
1075 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1079 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1080 "()Landroid/bluetooth/BluetoothSocket;");
1081 if (!jni_mid_accept)
1083 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1087 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1089 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1091 if (!jni_obj_BTSocket)
1093 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1095 if ((*env)->ExceptionCheck(env))
1097 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1098 (*env)->ExceptionDescribe(env);
1099 (*env)->ExceptionClear(env);
1104 // get remote address
1105 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1108 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1112 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1113 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1115 // set socket to list
1116 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1117 ca_mutex_lock(g_mutexObjectList);
1118 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1119 ca_mutex_unlock(g_mutexObjectList);
1121 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1124 ca_mutex_lock(g_mutexStateList);
1125 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1126 ca_mutex_unlock(g_mutexStateList);
1127 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1131 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1136 * InputStream & BluetoothServerSocket will be close for Terminating.
1138 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1142 OIC_LOG(DEBUG, TAG, "InputStream will be close");
1143 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1144 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1145 (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1146 (*env)->DeleteGlobalRef(env, g_inputStream);
1147 g_inputStream = NULL;
1152 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1154 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1155 env, "android/bluetooth/BluetoothServerSocket");
1156 if (!jni_cid_BTServerSocket)
1158 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1162 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1163 if (!jni_mid_accept)
1165 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1168 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1169 (*env)->DeleteGlobalRef(env, g_serverSocket);
1170 g_serverSocket = NULL;
1172 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");