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;
236 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null");
239 (*g_jvm)->DetachCurrentThread(g_jvm);
244 // it should be initialized for restart accept thread
245 ca_mutex_lock(g_mutexAcceptServer);
246 g_stopAccept = false;
247 ca_mutex_unlock(g_mutexAcceptServer);
249 while (true != *(ctx->stopFlag))
251 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
253 // when BT state is changed with Off. its thread will be stopped
254 if (!CAEDRNativeIsEnableBTAdapter(env))
256 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
257 ca_mutex_lock(g_mutexAcceptServer);
259 ca_mutex_unlock(g_mutexAcceptServer);
260 ca_mutex_lock(g_mutexServerSocket);
261 g_serverSocket = NULL;
262 ca_mutex_unlock(g_mutexServerSocket);
266 CAEDRNativeAccept(env, g_serverSocket);
272 (*g_jvm)->DetachCurrentThread(g_jvm);
277 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
283 * implement for adapter common method.
285 CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
287 OIC_LOG(DEBUG, TAG, "IN");
288 CAEDRServerInitialize(handle);
289 CAResult_t res = CAEDRStartUnicastServer(false);
290 if (CA_STATUS_OK != res)
292 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
293 return CA_STATUS_FAILED;
296 OIC_LOG(DEBUG, TAG, "OUT");
300 CAResult_t CAEDRServerStop()
302 OIC_LOG(DEBUG, TAG, "IN");
303 CAEDRStopUnicastServer();
304 CAEDRStopMulticastServer();
306 ca_mutex_lock(g_mutexAcceptServer);
308 ca_mutex_unlock(g_mutexAcceptServer);
312 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
313 return CA_STATUS_FAILED;
316 bool isAttached = false;
318 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
321 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
322 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
326 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
327 return CA_STATUS_FAILED;
332 CAEDRNatvieCloseServerTask(env);
336 (*g_jvm)->DetachCurrentThread(g_jvm);
339 OIC_LOG(DEBUG, TAG, "OUT");
343 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
345 g_edrPacketReceivedCallback = packetReceivedCallback;
351 static void CAEDRServerDestroyMutex()
353 OIC_LOG(DEBUG, TAG, "IN");
355 if (g_mutexUnicastServer)
357 ca_mutex_free(g_mutexUnicastServer);
358 g_mutexUnicastServer = NULL;
361 if (g_mutexMulticastServer)
363 ca_mutex_free(g_mutexMulticastServer);
364 g_mutexMulticastServer = NULL;
367 if (g_mutexSocketListManager)
369 ca_mutex_free(g_mutexSocketListManager);
370 g_mutexSocketListManager = NULL;
373 if (g_mutexAcceptServer)
375 ca_mutex_free(g_mutexAcceptServer);
376 g_mutexAcceptServer = NULL;
379 if (g_mutexServerSocket)
381 ca_mutex_free(g_mutexServerSocket);
382 g_mutexServerSocket = NULL;
385 if (g_mutexStateList)
387 ca_mutex_free(g_mutexStateList);
388 g_mutexStateList = NULL;
391 if (g_mutexObjectList)
393 ca_mutex_free(g_mutexObjectList);
394 g_mutexObjectList = NULL;
397 if (g_mutexInputStream)
399 ca_mutex_free(g_mutexInputStream);
400 g_mutexInputStream = NULL;
403 OIC_LOG(DEBUG, TAG, "OUT");
409 static CAResult_t CAEDRServerCreateMutex()
411 OIC_LOG(DEBUG, TAG, "IN");
413 g_mutexUnicastServer = ca_mutex_new();
414 if (!g_mutexUnicastServer)
416 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
417 return CA_STATUS_FAILED;
420 g_mutexMulticastServer = ca_mutex_new();
421 if (!g_mutexMulticastServer)
423 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
425 CAEDRServerDestroyMutex();
426 return CA_STATUS_FAILED;
429 g_mutexSocketListManager = ca_mutex_new();
430 if (!g_mutexSocketListManager)
432 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
434 CAEDRServerDestroyMutex();
435 return CA_STATUS_FAILED;
438 g_mutexAcceptServer = ca_mutex_new();
439 if (!g_mutexAcceptServer)
441 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
443 CAEDRServerDestroyMutex();
444 return CA_STATUS_FAILED;
447 g_mutexServerSocket = ca_mutex_new();
448 if (!g_mutexServerSocket)
450 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
452 CAEDRServerDestroyMutex();
453 return CA_STATUS_FAILED;
456 g_mutexStateList = ca_mutex_new();
457 if (!g_mutexStateList)
459 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
461 CAEDRServerDestroyMutex();
462 return CA_STATUS_FAILED;
465 g_mutexObjectList = ca_mutex_new();
466 if (!g_mutexObjectList)
468 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
470 CAEDRServerDestroyMutex();
471 return CA_STATUS_FAILED;
474 g_mutexInputStream = ca_mutex_new();
475 if (!g_mutexInputStream)
477 OIC_LOG(ERROR, TAG, "Failed to created g_mutexInputStream.");
479 CAEDRServerDestroyMutex();
480 return CA_STATUS_FAILED;
483 OIC_LOG(DEBUG, TAG, "OUT");
487 void CAEDRServerJniInit()
489 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
490 g_jvm = CANativeJNIGetJavaVM();
493 void CAEDRServerInitialize(ca_thread_pool_t handle)
495 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
497 g_threadPoolHandle = handle;
499 CAEDRServerStartAcceptThread();
501 OIC_LOG(DEBUG, TAG, "OUT");
504 void CAEDRServerStartAcceptThread()
506 CAEDRServerJniInit();
509 CAEDRServerCreateMutex();
511 bool isAttached = false;
513 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
516 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
517 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
521 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
527 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
530 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
531 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
532 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
535 ca_mutex_lock(g_mutexStateList);
536 CAEDRNativeCreateDeviceStateList();
537 ca_mutex_unlock(g_mutexStateList);
539 ca_mutex_lock(g_mutexObjectList);
540 CAEDRNativeCreateDeviceSocketList();
541 ca_mutex_unlock(g_mutexObjectList);
545 (*g_jvm)->DetachCurrentThread(g_jvm);
548 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
549 sizeof(CAAdapterReceiveThreadContext_t));
552 OIC_LOG(ERROR, TAG, "Out of memory!");
556 ctx->stopFlag = &g_stopAccept;
557 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
559 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
560 OICFree((void *) ctx);
564 OIC_LOG(DEBUG, TAG, "OUT");
567 void CAEDRServerTerminate()
569 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
575 bool isAttached = false;
577 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
580 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
581 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
585 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
591 CAEDRNativeSocketCloseToAll(env);
595 (*g_jvm)->DetachCurrentThread(g_jvm);
598 CAEDRNativeRemoveAllDeviceState();
599 CAEDRNativeRemoveAllDeviceSocket(env);
602 CAEDRServerDestroyMutex();
605 CAResult_t CAEDRStartUnicastServer(bool isSecured)
607 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
609 ca_mutex_lock(g_mutexUnicastServer);
612 * The task to listen for data from unicast is added to the thread pool.
613 * This is a blocking call is made where we try to receive some data..
614 * We will keep waiting until some data is received.
615 * This task will be terminated when thread pool is freed on stopping the adapters.
616 * Thread context will be freed by thread on exit.
618 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
619 sizeof(CAAdapterReceiveThreadContext_t));
622 OIC_LOG(ERROR, TAG, "Out of memory!");
623 ca_mutex_unlock(g_mutexUnicastServer);
624 return CA_MEMORY_ALLOC_FAILED;
627 ctx->stopFlag = &g_stopUnicast;
628 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
629 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
631 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
632 ca_mutex_unlock(g_mutexUnicastServer);
633 OICFree((void *) ctx);
634 return CA_STATUS_FAILED;
636 ca_mutex_unlock(g_mutexUnicastServer);
638 OIC_LOG(DEBUG, TAG, "OUT");
642 CAResult_t CAEDRStartMulticastServer()
644 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
646 ca_mutex_lock(g_mutexMulticastServer);
649 * The task to listen to data from multicast socket is added to the thread pool.
650 * This is a blocking call is made where we try to receive some data.
651 * We will keep waiting until some data is received.
652 * This task will be terminated when thread pool is freed on stopping the adapters.
653 * Thread context will be freed by thread on exit.
655 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
656 sizeof(CAAdapterReceiveThreadContext_t));
659 OIC_LOG(ERROR, TAG, "Out of memory!");
660 ca_mutex_unlock(g_mutexMulticastServer);
662 return CA_MEMORY_ALLOC_FAILED;
665 ctx->stopFlag = &g_stopMulticast;
666 ctx->type = CA_MULTICAST_SERVER;
668 g_stopMulticast = false;
669 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
671 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
673 g_stopMulticast = true;
674 ca_mutex_unlock(g_mutexMulticastServer);
675 OICFree((void *) ctx);
677 return CA_STATUS_FAILED;
679 ca_mutex_unlock(g_mutexMulticastServer);
681 OIC_LOG(DEBUG, TAG, "OUT");
685 CAResult_t CAEDRStopUnicastServer()
687 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
689 ca_mutex_lock(g_mutexUnicastServer);
690 g_stopUnicast = true;
691 ca_mutex_unlock(g_mutexUnicastServer);
696 CAResult_t CAEDRStopMulticastServer()
698 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
700 ca_mutex_lock(g_mutexMulticastServer);
701 g_stopMulticast = true;
702 ca_mutex_unlock(g_mutexMulticastServer);
704 OIC_LOG(INFO, TAG, "Multicast server stopped");
709 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
711 if (!CAEDRNativeIsEnableBTAdapter(env))
713 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
714 return CA_STATUS_INVALID_PARAM;
717 if (!((*env)->ExceptionCheck(env)))
719 // check whether this socket object is connected or not.
720 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
723 return CA_STATUS_INVALID_PARAM;
726 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
727 if (!jni_str_address)
729 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
730 return CA_STATUS_FAILED;
732 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
734 // check it whether is still connected or not through google api
735 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
738 OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket");
741 // check it whether is still connected or not through socket state list
742 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
744 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet..");
746 // remove socket to list
747 // this code is related to below read fail exception code
748 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
749 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
751 (*env)->DeleteLocalRef(env, jni_str_address);
753 return CA_STATUS_FAILED;
756 // start to read through InputStream
757 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
758 if (!jni_cid_BTsocket)
760 (*env)->DeleteLocalRef(env, jni_str_address);
762 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
763 return CA_STATUS_FAILED;
765 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
767 "()Ljava/io/InputStream;");
768 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
772 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
773 (*env)->DeleteLocalRef(env, jni_str_address);
775 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
776 return CA_STATUS_FAILED;
779 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
780 jni_mid_getInputStream);
781 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
783 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
784 if (!jni_cid_InputStream)
786 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
787 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
788 (*env)->DeleteLocalRef(env, jni_str_address);
790 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
791 return CA_STATUS_FAILED;
793 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
795 jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
799 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
800 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
801 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
802 (*env)->DeleteLocalRef(env, jni_str_address);
804 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
805 return CA_STATUS_FAILED;
808 ca_mutex_lock(g_mutexInputStream);
811 g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
814 jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
816 ca_mutex_unlock(g_mutexInputStream);
818 OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
822 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
823 (*env)->DeleteLocalRef(env, jbuf);
824 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
825 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
826 (*env)->DeleteLocalRef(env, jni_str_address);
828 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
829 return CA_STATUS_FAILED;
832 if ((*env)->ExceptionCheck(env))
834 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
835 (*env)->ExceptionDescribe(env);
836 (*env)->ExceptionClear(env);
838 // update state to disconnect
839 // the socket will be close next read thread routine
840 ca_mutex_lock(g_mutexStateList);
841 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
842 ca_mutex_unlock(g_mutexStateList);
843 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
845 (*env)->DeleteLocalRef(env, jbuf);
846 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
847 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
848 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
849 (*env)->DeleteLocalRef(env, jni_str_address);
851 return CA_STATUS_FAILED;
854 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
855 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
858 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
859 (*env)->DeleteLocalRef(env, jbuf);
860 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
861 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
862 (*env)->DeleteLocalRef(env, jni_str_address);
864 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
865 return CA_STATUS_FAILED;
868 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
870 char responseData[MAX_PDU_BUFFER] = { 0 };
871 memcpy(responseData, (const char*) buf, length);
875 case CA_UNICAST_SERVER:
876 case CA_MULTICAST_SERVER:
877 // Notify data to upper layer
878 if (g_edrPacketReceivedCallback)
880 uint32_t sentLength = 0;
881 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
882 %s, %d", responseData, length);
883 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
888 // Should never occur
889 OIC_LOG(ERROR, TAG, "Invalid server type");
890 return CA_STATUS_FAILED;
892 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
893 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
895 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
896 (*env)->DeleteLocalRef(env, jbuf);
897 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
898 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
899 (*env)->DeleteLocalRef(env, jni_str_address);
903 (*env)->ExceptionDescribe(env);
904 (*env)->ExceptionClear(env);
905 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
906 return CA_STATUS_FAILED;
912 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
914 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
916 if (!CAEDRNativeIsEnableBTAdapter(env))
918 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
924 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
928 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
929 if (!jni_cid_BTsocket)
931 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
935 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
937 if (!jni_mid_isConnected)
939 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
941 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
942 - jni_mid_isConnected is null.");
946 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
948 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
950 return jni_isConnected;
953 void CANativeStartListenTask(JNIEnv *env)
955 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
956 if (!jni_obj_BTServerSocket)
958 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
962 ca_mutex_lock(g_mutexServerSocket);
963 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
964 ca_mutex_unlock(g_mutexServerSocket);
967 jobject CAEDRNativeListen(JNIEnv *env)
969 if (!CAEDRNativeIsEnableBTAdapter(env))
971 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
975 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
977 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
978 if (!jni_cid_BTAdapter)
980 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
985 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
987 METHODID_OBJECTNONPARAM);
988 if (!jni_cid_BTAdapter)
990 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
994 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
995 jni_mid_getDefaultAdapter);
996 if (!jni_obj_BTAdapter)
998 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
1002 // get listen method ID
1003 jmethodID jni_mid_listen = (*env)->GetMethodID(
1004 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
1005 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
1006 if (!jni_mid_listen)
1008 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
1011 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
1013 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1016 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
1020 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
1021 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
1022 if (!jni_mid_fromString)
1024 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
1028 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
1031 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
1034 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1038 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
1043 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
1046 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
1049 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
1050 jni_name, jni_obj_uuid);
1051 if (!jni_obj_BTServerSocket)
1053 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1057 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1059 return jni_obj_BTServerSocket;
1062 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1064 if (NULL != serverSocketObject)
1066 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1067 env, "android/bluetooth/BluetoothServerSocket");
1068 if (!jni_cid_BTServerSocket)
1070 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1074 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1075 "()Landroid/bluetooth/BluetoothSocket;");
1076 if (!jni_mid_accept)
1078 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1082 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1084 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1086 if (!jni_obj_BTSocket)
1088 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1090 if ((*env)->ExceptionCheck(env))
1092 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1093 (*env)->ExceptionDescribe(env);
1094 (*env)->ExceptionClear(env);
1099 // get remote address
1100 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1103 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1107 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1108 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1110 // set socket to list
1111 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1112 ca_mutex_lock(g_mutexObjectList);
1113 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1114 ca_mutex_unlock(g_mutexObjectList);
1116 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1119 ca_mutex_lock(g_mutexStateList);
1120 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1121 ca_mutex_unlock(g_mutexStateList);
1122 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1126 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1131 * InputStream & BluetoothServerSocket will be close for Terminating.
1133 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1137 OIC_LOG(DEBUG, TAG, "InputStream will be close");
1138 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1139 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1140 (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1141 (*env)->DeleteGlobalRef(env, g_inputStream);
1142 g_inputStream = NULL;
1147 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1149 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1150 env, "android/bluetooth/BluetoothServerSocket");
1151 if (!jni_cid_BTServerSocket)
1153 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1157 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1158 if (!jni_mid_accept)
1160 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1163 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1164 (*env)->DeleteGlobalRef(env, g_serverSocket);
1165 g_serverSocket = NULL;
1167 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");