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 * Maximum CoAP over TCP header length
51 * to know the total data length.
53 #define EDR_MAX_HEADER_LEN 6
56 * server socket instance.
58 static jobject g_serverSocketObject = NULL;
61 * Mutex to synchronize unicast server.
63 static ca_mutex g_mutexUnicastServer = NULL;
66 * Flag to control the Receive Unicast Data Thread.
68 static bool g_stopUnicast = false;
71 * Mutex to synchronize secure multicast server.
73 static ca_mutex g_mutexMulticastServer = NULL;
76 * Flag to control the Receive Multicast Data Thread.
78 static bool g_stopMulticast = false;
81 * Mutex to synchronize accept server.
83 static ca_mutex g_mutexAcceptServer = NULL;
86 * Flag to control the Accept Thread.
88 static bool g_stopAccept = false;
91 * Mutex to synchronize server socket.
93 static ca_mutex g_mutexServerSocket = NULL;
95 static jobject g_serverSocket = NULL;
98 * Mutex to synchronize device state list.
100 static ca_mutex g_mutexStateList = NULL;
103 * Mutex to synchronize device object list.
105 static ca_mutex g_mutexObjectList = NULL;
108 * Thread context information for unicast, multicast and secured unicast server.
113 CAAdapterServerType_t type;
114 } CAAdapterReceiveThreadContext_t;
119 } CAAdapterAcceptThreadContext_t;
122 * Maintains the callback to be notified when data received from remote
125 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
127 static void CAReceiveHandler(void *data)
129 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
131 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
133 bool isAttached = false;
135 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
138 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
139 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
143 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
149 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
151 while (true != *(ctx->stopFlag))
153 if (!CAEDRNativeIsEnableBTAdapter(env))
155 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
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);
173 (*g_jvm)->DetachCurrentThread(g_jvm);
178 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
181 static void CAAcceptHandler(void *data)
183 OIC_LOG(DEBUG, TAG, "AcceptThread start");
185 VERIFY_NON_NULL_VOID(data, TAG, "CAAcceptHandler: data is null");
187 bool isAttached = false;
189 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
192 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
193 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
197 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
203 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
204 if (!jni_obj_BTServerSocket)
206 OIC_LOG(ERROR, TAG, "AcceptThread: jni_obj_BTServerSocket is null");
210 (*g_jvm)->DetachCurrentThread(g_jvm);
216 ca_mutex_lock(g_mutexServerSocket);
217 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
218 ca_mutex_unlock(g_mutexServerSocket);
220 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
222 // it should be initialized for restart accept thread
223 ca_mutex_lock(g_mutexAcceptServer);
224 g_stopAccept = false;
225 ca_mutex_unlock(g_mutexAcceptServer);
227 while (true != *(ctx->stopFlag))
229 OIC_LOG(DEBUG, TAG, "AcceptThread running");
231 // when BT state is changed with Off. its thread will be stopped
232 if (!CAEDRNativeIsEnableBTAdapter(env))
234 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
235 ca_mutex_lock(g_mutexAcceptServer);
237 ca_mutex_unlock(g_mutexAcceptServer);
238 ca_mutex_lock(g_mutexServerSocket);
239 g_serverSocket = NULL;
240 ca_mutex_unlock(g_mutexServerSocket);
244 CAEDRNativeAccept(env, g_serverSocket);
250 (*g_jvm)->DetachCurrentThread(g_jvm);
255 OIC_LOG(DEBUG, TAG, "AcceptThread finish");
261 * implement for adapter common method.
263 CAResult_t CAEDRServerStart()
265 if (!g_threadPoolHandle)
267 return CA_STATUS_NOT_INITIALIZED;
270 CAEDRServerStartAcceptThread();
271 CAResult_t res = CAEDRStartUnicastServer(false);
272 if (CA_STATUS_OK != res)
274 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
276 return CA_STATUS_FAILED;
282 CAResult_t CAEDRServerStop()
284 CAEDRStopUnicastServer();
285 CAEDRStopMulticastServer();
287 ca_mutex_lock(g_mutexAcceptServer);
289 ca_mutex_unlock(g_mutexAcceptServer);
293 OIC_LOG(DEBUG, TAG, "g_jvm is null");
294 return CA_STATUS_FAILED;
297 bool isAttached = false;
299 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
302 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
303 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
307 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
308 return CA_STATUS_FAILED;
313 CAEDRNatvieCloseServerTask(env);
317 (*g_jvm)->DetachCurrentThread(g_jvm);
323 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
325 g_edrPacketReceivedCallback = packetReceivedCallback;
328 static void CAEDRServerDestroyMutex()
330 if (g_mutexUnicastServer)
332 ca_mutex_free(g_mutexUnicastServer);
333 g_mutexUnicastServer = NULL;
336 if (g_mutexMulticastServer)
338 ca_mutex_free(g_mutexMulticastServer);
339 g_mutexMulticastServer = NULL;
342 if (g_mutexAcceptServer)
344 ca_mutex_free(g_mutexAcceptServer);
345 g_mutexAcceptServer = NULL;
348 if (g_mutexServerSocket)
350 ca_mutex_free(g_mutexServerSocket);
351 g_mutexServerSocket = NULL;
354 if (g_mutexStateList)
356 ca_mutex_free(g_mutexStateList);
357 g_mutexStateList = NULL;
360 if (g_mutexObjectList)
362 ca_mutex_free(g_mutexObjectList);
363 g_mutexObjectList = NULL;
367 static CAResult_t CAEDRServerCreateMutex()
369 g_mutexUnicastServer = ca_mutex_new();
370 if (!g_mutexUnicastServer)
372 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
373 return CA_STATUS_FAILED;
376 g_mutexMulticastServer = ca_mutex_new();
377 if (!g_mutexMulticastServer)
379 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
381 CAEDRServerDestroyMutex();
382 return CA_STATUS_FAILED;
385 g_mutexAcceptServer = ca_mutex_new();
386 if (!g_mutexAcceptServer)
388 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
390 CAEDRServerDestroyMutex();
391 return CA_STATUS_FAILED;
394 g_mutexServerSocket = ca_mutex_new();
395 if (!g_mutexServerSocket)
397 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
399 CAEDRServerDestroyMutex();
400 return CA_STATUS_FAILED;
403 g_mutexStateList = ca_mutex_new();
404 if (!g_mutexStateList)
406 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
408 CAEDRServerDestroyMutex();
409 return CA_STATUS_FAILED;
412 g_mutexObjectList = ca_mutex_new();
413 if (!g_mutexObjectList)
415 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
417 CAEDRServerDestroyMutex();
418 return CA_STATUS_FAILED;
424 void CAEDRServerJniInit()
426 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
427 g_jvm = CANativeJNIGetJavaVM();
430 CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle)
432 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
433 VERIFY_NON_NULL(handle, TAG, "handle is NULL");
434 g_threadPoolHandle = handle;
435 CAEDRServerJniInit();
438 CAResult_t result = CAEDRServerCreateMutex();
442 CAResult_t CAEDRServerStartAcceptThread()
444 bool isAttached = false;
446 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
449 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
450 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
454 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
455 return CA_STATUS_FAILED;
460 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
463 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
464 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
465 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
468 ca_mutex_lock(g_mutexStateList);
469 CAEDRNativeCreateDeviceStateList();
470 ca_mutex_unlock(g_mutexStateList);
472 ca_mutex_lock(g_mutexObjectList);
473 CAEDRNativeCreateDeviceSocketList();
474 ca_mutex_unlock(g_mutexObjectList);
478 (*g_jvm)->DetachCurrentThread(g_jvm);
481 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
482 sizeof(CAAdapterReceiveThreadContext_t));
485 OIC_LOG(ERROR, TAG, "Out of memory!");
486 return CA_MEMORY_ALLOC_FAILED;
489 ctx->stopFlag = &g_stopAccept;
490 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
492 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
493 OICFree((void *) ctx);
494 return CA_STATUS_FAILED;
500 void CAEDRServerTerminate()
502 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
508 bool isAttached = false;
510 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
513 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
514 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
518 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
524 CAEDRNativeSocketCloseToAll(env);
528 (*g_jvm)->DetachCurrentThread(g_jvm);
531 CAEDRNativeRemoveAllDeviceState();
532 CAEDRNativeRemoveAllDeviceSocket(env);
535 CAEDRServerDestroyMutex();
538 CAResult_t CAEDRStartUnicastServer(bool isSecured)
540 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
542 ca_mutex_lock(g_mutexUnicastServer);
545 * The task to listen for data from unicast is added to the thread pool.
546 * This is a blocking call is made where we try to receive some data..
547 * We will keep waiting until some data is received.
548 * This task will be terminated when thread pool is freed on stopping the adapters.
549 * Thread context will be freed by thread on exit.
551 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
552 sizeof(CAAdapterReceiveThreadContext_t));
555 OIC_LOG(ERROR, TAG, "Out of memory!");
556 ca_mutex_unlock(g_mutexUnicastServer);
557 return CA_MEMORY_ALLOC_FAILED;
560 ctx->stopFlag = &g_stopUnicast;
561 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
562 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
564 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
565 ca_mutex_unlock(g_mutexUnicastServer);
566 OICFree((void *) ctx);
567 return CA_STATUS_FAILED;
569 ca_mutex_unlock(g_mutexUnicastServer);
571 OIC_LOG(DEBUG, TAG, "OUT");
575 CAResult_t CAEDRStartMulticastServer()
577 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
579 ca_mutex_lock(g_mutexMulticastServer);
582 * The task to listen to data from multicast socket is added to the thread pool.
583 * This is a blocking call is made where we try to receive some data.
584 * We will keep waiting until some data is received.
585 * This task will be terminated when thread pool is freed on stopping the adapters.
586 * Thread context will be freed by thread on exit.
588 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
589 sizeof(CAAdapterReceiveThreadContext_t));
592 OIC_LOG(ERROR, TAG, "Out of memory!");
593 ca_mutex_unlock(g_mutexMulticastServer);
595 return CA_MEMORY_ALLOC_FAILED;
598 ctx->stopFlag = &g_stopMulticast;
599 ctx->type = CA_MULTICAST_SERVER;
601 g_stopMulticast = false;
602 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
604 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
606 g_stopMulticast = true;
607 ca_mutex_unlock(g_mutexMulticastServer);
608 OICFree((void *) ctx);
610 return CA_STATUS_FAILED;
612 ca_mutex_unlock(g_mutexMulticastServer);
614 OIC_LOG(DEBUG, TAG, "OUT");
618 CAResult_t CAEDRStopUnicastServer()
620 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
622 ca_mutex_lock(g_mutexUnicastServer);
623 g_stopUnicast = true;
624 ca_mutex_unlock(g_mutexUnicastServer);
629 CAResult_t CAEDRStopMulticastServer()
631 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
633 ca_mutex_lock(g_mutexMulticastServer);
634 g_stopMulticast = true;
635 ca_mutex_unlock(g_mutexMulticastServer);
637 OIC_LOG(INFO, TAG, "Multicast server stopped");
642 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id)
644 if ((*env)->ExceptionCheck(env))
646 (*env)->ExceptionDescribe(env);
647 (*env)->ExceptionClear(env);
648 OIC_LOG(ERROR, TAG, "env error!!");
649 return CA_STATUS_FAILED;
652 // check whether this socket object is connected or not.
653 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
656 return CA_STATUS_INVALID_PARAM;
659 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
660 if (!jni_str_address)
662 OIC_LOG(ERROR, TAG, "jni_str_address is null");
663 return CA_STATUS_FAILED;
665 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
667 // check it whether is still connected or not through google api
668 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
671 OIC_LOG(ERROR, TAG, "it is not connected yet.");
673 // remove socket to list
674 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
675 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
676 (*env)->DeleteLocalRef(env, jni_str_address);
678 return CA_STATUS_FAILED;
681 // start to read through InputStream
682 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
683 if (!jni_cid_BTsocket)
685 OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null");
686 (*env)->DeleteLocalRef(env, jni_str_address);
687 return CA_STATUS_FAILED;
689 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
691 "()Ljava/io/InputStream;");
693 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
694 jni_mid_getInputStream);
695 if (!jni_obj_inputStream)
697 OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
698 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
699 (*env)->DeleteLocalRef(env, jni_str_address);
700 return CA_STATUS_FAILED;
703 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
704 if (!jni_cid_InputStream)
706 OIC_LOG(ERROR, TAG, "jni_cid_InputStream is null");
710 jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream,
712 if (!jni_mid_available)
714 OIC_LOG(ERROR, TAG, "jni_mid_available is null");
718 jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
720 CAConnectedDeviceInfo_t *deviceInfo = NULL;
723 OIC_LOG_V(DEBUG, TAG, "get InputStream..%d, %s", id, address);
724 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream,
728 OIC_LOG(ERROR, TAG, "jni_mid_read is null");
732 deviceInfo = (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
735 OIC_LOG(ERROR, TAG, "failed to get device info from list");
739 jint bufSize = (deviceInfo->totalDataLen == 0) ?
740 EDR_MAX_HEADER_LEN : deviceInfo->totalDataLen;
741 if (!deviceInfo->recvData)
743 deviceInfo->recvData = OICCalloc(1, bufSize);
744 if (!deviceInfo->recvData)
746 OIC_LOG(ERROR, TAG, "out of memory");
751 jbyteArray jbuf = (*env)->NewByteArray(env, (jint) bufSize - deviceInfo->recvDataLen);
752 jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read,
754 (jint) bufSize - deviceInfo->recvDataLen);
757 (*env)->DeleteLocalRef(env, jbuf);
761 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
764 (*env)->DeleteLocalRef(env, jbuf);
767 memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen);
768 deviceInfo->recvDataLen += recvLen;
770 OIC_LOG(DEBUG, TAG, "read something from InputStream");
772 if (!deviceInfo->totalDataLen)
774 coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
775 ((unsigned char *) deviceInfo->recvData)[0] >> 4);
776 size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
777 if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen)
779 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
780 deviceInfo->recvDataLen);
781 OIC_LOG_V(DEBUG, TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
783 uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
786 OIC_LOG(ERROR, TAG, "out of memory");
787 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
788 (*env)->DeleteLocalRef(env, jbuf);
791 deviceInfo->recvData = newBuf;
795 if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
797 if ((*env)->ExceptionCheck(env))
799 OIC_LOG(ERROR, TAG, "read Error!!!");
800 (*env)->ExceptionDescribe(env);
801 (*env)->ExceptionClear(env);
803 // update state to disconnect
804 // the socket will be close next read thread routine
805 ca_mutex_lock(g_mutexStateList);
806 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
807 ca_mutex_unlock(g_mutexStateList);
809 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
810 (*env)->DeleteLocalRef(env, jbuf);
814 if (g_edrPacketReceivedCallback)
816 OIC_LOG_V(DEBUG, TAG,"data will be sent to callback routine: \
817 %s, %d", deviceInfo->recvData, deviceInfo->recvDataLen);
819 uint32_t sentLength = 0;
820 g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData,
821 deviceInfo->recvDataLen, &sentLength);
823 OICFree(deviceInfo->recvData);
824 deviceInfo->recvData = NULL;
825 deviceInfo->recvDataLen = 0;
826 deviceInfo->totalDataLen = 0;
829 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
830 (*env)->DeleteLocalRef(env, jbuf);
832 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
833 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
834 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
835 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
836 (*env)->DeleteLocalRef(env, jni_str_address);
841 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
842 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
843 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
844 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
845 (*env)->DeleteLocalRef(env, jni_str_address);
847 return CA_STATUS_FAILED;
850 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
854 OIC_LOG(ERROR, TAG, "socket is null");
858 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
859 if (!jni_cid_BTsocket)
861 OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null");
865 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
867 if (!jni_mid_isConnected)
869 OIC_LOG(ERROR, TAG, "jni_mid_isConnected is null.");
870 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
874 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
876 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
878 return jni_isConnected;
881 void CANativeStartListenTask(JNIEnv *env)
883 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
884 if (!jni_obj_BTServerSocket)
886 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
890 ca_mutex_lock(g_mutexServerSocket);
891 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
892 ca_mutex_unlock(g_mutexServerSocket);
895 jobject CAEDRNativeListen(JNIEnv *env)
897 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - IN");
899 if (!CAEDRNativeIsEnableBTAdapter(env))
901 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
905 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
906 if (!jni_cid_BTAdapter)
908 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
913 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
915 METHODID_OBJECTNONPARAM);
916 if (!jni_mid_getDefaultAdapter)
918 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
922 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
923 jni_mid_getDefaultAdapter);
924 if (!jni_obj_BTAdapter)
926 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
930 // get listen method ID
931 jmethodID jni_mid_listen = (*env)->GetMethodID(
932 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
933 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
936 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
939 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
941 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
944 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
948 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
949 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
950 if (!jni_mid_fromString)
952 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
956 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
959 OIC_LOG(ERROR, TAG, "jni_uuid is null");
962 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
966 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
971 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
974 OIC_LOG(ERROR, TAG, "jni_name is null");
977 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
978 jni_name, jni_obj_uuid);
979 if (!jni_obj_BTServerSocket)
981 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
985 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
987 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT");
989 return jni_obj_BTServerSocket;
992 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
994 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - IN");
996 if (NULL != serverSocketObject)
998 jclass jni_cid_BTServerSocket = (*env)->FindClass(
999 env, "android/bluetooth/BluetoothServerSocket");
1000 if (!jni_cid_BTServerSocket)
1002 OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null");
1006 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1007 "()Landroid/bluetooth/BluetoothSocket;");
1008 if (!jni_mid_accept)
1010 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
1014 OIC_LOG(DEBUG, TAG, "initiating accept...");
1016 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1018 if (!jni_obj_BTSocket)
1020 OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null");
1022 if ((*env)->ExceptionCheck(env))
1024 OIC_LOG(ERROR, TAG, "socket might closed or timeout!!!");
1025 (*env)->ExceptionDescribe(env);
1026 (*env)->ExceptionClear(env);
1031 // get remote address
1032 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1035 OIC_LOG(ERROR, TAG, "j_str_address is null");
1039 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1040 OIC_LOG_V(DEBUG, TAG, "address is %s", address);
1042 // set socket to list
1043 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1044 ca_mutex_lock(g_mutexObjectList);
1045 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1046 ca_mutex_unlock(g_mutexObjectList);
1048 OIC_LOG(DEBUG, TAG, "Accepted!!");
1051 ca_mutex_lock(g_mutexStateList);
1052 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1053 ca_mutex_unlock(g_mutexStateList);
1055 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1056 (*env)->DeleteLocalRef(env, j_str_address);
1060 OIC_LOG(DEBUG, TAG, "serverSocket is close previously");
1063 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - OUT");
1067 * InputStream & BluetoothServerSocket will be close for Terminating.
1069 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1073 OIC_LOG(DEBUG, TAG, "Accept Resource will be close");
1075 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1076 env, "android/bluetooth/BluetoothServerSocket");
1077 if (!jni_cid_BTServerSocket)
1079 OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null");
1083 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1084 if (!jni_mid_accept)
1086 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
1089 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1090 (*env)->DeleteGlobalRef(env, g_serverSocket);
1091 g_serverSocket = NULL;
1093 OIC_LOG(DEBUG, TAG, "close accept obj");