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("OIC_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 ca_mutex_lock(g_mutexUnicastServer);
158 g_stopUnicast = false;
159 ca_mutex_unlock(g_mutexUnicastServer);
161 while (true != *(ctx->stopFlag))
163 // if new socket object is added in socket list after below logic is ran.
164 // new socket will be started to read after next while loop
165 uint32_t length = CAEDRGetSocketListLength();
168 for (uint32_t idx = 0; idx < length; idx++)
170 CAEDRNativeReadData(env, idx, ctx->type);
177 (*g_jvm)->DetachCurrentThread(g_jvm);
182 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
185 static void CAAcceptHandler(void *data)
189 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
193 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
195 bool isAttached = false;
197 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
200 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
201 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
205 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
211 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
212 if (!jni_obj_BTServerSocket)
214 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
218 (*g_jvm)->DetachCurrentThread(g_jvm);
224 ca_mutex_lock(g_mutexServerSocket);
225 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
226 ca_mutex_unlock(g_mutexServerSocket);
228 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
230 // it should be initialized for restart accept thread
231 ca_mutex_lock(g_mutexAcceptServer);
232 g_stopAccept = false;
233 ca_mutex_unlock(g_mutexAcceptServer);
235 while (true != *(ctx->stopFlag))
237 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
239 // when BT state is changed with Off. its thread will be stopped
240 if (!CAEDRNativeIsEnableBTAdapter(env))
242 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
243 ca_mutex_lock(g_mutexAcceptServer);
245 ca_mutex_unlock(g_mutexAcceptServer);
246 ca_mutex_lock(g_mutexServerSocket);
247 g_serverSocket = NULL;
248 ca_mutex_unlock(g_mutexServerSocket);
252 CAEDRNativeAccept(env, g_serverSocket);
258 (*g_jvm)->DetachCurrentThread(g_jvm);
263 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
269 * implement for adapter common method.
271 CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
273 OIC_LOG(DEBUG, TAG, "IN");
274 CAEDRServerInitialize(handle);
275 CAResult_t res = CAEDRStartUnicastServer(false);
276 if (CA_STATUS_OK != res)
278 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
279 return CA_STATUS_FAILED;
282 OIC_LOG(DEBUG, TAG, "OUT");
286 CAResult_t CAEDRServerStop()
288 OIC_LOG(DEBUG, TAG, "IN");
289 CAEDRStopUnicastServer();
290 CAEDRStopMulticastServer();
292 ca_mutex_lock(g_mutexAcceptServer);
294 ca_mutex_unlock(g_mutexAcceptServer);
298 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
299 return CA_STATUS_FAILED;
302 bool isAttached = false;
304 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
307 OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
308 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
312 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
313 return CA_STATUS_FAILED;
318 CAEDRNatvieCloseServerTask(env);
322 (*g_jvm)->DetachCurrentThread(g_jvm);
325 OIC_LOG(DEBUG, TAG, "OUT");
329 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
331 g_edrPacketReceivedCallback = packetReceivedCallback;
337 static void CAEDRServerDestroyMutex()
339 OIC_LOG(DEBUG, TAG, "IN");
341 if (g_mutexUnicastServer)
343 ca_mutex_free(g_mutexUnicastServer);
344 g_mutexUnicastServer = NULL;
347 if (g_mutexMulticastServer)
349 ca_mutex_free(g_mutexMulticastServer);
350 g_mutexMulticastServer = NULL;
353 if (g_mutexSocketListManager)
355 ca_mutex_free(g_mutexSocketListManager);
356 g_mutexSocketListManager = NULL;
359 if (g_mutexAcceptServer)
361 ca_mutex_free(g_mutexAcceptServer);
362 g_mutexAcceptServer = NULL;
365 if (g_mutexServerSocket)
367 ca_mutex_free(g_mutexServerSocket);
368 g_mutexServerSocket = NULL;
371 if (g_mutexStateList)
373 ca_mutex_free(g_mutexStateList);
374 g_mutexStateList = NULL;
377 if (g_mutexObjectList)
379 ca_mutex_free(g_mutexObjectList);
380 g_mutexObjectList = NULL;
383 OIC_LOG(DEBUG, TAG, "OUT");
389 static CAResult_t CAEDRServerCreateMutex()
391 OIC_LOG(DEBUG, TAG, "IN");
393 g_mutexUnicastServer = ca_mutex_new();
394 if (!g_mutexUnicastServer)
396 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
397 return CA_STATUS_FAILED;
400 g_mutexMulticastServer = ca_mutex_new();
401 if (!g_mutexMulticastServer)
403 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
405 CAEDRServerDestroyMutex();
406 return CA_STATUS_FAILED;
409 g_mutexSocketListManager = ca_mutex_new();
410 if (!g_mutexSocketListManager)
412 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
414 CAEDRServerDestroyMutex();
415 return CA_STATUS_FAILED;
418 g_mutexAcceptServer = ca_mutex_new();
419 if (!g_mutexAcceptServer)
421 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
423 CAEDRServerDestroyMutex();
424 return CA_STATUS_FAILED;
427 g_mutexServerSocket = ca_mutex_new();
428 if (!g_mutexServerSocket)
430 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
432 CAEDRServerDestroyMutex();
433 return CA_STATUS_FAILED;
436 g_mutexStateList = ca_mutex_new();
437 if (!g_mutexStateList)
439 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
441 CAEDRServerDestroyMutex();
442 return CA_STATUS_FAILED;
445 g_mutexObjectList = ca_mutex_new();
446 if (!g_mutexObjectList)
448 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
450 CAEDRServerDestroyMutex();
451 return CA_STATUS_FAILED;
454 OIC_LOG(DEBUG, TAG, "OUT");
458 void CAEDRServerJniInit()
460 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
461 g_jvm = CANativeJNIGetJavaVM();
464 void CAEDRServerInitialize(ca_thread_pool_t handle)
466 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
468 g_threadPoolHandle = handle;
470 CAEDRServerStartAcceptThread();
472 OIC_LOG(DEBUG, TAG, "OUT");
475 void CAEDRServerStartAcceptThread()
477 CAEDRServerJniInit();
480 CAEDRServerCreateMutex();
482 bool isAttached = false;
484 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
487 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
488 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
492 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
498 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
501 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
502 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
503 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
506 ca_mutex_lock(g_mutexStateList);
507 CAEDRNativeCreateDeviceStateList();
508 ca_mutex_unlock(g_mutexStateList);
510 ca_mutex_lock(g_mutexObjectList);
511 CAEDRNativeCreateDeviceSocketList();
512 ca_mutex_unlock(g_mutexObjectList);
516 (*g_jvm)->DetachCurrentThread(g_jvm);
519 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
520 sizeof(CAAdapterReceiveThreadContext_t));
523 OIC_LOG(ERROR, TAG, "Out of memory!");
527 ctx->stopFlag = &g_stopAccept;
528 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
530 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
531 OICFree((void *) ctx);
535 OIC_LOG(DEBUG, TAG, "OUT");
538 void CAEDRServerTerminate()
540 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
546 bool isAttached = false;
548 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
551 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
552 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
556 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
562 CAEDRNativeSocketCloseToAll(env);
566 (*g_jvm)->DetachCurrentThread(g_jvm);
569 CAEDRNativeRemoveAllDeviceState();
570 CAEDRNativeRemoveAllDeviceSocket(env);
573 CAEDRServerDestroyMutex();
576 CAResult_t CAEDRStartUnicastServer(bool isSecured)
578 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
580 ca_mutex_lock(g_mutexUnicastServer);
583 * The task to listen for data from unicast is added to the thread pool.
584 * This is a blocking call is made where we try to receive some data..
585 * We will keep waiting until some data is received.
586 * This task will be terminated when thread pool is freed on stopping the adapters.
587 * Thread context will be freed by thread on exit.
589 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
590 sizeof(CAAdapterReceiveThreadContext_t));
593 OIC_LOG(ERROR, TAG, "Out of memory!");
594 ca_mutex_unlock(g_mutexUnicastServer);
595 return CA_MEMORY_ALLOC_FAILED;
598 ctx->stopFlag = &g_stopUnicast;
599 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
600 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
602 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
603 ca_mutex_unlock(g_mutexUnicastServer);
604 OICFree((void *) ctx);
605 return CA_STATUS_FAILED;
607 ca_mutex_unlock(g_mutexUnicastServer);
609 OIC_LOG(DEBUG, TAG, "OUT");
613 CAResult_t CAEDRStartMulticastServer()
615 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
617 ca_mutex_lock(g_mutexMulticastServer);
620 * The task to listen to data from multicast socket is added to the thread pool.
621 * This is a blocking call is made where we try to receive some data.
622 * We will keep waiting until some data is received.
623 * This task will be terminated when thread pool is freed on stopping the adapters.
624 * Thread context will be freed by thread on exit.
626 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
627 sizeof(CAAdapterReceiveThreadContext_t));
630 OIC_LOG(ERROR, TAG, "Out of memory!");
631 ca_mutex_unlock(g_mutexMulticastServer);
633 return CA_MEMORY_ALLOC_FAILED;
636 ctx->stopFlag = &g_stopMulticast;
637 ctx->type = CA_MULTICAST_SERVER;
639 g_stopMulticast = false;
640 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
642 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
644 g_stopMulticast = true;
645 ca_mutex_unlock(g_mutexMulticastServer);
646 OICFree((void *) ctx);
648 return CA_STATUS_FAILED;
650 ca_mutex_unlock(g_mutexMulticastServer);
652 OIC_LOG(DEBUG, TAG, "OUT");
656 CAResult_t CAEDRStopUnicastServer()
658 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
660 ca_mutex_lock(g_mutexUnicastServer);
661 g_stopUnicast = true;
662 ca_mutex_unlock(g_mutexUnicastServer);
667 CAResult_t CAEDRStopMulticastServer()
669 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
671 ca_mutex_lock(g_mutexMulticastServer);
672 g_stopMulticast = true;
673 ca_mutex_unlock(g_mutexMulticastServer);
675 OIC_LOG(INFO, TAG, "Multicast server stopped");
680 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
682 if (!CAEDRNativeIsEnableBTAdapter(env))
684 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
685 return CA_STATUS_INVALID_PARAM;
688 if (!((*env)->ExceptionCheck(env)))
690 // check whether this socket object is connected or not.
691 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
694 return CA_STATUS_INVALID_PARAM;
697 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
698 if (!jni_str_address)
700 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
701 return CA_STATUS_FAILED;
703 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
705 // check it whether is still connected or not through google api
706 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
709 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet.");
711 // remove socket to list
712 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
713 CAEDRNativeRemoveDevice(address);
714 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
716 (*env)->DeleteLocalRef(env, jni_str_address);
718 return CA_STATUS_FAILED;
721 // start to read through InputStream
722 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
723 if (!jni_cid_BTsocket)
725 (*env)->DeleteLocalRef(env, jni_str_address);
726 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
727 return CA_STATUS_FAILED;
729 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
731 "()Ljava/io/InputStream;");
733 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
734 jni_mid_getInputStream);
735 if (!jni_obj_inputStream)
737 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
738 (*env)->DeleteLocalRef(env, jni_str_address);
740 OIC_LOG(ERROR, TAG, "[EDR] btReadData: jni_obj_inputStream is null");
741 return CA_STATUS_FAILED;
744 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
745 if (!jni_cid_InputStream)
747 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
748 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
749 (*env)->DeleteLocalRef(env, jni_str_address);
751 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
752 return CA_STATUS_FAILED;
755 jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream,
757 if (!jni_mid_available) {
758 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
759 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
760 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
761 (*env)->DeleteLocalRef(env, jni_str_address);
763 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_mid_available is null");
764 return CA_STATUS_FAILED;
767 jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
769 jbyteArray jbuf = NULL;
773 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
774 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream,
777 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
778 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
779 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
780 (*env)->DeleteLocalRef(env, jni_str_address);
782 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_mid_read is null");
783 return CA_STATUS_FAILED;
786 jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
787 length = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read, jbuf, (jint) 0,
789 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: read something from InputStream");
792 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
796 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
799 OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
800 (*env)->DeleteLocalRef(env, jbuf);
802 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
803 (*env)->DeleteLocalRef(env, jni_str_address);
805 return CA_STATUS_FAILED;
808 if ((*env)->ExceptionCheck(env))
810 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
811 (*env)->ExceptionDescribe(env);
812 (*env)->ExceptionClear(env);
814 // update state to disconnect
815 // the socket will be close next read thread routine
816 ca_mutex_lock(g_mutexStateList);
817 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
818 ca_mutex_unlock(g_mutexStateList);
819 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
821 (*env)->DeleteLocalRef(env, jbuf);
822 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
823 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
824 (*env)->DeleteLocalRef(env, jni_str_address);
826 return CA_STATUS_FAILED;
829 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
830 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
833 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
834 (*env)->DeleteLocalRef(env, jbuf);
835 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
836 (*env)->DeleteLocalRef(env, jni_str_address);
838 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
839 return CA_STATUS_FAILED;
842 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
844 char responseData[MAX_PDU_BUFFER] = { 0 };
845 memcpy(responseData, (const char*) buf, length);
849 case CA_UNICAST_SERVER:
850 case CA_MULTICAST_SERVER:
851 // Notify data to upper layer
852 if (g_edrPacketReceivedCallback)
854 uint32_t sentLength = 0;
855 OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
856 %s, %d", responseData, length);
857 g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
862 // Should never occur
863 OIC_LOG(ERROR, TAG, "Invalid server type");
864 return CA_STATUS_FAILED;
866 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
867 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
869 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
870 (*env)->DeleteLocalRef(env, jbuf);
871 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
872 (*env)->DeleteLocalRef(env, jni_str_address);
876 (*env)->ExceptionDescribe(env);
877 (*env)->ExceptionClear(env);
878 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
879 return CA_STATUS_FAILED;
885 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
889 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
893 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
894 if (!jni_cid_BTsocket)
896 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
900 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
902 if (!jni_mid_isConnected)
904 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
906 OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
907 - jni_mid_isConnected is null.");
911 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
913 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
915 return jni_isConnected;
918 void CANativeStartListenTask(JNIEnv *env)
920 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
921 if (!jni_obj_BTServerSocket)
923 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
927 ca_mutex_lock(g_mutexServerSocket);
928 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
929 ca_mutex_unlock(g_mutexServerSocket);
932 jobject CAEDRNativeListen(JNIEnv *env)
934 if (!CAEDRNativeIsEnableBTAdapter(env))
936 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
940 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
942 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
943 if (!jni_cid_BTAdapter)
945 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
950 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
952 METHODID_OBJECTNONPARAM);
953 if (!jni_mid_getDefaultAdapter)
955 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_getDefaultAdapter is null");
959 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
960 jni_mid_getDefaultAdapter);
961 if (!jni_obj_BTAdapter)
963 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
967 // get listen method ID
968 jmethodID jni_mid_listen = (*env)->GetMethodID(
969 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
970 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
973 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
976 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
978 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
981 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
985 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
986 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
987 if (!jni_mid_fromString)
989 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
993 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
996 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
999 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1003 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
1008 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
1011 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
1014 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
1015 jni_name, jni_obj_uuid);
1016 if (!jni_obj_BTServerSocket)
1018 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1022 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1024 return jni_obj_BTServerSocket;
1027 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1029 if (NULL != serverSocketObject)
1031 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1032 env, "android/bluetooth/BluetoothServerSocket");
1033 if (!jni_cid_BTServerSocket)
1035 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1039 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1040 "()Landroid/bluetooth/BluetoothSocket;");
1041 if (!jni_mid_accept)
1043 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1047 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1049 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1051 if (!jni_obj_BTSocket)
1053 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1055 if ((*env)->ExceptionCheck(env))
1057 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1058 (*env)->ExceptionDescribe(env);
1059 (*env)->ExceptionClear(env);
1064 // get remote address
1065 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1068 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1072 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1073 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1075 // set socket to list
1076 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1077 ca_mutex_lock(g_mutexObjectList);
1078 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1079 ca_mutex_unlock(g_mutexObjectList);
1081 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1084 ca_mutex_lock(g_mutexStateList);
1085 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1086 ca_mutex_unlock(g_mutexStateList);
1087 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1091 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1096 * InputStream & BluetoothServerSocket will be close for Terminating.
1098 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1102 OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1104 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1105 env, "android/bluetooth/BluetoothServerSocket");
1106 if (!jni_cid_BTServerSocket)
1108 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1112 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1113 if (!jni_mid_accept)
1115 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1118 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1119 (*env)->DeleteGlobalRef(env, g_serverSocket);
1120 g_serverSocket = NULL;
1122 OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");