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;
90 * Mutex to synchronize server socket.
92 static ca_mutex g_mutexServerSocket = NULL;
94 static jobject g_serverSocket = NULL;
97 * Mutex to synchronize device state list.
99 static ca_mutex g_mutexStateList = NULL;
102 * Mutex to synchronize device object list.
104 static ca_mutex g_mutexObjectList = NULL;
106 typedef struct send_data
114 * Thread context information for unicast, multicast and secured unicast server.
119 CAAdapterServerType_t type;
120 } CAAdapterReceiveThreadContext_t;
125 } CAAdapterAcceptThreadContext_t;
128 * Maintains the callback to be notified when data received from remote
131 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
133 static void CAReceiveHandler(void *data)
135 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
137 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
139 bool isAttached = false;
141 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
144 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
145 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
149 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
155 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
157 while (true != *(ctx->stopFlag))
159 // if new socket object is added in socket list after below logic is ran.
160 // new socket will be started to read after next while loop
161 uint32_t length = CAEDRGetSocketListLength();
164 for (uint32_t idx = 0; idx < length; idx++)
166 CAEDRNativeReadData(env, idx, ctx->type);
173 (*g_jvm)->DetachCurrentThread(g_jvm);
178 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
181 static void CAAcceptHandler(void *data)
185 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
189 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
191 bool isAttached = false;
193 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
196 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
197 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
201 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
207 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
208 if (!jni_obj_BTServerSocket)
210 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
214 (*g_jvm)->DetachCurrentThread(g_jvm);
220 ca_mutex_lock(g_mutexServerSocket);
221 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
222 ca_mutex_unlock(g_mutexServerSocket);
224 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
226 // it should be initialized for restart accept thread
227 ca_mutex_lock(g_mutexAcceptServer);
228 g_stopAccept = false;
229 ca_mutex_unlock(g_mutexAcceptServer);
231 while (true != *(ctx->stopFlag))
233 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
235 // when BT state is changed with Off. its thread will be stopped
236 if (!CAEDRNativeIsEnableBTAdapter(env))
238 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
239 ca_mutex_lock(g_mutexAcceptServer);
241 ca_mutex_unlock(g_mutexAcceptServer);
242 ca_mutex_lock(g_mutexServerSocket);
243 g_serverSocket = NULL;
244 ca_mutex_unlock(g_mutexServerSocket);
248 CAEDRNativeAccept(env, g_serverSocket);
254 (*g_jvm)->DetachCurrentThread(g_jvm);
259 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
265 * implement for adapter common method.
267 CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
269 OIC_LOG(DEBUG, TAG, "IN");
270 CAEDRServerInitialize(handle);
271 CAResult_t res = CAEDRStartUnicastServer(false);
272 if (CA_STATUS_OK != res)
274 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
275 return CA_STATUS_FAILED;
278 OIC_LOG(DEBUG, TAG, "OUT");
282 CAResult_t CAEDRServerStop()
284 OIC_LOG(DEBUG, TAG, "IN");
285 CAEDRStopUnicastServer();
286 CAEDRStopMulticastServer();
288 ca_mutex_lock(g_mutexAcceptServer);
290 ca_mutex_unlock(g_mutexAcceptServer);
294 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
295 return CA_STATUS_FAILED;
298 bool isAttached = false;
300 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
303 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
304 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
308 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
309 return CA_STATUS_FAILED;
314 CAEDRNatvieCloseServerTask(env);
318 (*g_jvm)->DetachCurrentThread(g_jvm);
321 OIC_LOG(DEBUG, TAG, "OUT");
325 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
327 g_edrPacketReceivedCallback = packetReceivedCallback;
333 static void CAEDRServerDestroyMutex()
335 OIC_LOG(DEBUG, TAG, "IN");
337 if (g_mutexUnicastServer)
339 ca_mutex_free(g_mutexUnicastServer);
340 g_mutexUnicastServer = NULL;
343 if (g_mutexMulticastServer)
345 ca_mutex_free(g_mutexMulticastServer);
346 g_mutexMulticastServer = NULL;
349 if (g_mutexSocketListManager)
351 ca_mutex_free(g_mutexSocketListManager);
352 g_mutexSocketListManager = NULL;
355 if (g_mutexAcceptServer)
357 ca_mutex_free(g_mutexAcceptServer);
358 g_mutexAcceptServer = NULL;
361 if (g_mutexServerSocket)
363 ca_mutex_free(g_mutexServerSocket);
364 g_mutexServerSocket = NULL;
367 if (g_mutexStateList)
369 ca_mutex_free(g_mutexStateList);
370 g_mutexStateList = NULL;
373 if (g_mutexObjectList)
375 ca_mutex_free(g_mutexObjectList);
376 g_mutexObjectList = NULL;
379 OIC_LOG(DEBUG, TAG, "OUT");
385 static CAResult_t CAEDRServerCreateMutex()
387 OIC_LOG(DEBUG, TAG, "IN");
389 g_mutexUnicastServer = ca_mutex_new();
390 if (!g_mutexUnicastServer)
392 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
393 return CA_STATUS_FAILED;
396 g_mutexMulticastServer = ca_mutex_new();
397 if (!g_mutexMulticastServer)
399 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
401 CAEDRServerDestroyMutex();
402 return CA_STATUS_FAILED;
405 g_mutexSocketListManager = ca_mutex_new();
406 if (!g_mutexSocketListManager)
408 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
410 CAEDRServerDestroyMutex();
411 return CA_STATUS_FAILED;
414 g_mutexAcceptServer = ca_mutex_new();
415 if (!g_mutexAcceptServer)
417 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
419 CAEDRServerDestroyMutex();
420 return CA_STATUS_FAILED;
423 g_mutexServerSocket = ca_mutex_new();
424 if (!g_mutexServerSocket)
426 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
428 CAEDRServerDestroyMutex();
429 return CA_STATUS_FAILED;
432 g_mutexStateList = ca_mutex_new();
433 if (!g_mutexStateList)
435 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
437 CAEDRServerDestroyMutex();
438 return CA_STATUS_FAILED;
441 g_mutexObjectList = ca_mutex_new();
442 if (!g_mutexObjectList)
444 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
446 CAEDRServerDestroyMutex();
447 return CA_STATUS_FAILED;
450 OIC_LOG(DEBUG, TAG, "OUT");
454 void CAEDRServerJniInit()
456 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
457 g_jvm = CANativeJNIGetJavaVM();
460 void CAEDRServerInitialize(ca_thread_pool_t handle)
462 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
464 g_threadPoolHandle = handle;
466 CAEDRServerStartAcceptThread();
468 OIC_LOG(DEBUG, TAG, "OUT");
471 void CAEDRServerStartAcceptThread()
473 CAEDRServerJniInit();
476 CAEDRServerCreateMutex();
478 bool isAttached = false;
480 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
483 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
484 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
488 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
494 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
497 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
498 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
499 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
502 ca_mutex_lock(g_mutexStateList);
503 CAEDRNativeCreateDeviceStateList();
504 ca_mutex_unlock(g_mutexStateList);
506 ca_mutex_lock(g_mutexObjectList);
507 CAEDRNativeCreateDeviceSocketList();
508 ca_mutex_unlock(g_mutexObjectList);
512 (*g_jvm)->DetachCurrentThread(g_jvm);
515 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
516 sizeof(CAAdapterReceiveThreadContext_t));
519 OIC_LOG(ERROR, TAG, "Out of memory!");
523 ctx->stopFlag = &g_stopAccept;
524 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
526 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
527 OICFree((void *) ctx);
531 OIC_LOG(DEBUG, TAG, "OUT");
534 void CAEDRServerTerminate()
536 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
542 bool isAttached = false;
544 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
547 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
548 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
552 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
558 CAEDRNativeSocketCloseToAll(env);
562 (*g_jvm)->DetachCurrentThread(g_jvm);
565 CAEDRNativeRemoveAllDeviceState();
566 CAEDRNativeRemoveAllDeviceSocket(env);
569 CAEDRServerDestroyMutex();
572 CAResult_t CAEDRStartUnicastServer(bool isSecured)
574 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
576 ca_mutex_lock(g_mutexUnicastServer);
579 * The task to listen for data from unicast is added to the thread pool.
580 * This is a blocking call is made where we try to receive some data..
581 * We will keep waiting until some data is received.
582 * This task will be terminated when thread pool is freed on stopping the adapters.
583 * Thread context will be freed by thread on exit.
585 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
586 sizeof(CAAdapterReceiveThreadContext_t));
589 OIC_LOG(ERROR, TAG, "Out of memory!");
590 ca_mutex_unlock(g_mutexUnicastServer);
591 return CA_MEMORY_ALLOC_FAILED;
594 ctx->stopFlag = &g_stopUnicast;
595 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
596 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
598 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
599 ca_mutex_unlock(g_mutexUnicastServer);
600 OICFree((void *) ctx);
601 return CA_STATUS_FAILED;
603 ca_mutex_unlock(g_mutexUnicastServer);
605 OIC_LOG(DEBUG, TAG, "OUT");
609 CAResult_t CAEDRStartMulticastServer()
611 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
613 ca_mutex_lock(g_mutexMulticastServer);
616 * The task to listen to data from multicast socket is added to the thread pool.
617 * This is a blocking call is made where we try to receive some data.
618 * We will keep waiting until some data is received.
619 * This task will be terminated when thread pool is freed on stopping the adapters.
620 * Thread context will be freed by thread on exit.
622 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
623 sizeof(CAAdapterReceiveThreadContext_t));
626 OIC_LOG(ERROR, TAG, "Out of memory!");
627 ca_mutex_unlock(g_mutexMulticastServer);
629 return CA_MEMORY_ALLOC_FAILED;
632 ctx->stopFlag = &g_stopMulticast;
633 ctx->type = CA_MULTICAST_SERVER;
635 g_stopMulticast = false;
636 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
638 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
640 g_stopMulticast = true;
641 ca_mutex_unlock(g_mutexMulticastServer);
642 OICFree((void *) ctx);
644 return CA_STATUS_FAILED;
646 ca_mutex_unlock(g_mutexMulticastServer);
648 OIC_LOG(DEBUG, TAG, "OUT");
652 CAResult_t CAEDRStopUnicastServer()
654 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
656 ca_mutex_lock(g_mutexUnicastServer);
657 g_stopUnicast = true;
658 ca_mutex_unlock(g_mutexUnicastServer);
663 CAResult_t CAEDRStopMulticastServer()
665 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
667 ca_mutex_lock(g_mutexMulticastServer);
668 g_stopMulticast = true;
669 ca_mutex_unlock(g_mutexMulticastServer);
671 OIC_LOG(INFO, TAG, "Multicast server stopped");
676 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
678 if (!CAEDRNativeIsEnableBTAdapter(env))
680 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
681 return CA_STATUS_INVALID_PARAM;
684 if (!((*env)->ExceptionCheck(env)))
686 // check whether this socket object is connected or not.
687 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
690 return CA_STATUS_INVALID_PARAM;
693 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
694 if (!jni_str_address)
696 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
697 return CA_STATUS_FAILED;
699 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
701 // check it whether is still connected or not through google api
702 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
705 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet.");
707 // remove socket to list
708 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
709 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
711 (*env)->DeleteLocalRef(env, jni_str_address);
713 return CA_STATUS_FAILED;
716 // start to read through InputStream
717 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
718 if (!jni_cid_BTsocket)
720 (*env)->DeleteLocalRef(env, jni_str_address);
722 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
723 return CA_STATUS_FAILED;
725 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
727 "()Ljava/io/InputStream;");
729 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
730 jni_mid_getInputStream);
731 if (!jni_obj_inputStream)
733 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
734 (*env)->DeleteLocalRef(env, jni_str_address);
736 OIC_LOG(ERROR, TAG, "[EDR] btReadData: jni_obj_inputStream is null");
737 return CA_STATUS_FAILED;
740 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
741 if (!jni_cid_InputStream)
743 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
744 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
745 (*env)->DeleteLocalRef(env, jni_str_address);
747 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
748 return CA_STATUS_FAILED;
751 jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream,
753 if (!jni_mid_available) {
754 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
755 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
756 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
757 (*env)->DeleteLocalRef(env, jni_str_address);
759 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_mid_available is null");
760 return CA_STATUS_FAILED;
763 jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
765 jbyteArray jbuf = NULL;
769 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
770 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream,
773 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
774 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
775 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
776 (*env)->DeleteLocalRef(env, jni_str_address);
778 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_mid_read is null");
779 return CA_STATUS_FAILED;
782 jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
783 length = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read, jbuf, (jint) 0,
785 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: read something from InputStream");
788 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
792 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
795 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
796 (*env)->DeleteLocalRef(env, jbuf);
798 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
799 (*env)->DeleteLocalRef(env, jni_str_address);
801 return CA_STATUS_FAILED;
804 if ((*env)->ExceptionCheck(env))
806 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
807 (*env)->ExceptionDescribe(env);
808 (*env)->ExceptionClear(env);
810 // update state to disconnect
811 // the socket will be close next read thread routine
812 ca_mutex_lock(g_mutexStateList);
813 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
814 ca_mutex_unlock(g_mutexStateList);
815 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
817 (*env)->DeleteLocalRef(env, jbuf);
818 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
819 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
820 (*env)->DeleteLocalRef(env, jni_str_address);
822 return CA_STATUS_FAILED;
825 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
826 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
829 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
830 (*env)->DeleteLocalRef(env, jbuf);
831 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
832 (*env)->DeleteLocalRef(env, jni_str_address);
834 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
835 return CA_STATUS_FAILED;
838 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
840 char responseData[MAX_PDU_BUFFER] = { 0 };
841 memcpy(responseData, (const char*) buf, length);
845 case CA_UNICAST_SERVER:
846 case CA_MULTICAST_SERVER:
847 // Notify data to upper layer
848 if (g_edrPacketReceivedCallback)
850 uint32_t sentLength = 0;
851 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
852 %s, %d", responseData, length);
853 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
858 // Should never occur
859 OIC_LOG(ERROR, TAG, "Invalid server type");
860 return CA_STATUS_FAILED;
862 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
863 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
865 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
866 (*env)->DeleteLocalRef(env, jbuf);
867 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
868 (*env)->DeleteLocalRef(env, jni_str_address);
872 (*env)->ExceptionDescribe(env);
873 (*env)->ExceptionClear(env);
874 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
875 return CA_STATUS_FAILED;
881 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
885 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
889 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
890 if (!jni_cid_BTsocket)
892 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
896 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
898 if (!jni_mid_isConnected)
900 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
902 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
903 - jni_mid_isConnected is null.");
907 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
909 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
911 return jni_isConnected;
914 void CANativeStartListenTask(JNIEnv *env)
916 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
917 if (!jni_obj_BTServerSocket)
919 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
923 ca_mutex_lock(g_mutexServerSocket);
924 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
925 ca_mutex_unlock(g_mutexServerSocket);
928 jobject CAEDRNativeListen(JNIEnv *env)
930 if (!CAEDRNativeIsEnableBTAdapter(env))
932 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
936 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
938 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
939 if (!jni_cid_BTAdapter)
941 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
946 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
948 METHODID_OBJECTNONPARAM);
949 if (!jni_mid_getDefaultAdapter)
951 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_getDefaultAdapter is null");
955 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
956 jni_mid_getDefaultAdapter);
957 if (!jni_obj_BTAdapter)
959 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
963 // get listen method ID
964 jmethodID jni_mid_listen = (*env)->GetMethodID(
965 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
966 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
969 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
972 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
974 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
977 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
981 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
982 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
983 if (!jni_mid_fromString)
985 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
989 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
992 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
995 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
999 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
1004 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
1007 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
1010 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
1011 jni_name, jni_obj_uuid);
1012 if (!jni_obj_BTServerSocket)
1014 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1018 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1020 return jni_obj_BTServerSocket;
1023 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1025 if (NULL != serverSocketObject)
1027 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1028 env, "android/bluetooth/BluetoothServerSocket");
1029 if (!jni_cid_BTServerSocket)
1031 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1035 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1036 "()Landroid/bluetooth/BluetoothSocket;");
1037 if (!jni_mid_accept)
1039 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1043 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1045 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1047 if (!jni_obj_BTSocket)
1049 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1051 if ((*env)->ExceptionCheck(env))
1053 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1054 (*env)->ExceptionDescribe(env);
1055 (*env)->ExceptionClear(env);
1060 // get remote address
1061 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1064 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1068 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1069 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1071 // set socket to list
1072 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1073 ca_mutex_lock(g_mutexObjectList);
1074 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1075 ca_mutex_unlock(g_mutexObjectList);
1077 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1080 ca_mutex_lock(g_mutexStateList);
1081 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1082 ca_mutex_unlock(g_mutexStateList);
1083 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1087 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1092 * InputStream & BluetoothServerSocket will be close for Terminating.
1094 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1098 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1100 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1101 env, "android/bluetooth/BluetoothServerSocket");
1102 if (!jni_cid_BTServerSocket)
1104 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1108 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1109 if (!jni_mid_accept)
1111 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1114 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1115 (*env)->DeleteGlobalRef(env, g_serverSocket);
1116 g_serverSocket = NULL;
1118 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");