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"
37 #define TAG PCF("OIC_CA_EDR_SERVER")
39 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
40 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
41 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
42 static const char CLASSPATH_BT_SERVER_SOCKET[] = "android/bluetooth/BluetoothServerSocket";
43 static const char CLASSPATH_BT_SOCKET[] = "android/bluetooth/BluetoothSocket";
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 receive server.
63 static ca_mutex g_mutexReceiveServer = NULL;
66 * Flag to control the Receive Unicast Data Thread.
68 static bool g_stopUnicast = false;
71 * Mutex to synchronize accept server.
73 static ca_mutex g_mutexAcceptServer = NULL;
76 * Flag to control the Accept Thread.
78 static bool g_stopAccept = false;
81 * Mutex to synchronize server socket.
83 static ca_mutex g_mutexServerSocket = NULL;
86 * Flag to control the server socket.
88 static jobject g_serverSocket = NULL;
91 * Mutex to synchronize device state list.
93 static ca_mutex g_mutexStateList = NULL;
96 * Mutex to synchronize device object list.
98 static ca_mutex g_mutexObjectList = NULL;
101 * Thread context information for unicast, multicast and secured unicast server.
106 CAAdapterServerType_t type;
107 } CAAdapterReceiveThreadContext_t;
112 } CAAdapterAcceptThreadContext_t;
115 * Maintains the callback to be notified when data received from remote
118 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
120 static void CAReceiveHandler(void *data)
122 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
124 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
126 bool isAttached = false;
128 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
131 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
132 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
136 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
142 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
144 while (true != *(ctx->stopFlag))
146 if (!CAEDRNativeIsEnableBTAdapter(env))
148 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
152 // if new socket object is added in socket list after below logic is ran.
153 // new socket will be started to read after next while loop
154 uint32_t length = CAEDRGetSocketListLength();
157 for (uint32_t idx = 0; idx < length; idx++)
159 CAEDRNativeReadData(env, idx);
166 (*g_jvm)->DetachCurrentThread(g_jvm);
171 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
174 static void CAAcceptHandler(void *data)
176 OIC_LOG(DEBUG, TAG, "AcceptThread start");
178 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
180 bool isAttached = false;
182 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
185 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
186 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
190 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
196 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
197 if (!jni_obj_BTServerSocket)
199 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
203 (*g_jvm)->DetachCurrentThread(g_jvm);
209 ca_mutex_lock(g_mutexServerSocket);
210 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
211 ca_mutex_unlock(g_mutexServerSocket);
213 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
215 // it should be initialized for restart accept thread
216 ca_mutex_lock(g_mutexAcceptServer);
217 g_stopAccept = false;
218 ca_mutex_unlock(g_mutexAcceptServer);
220 while (true != *(ctx->stopFlag))
222 // when BT state is changed with Off. its thread will be stopped
223 if (!CAEDRNativeIsEnableBTAdapter(env))
225 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
226 ca_mutex_lock(g_mutexAcceptServer);
228 ca_mutex_unlock(g_mutexAcceptServer);
229 ca_mutex_lock(g_mutexServerSocket);
230 g_serverSocket = NULL;
231 ca_mutex_unlock(g_mutexServerSocket);
235 CAEDRNativeAccept(env, g_serverSocket);
241 (*g_jvm)->DetachCurrentThread(g_jvm);
246 OIC_LOG(DEBUG, TAG, "AcceptThread finish");
252 * implement for adapter common method.
254 CAResult_t CAEDRServerStart()
256 if (!g_threadPoolHandle)
258 return CA_STATUS_NOT_INITIALIZED;
261 CAResult_t res = CAEDRServerStartAcceptThread();
262 if (CA_STATUS_OK == res)
264 res = CAEDRStartReceiveThread(false);
265 if (CA_STATUS_OK != res)
267 OIC_LOG(ERROR, TAG, "failed to start receive thread");
269 return CA_STATUS_FAILED;
276 CAResult_t CAEDRServerStop()
278 CAEDRStopReceiveThread();
280 ca_mutex_lock(g_mutexAcceptServer);
282 ca_mutex_unlock(g_mutexAcceptServer);
286 OIC_LOG(DEBUG, TAG, "g_jvm is null");
287 return CA_STATUS_FAILED;
290 bool isAttached = false;
292 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
295 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
296 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
300 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
301 return CA_STATUS_FAILED;
306 CAEDRNatvieCloseServerTask(env);
310 (*g_jvm)->DetachCurrentThread(g_jvm);
316 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
318 g_edrPacketReceivedCallback = packetReceivedCallback;
321 static void CAEDRServerDestroyMutex()
323 if (g_mutexReceiveServer)
325 ca_mutex_free(g_mutexReceiveServer);
326 g_mutexReceiveServer = NULL;
329 if (g_mutexAcceptServer)
331 ca_mutex_free(g_mutexAcceptServer);
332 g_mutexAcceptServer = NULL;
335 if (g_mutexServerSocket)
337 ca_mutex_free(g_mutexServerSocket);
338 g_mutexServerSocket = NULL;
341 if (g_mutexStateList)
343 ca_mutex_free(g_mutexStateList);
344 g_mutexStateList = NULL;
347 if (g_mutexObjectList)
349 ca_mutex_free(g_mutexObjectList);
350 g_mutexObjectList = NULL;
354 static CAResult_t CAEDRServerCreateMutex()
356 g_mutexReceiveServer = ca_mutex_new();
357 if (!g_mutexReceiveServer)
359 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
360 return CA_STATUS_FAILED;
363 g_mutexAcceptServer = ca_mutex_new();
364 if (!g_mutexAcceptServer)
366 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
368 CAEDRServerDestroyMutex();
369 return CA_STATUS_FAILED;
372 g_mutexServerSocket = ca_mutex_new();
373 if (!g_mutexServerSocket)
375 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
377 CAEDRServerDestroyMutex();
378 return CA_STATUS_FAILED;
381 g_mutexStateList = ca_mutex_new();
382 if (!g_mutexStateList)
384 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
386 CAEDRServerDestroyMutex();
387 return CA_STATUS_FAILED;
390 g_mutexObjectList = ca_mutex_new();
391 if (!g_mutexObjectList)
393 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
395 CAEDRServerDestroyMutex();
396 return CA_STATUS_FAILED;
402 void CAEDRServerJniInit()
404 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
405 g_jvm = CANativeJNIGetJavaVM();
408 CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle)
410 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
411 VERIFY_NON_NULL(handle, TAG, "handle is NULL");
413 g_threadPoolHandle = handle;
414 CAEDRServerJniInit();
416 return CAEDRServerCreateMutex();
419 CAResult_t CAEDRServerStartAcceptThread()
421 bool isAttached = false;
423 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
426 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
427 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
431 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
432 return CA_STATUS_FAILED;
437 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
440 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
441 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
442 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
445 ca_mutex_lock(g_mutexStateList);
446 CAEDRNativeCreateDeviceStateList();
447 ca_mutex_unlock(g_mutexStateList);
449 ca_mutex_lock(g_mutexObjectList);
450 CAEDRNativeCreateDeviceSocketList();
451 ca_mutex_unlock(g_mutexObjectList);
455 (*g_jvm)->DetachCurrentThread(g_jvm);
458 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
459 sizeof(CAAdapterReceiveThreadContext_t));
462 OIC_LOG(ERROR, TAG, "Out of memory!");
463 return CA_MEMORY_ALLOC_FAILED;
466 ctx->stopFlag = &g_stopAccept;
467 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
469 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
470 OICFree((void *) ctx);
471 return CA_STATUS_FAILED;
477 void CAEDRServerTerminate()
479 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
485 bool isAttached = false;
487 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
490 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
491 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
495 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
501 CAEDRNativeSocketCloseToAll(env);
505 (*g_jvm)->DetachCurrentThread(g_jvm);
508 CAEDRNativeRemoveAllDeviceState();
509 CAEDRNativeRemoveAllDeviceSocket(env);
512 CAEDRServerDestroyMutex();
515 CAResult_t CAEDRStartReceiveThread(bool isSecured)
517 OIC_LOG(DEBUG, TAG, "CAEDRStartReceiveThread");
519 ca_mutex_lock(g_mutexReceiveServer);
522 * The task to listen for data from unicast is added to the thread pool.
523 * This is a blocking call is made where we try to receive some data..
524 * We will keep waiting until some data is received.
525 * This task will be terminated when thread pool is freed on stopping the adapters.
526 * Thread context will be freed by thread on exit.
528 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
529 sizeof(CAAdapterReceiveThreadContext_t));
532 OIC_LOG(ERROR, TAG, "Out of memory!");
533 ca_mutex_unlock(g_mutexReceiveServer);
534 return CA_MEMORY_ALLOC_FAILED;
537 g_stopUnicast = false;
538 ctx->stopFlag = &g_stopUnicast;
539 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
540 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
542 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
543 ca_mutex_unlock(g_mutexReceiveServer);
544 OICFree((void *) ctx);
545 return CA_STATUS_FAILED;
547 ca_mutex_unlock(g_mutexReceiveServer);
549 OIC_LOG(DEBUG, TAG, "OUT");
553 CAResult_t CAEDRStopReceiveThread()
555 OIC_LOG(DEBUG, TAG, "CAEDRStopReceiveThread");
557 ca_mutex_lock(g_mutexReceiveServer);
558 g_stopUnicast = true;
559 ca_mutex_unlock(g_mutexReceiveServer);
564 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id)
566 if ((*env)->ExceptionCheck(env))
568 (*env)->ExceptionDescribe(env);
569 (*env)->ExceptionClear(env);
570 OIC_LOG(ERROR, TAG, "env error!!");
571 return CA_STATUS_FAILED;
574 // check whether this socket object is connected or not.
575 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
578 return CA_STATUS_INVALID_PARAM;
581 // start to read through InputStream
582 jmethodID jni_mid_getInputStream = CAGetJNIMethodID(env,
585 "()Ljava/io/InputStream;");
587 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
588 jni_mid_getInputStream);
589 if (!jni_obj_inputStream)
591 OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
592 return CA_STATUS_FAILED;
595 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
596 if (!jni_cid_InputStream)
598 OIC_LOG(ERROR, TAG, "jni_cid_InputStream is null");
599 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
600 return CA_STATUS_FAILED;
603 jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream,
605 if (!jni_mid_available)
607 OIC_LOG(ERROR, TAG, "jni_mid_available is null");
611 jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
613 CAConnectedDeviceInfo_t *deviceInfo = NULL;
616 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
617 if (!jni_str_address)
619 OIC_LOG(ERROR, TAG, "jni_str_address is null");
623 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
626 OIC_LOG(ERROR, TAG, "address is null");
627 (*env)->DeleteLocalRef(env, jni_str_address);
631 OIC_LOG_V(DEBUG, TAG, "get InputStream..%d, %s", id, address);
632 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream,
636 OIC_LOG(ERROR, TAG, "jni_mid_read is null");
637 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
638 (*env)->DeleteLocalRef(env, jni_str_address);
642 deviceInfo = (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
645 OIC_LOG(ERROR, TAG, "failed to get device info from list");
646 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
647 (*env)->DeleteLocalRef(env, jni_str_address);
651 jint bufSize = (deviceInfo->totalDataLen == 0) ?
652 EDR_MAX_HEADER_LEN : deviceInfo->totalDataLen;
653 if (!deviceInfo->recvData)
655 deviceInfo->recvData = OICCalloc(1, bufSize);
656 if (!deviceInfo->recvData)
658 OIC_LOG(ERROR, TAG, "out of memory");
659 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
660 (*env)->DeleteLocalRef(env, jni_str_address);
665 jbyteArray jbuf = (*env)->NewByteArray(env, (jint) bufSize - deviceInfo->recvDataLen);
668 OIC_LOG(ERROR, TAG, "jbuf is null");
669 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
670 (*env)->DeleteLocalRef(env, jni_str_address);
674 jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read,
676 (jint) bufSize - deviceInfo->recvDataLen);
679 OIC_LOG(ERROR, TAG, "recvLen is -1");
680 (*env)->DeleteLocalRef(env, jbuf);
681 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
682 (*env)->DeleteLocalRef(env, jni_str_address);
686 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
689 OIC_LOG(ERROR, TAG, "buf is null");
690 (*env)->DeleteLocalRef(env, jbuf);
691 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
692 (*env)->DeleteLocalRef(env, jni_str_address);
695 memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen);
696 deviceInfo->recvDataLen += recvLen;
698 OIC_LOG(DEBUG, TAG, "read something from InputStream");
700 if (!deviceInfo->totalDataLen)
702 coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
703 ((unsigned char *) deviceInfo->recvData)[0] >> 4);
704 size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
705 if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen)
707 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
708 deviceInfo->recvDataLen);
709 OIC_LOG_V(DEBUG, TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
711 uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
714 OIC_LOG(ERROR, TAG, "out of memory");
715 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
716 (*env)->DeleteLocalRef(env, jbuf);
717 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
718 (*env)->DeleteLocalRef(env, jni_str_address);
721 deviceInfo->recvData = newBuf;
725 if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
727 if ((*env)->ExceptionCheck(env))
729 OIC_LOG(ERROR, TAG, "read Error!!!");
730 (*env)->ExceptionDescribe(env);
731 (*env)->ExceptionClear(env);
733 // update state to disconnect
734 // the socket will be close next read thread routine
735 ca_mutex_lock(g_mutexStateList);
736 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
737 ca_mutex_unlock(g_mutexStateList);
739 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
740 (*env)->DeleteLocalRef(env, jbuf);
741 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
742 (*env)->DeleteLocalRef(env, jni_str_address);
746 if (g_edrPacketReceivedCallback)
748 OIC_LOG_V(DEBUG, TAG,"data will be sent to callback routine: \
749 %s, %d", deviceInfo->recvData, deviceInfo->recvDataLen);
751 uint32_t sentLength = 0;
752 g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData,
753 deviceInfo->recvDataLen, &sentLength);
755 OICFree(deviceInfo->recvData);
756 deviceInfo->recvData = NULL;
757 deviceInfo->recvDataLen = 0;
758 deviceInfo->totalDataLen = 0;
761 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
762 (*env)->DeleteLocalRef(env, jbuf);
763 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
764 (*env)->DeleteLocalRef(env, jni_str_address);
766 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
767 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
772 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
773 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
775 return CA_STATUS_FAILED;
778 void CANativeStartListenTask(JNIEnv *env)
780 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
781 if (!jni_obj_BTServerSocket)
783 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
787 ca_mutex_lock(g_mutexServerSocket);
788 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
789 ca_mutex_unlock(g_mutexServerSocket);
792 jobject CAEDRNativeListen(JNIEnv *env)
794 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - IN");
796 if (!CAEDRNativeIsEnableBTAdapter(env))
798 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
802 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
803 if (!jni_cid_BTAdapter)
805 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
810 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
812 METHODID_OBJECTNONPARAM);
813 if (!jni_mid_getDefaultAdapter)
815 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
819 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
820 jni_mid_getDefaultAdapter);
821 if (!jni_obj_BTAdapter)
823 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
827 // get listen method ID
828 jmethodID jni_mid_listen = (*env)->GetMethodID(
829 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
830 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
833 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
836 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
838 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
841 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
845 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
846 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
847 if (!jni_mid_fromString)
849 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
853 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
856 OIC_LOG(ERROR, TAG, "jni_uuid is null");
859 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
863 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
868 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
871 OIC_LOG(ERROR, TAG, "jni_name is null");
874 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
875 jni_name, jni_obj_uuid);
876 if (!jni_obj_BTServerSocket)
878 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
882 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
884 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT");
886 return jni_obj_BTServerSocket;
889 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
891 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - IN");
893 if (NULL != serverSocketObject)
895 jmethodID jni_mid_accept = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
897 "()Landroid/bluetooth/BluetoothSocket;");
900 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
904 OIC_LOG(DEBUG, TAG, "waiting for the new connection request...");
906 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
908 if (!jni_obj_BTSocket)
910 OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null");
912 if ((*env)->ExceptionCheck(env))
914 OIC_LOG(ERROR, TAG, "socket might closed or timeout!!!");
915 (*env)->ExceptionDescribe(env);
916 (*env)->ExceptionClear(env);
921 // get remote address
922 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
925 OIC_LOG(ERROR, TAG, "j_str_address is null");
929 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
930 OIC_LOG_V(DEBUG, TAG, "received the connection request from [%s]", address);
932 // set socket to list
933 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
934 ca_mutex_lock(g_mutexObjectList);
935 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
936 ca_mutex_unlock(g_mutexObjectList);
939 ca_mutex_lock(g_mutexStateList);
940 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
941 ca_mutex_unlock(g_mutexStateList);
943 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
944 (*env)->DeleteLocalRef(env, j_str_address);
946 OIC_LOG_V(DEBUG, TAG, "connected with [%s]", address);
950 OIC_LOG(DEBUG, TAG, "serverSocket is close previously");
953 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - OUT");
957 * InputStream & BluetoothServerSocket will be close for Terminating.
959 void CAEDRNatvieCloseServerTask(JNIEnv* env)
963 OIC_LOG(DEBUG, TAG, "Accept Resource will be close");
965 jmethodID jni_mid_close = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
969 OIC_LOG(ERROR, TAG, "jni_mid_close is null");
973 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_close);
974 (*env)->DeleteGlobalRef(env, g_serverSocket);
975 g_serverSocket = NULL;
977 OIC_LOG(DEBUG, TAG, "close accept obj");