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";
44 static ca_thread_pool_t g_threadPoolHandle = NULL;
49 * Maximum CoAP over TCP header length
50 * to know the total data length.
52 #define EDR_MAX_HEADER_LEN 6
55 * Mutex to synchronize receive server.
57 static ca_mutex g_mutexReceiveServer = NULL;
60 * Flag to control the Receive Unicast Data Thread.
62 static bool g_stopUnicast = false;
65 * Mutex to synchronize accept server.
67 static ca_mutex g_mutexAcceptServer = NULL;
70 * Flag to control the Accept Thread.
72 static bool g_stopAccept = false;
75 * Mutex to synchronize server socket.
77 static ca_mutex g_mutexServerSocket = NULL;
80 * Flag to control the server socket.
82 static jobject g_serverSocket = NULL;
85 * Mutex to synchronize device state list.
87 static ca_mutex g_mutexStateList = NULL;
90 * Mutex to synchronize device object list.
92 static ca_mutex g_mutexObjectList = NULL;
95 * Thread context information for unicast, multicast and secured unicast server.
100 CAAdapterServerType_t type;
101 } CAAdapterReceiveThreadContext_t;
106 } CAAdapterAcceptThreadContext_t;
109 * Maintains the callback to be notified when data received from remote
112 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
114 static void CAReceiveHandler(void *data)
116 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
118 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
120 bool isAttached = false;
122 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
125 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
126 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
130 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
136 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
138 while (true != *(ctx->stopFlag))
140 if (!CAEDRNativeIsEnableBTAdapter(env))
142 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
146 // if new socket object is added in socket list after below logic is ran.
147 // new socket will be started to read after next while loop
148 uint32_t length = CAEDRGetSocketListLength();
151 for (uint32_t idx = 0; idx < length; idx++)
153 CAEDRNativeReadData(env, idx);
160 (*g_jvm)->DetachCurrentThread(g_jvm);
165 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
168 static void CAAcceptHandler(void *data)
170 OIC_LOG(DEBUG, TAG, "AcceptThread start");
172 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
174 bool isAttached = false;
176 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
179 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
180 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
184 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
190 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
191 if (!jni_obj_BTServerSocket)
193 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
197 (*g_jvm)->DetachCurrentThread(g_jvm);
203 ca_mutex_lock(g_mutexServerSocket);
204 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
205 ca_mutex_unlock(g_mutexServerSocket);
207 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
209 // it should be initialized for restart accept thread
210 ca_mutex_lock(g_mutexAcceptServer);
211 g_stopAccept = false;
212 ca_mutex_unlock(g_mutexAcceptServer);
214 while (true != *(ctx->stopFlag))
216 // when BT state is changed with Off. its thread will be stopped
217 if (!CAEDRNativeIsEnableBTAdapter(env))
219 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
220 ca_mutex_lock(g_mutexAcceptServer);
222 ca_mutex_unlock(g_mutexAcceptServer);
223 ca_mutex_lock(g_mutexServerSocket);
224 g_serverSocket = NULL;
225 ca_mutex_unlock(g_mutexServerSocket);
229 CAEDRNativeAccept(env, g_serverSocket);
235 (*g_jvm)->DetachCurrentThread(g_jvm);
240 OIC_LOG(DEBUG, TAG, "AcceptThread finish");
246 * implement for adapter common method.
248 CAResult_t CAEDRServerStart()
250 if (!g_threadPoolHandle)
252 return CA_STATUS_NOT_INITIALIZED;
255 CAResult_t res = CAEDRServerStartAcceptThread();
256 if (CA_STATUS_OK == res)
258 res = CAEDRStartReceiveThread(false);
259 if (CA_STATUS_OK != res)
261 OIC_LOG(ERROR, TAG, "failed to start receive thread");
263 return CA_STATUS_FAILED;
270 CAResult_t CAEDRServerStop()
272 CAEDRStopReceiveThread();
274 ca_mutex_lock(g_mutexAcceptServer);
276 ca_mutex_unlock(g_mutexAcceptServer);
280 OIC_LOG(DEBUG, TAG, "g_jvm is null");
281 return CA_STATUS_FAILED;
284 bool isAttached = false;
286 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
289 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
290 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
294 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
295 return CA_STATUS_FAILED;
300 CAEDRNatvieCloseServerTask(env);
304 (*g_jvm)->DetachCurrentThread(g_jvm);
310 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
312 g_edrPacketReceivedCallback = packetReceivedCallback;
315 static void CAEDRServerDestroyMutex()
317 if (g_mutexReceiveServer)
319 ca_mutex_free(g_mutexReceiveServer);
320 g_mutexReceiveServer = NULL;
323 if (g_mutexAcceptServer)
325 ca_mutex_free(g_mutexAcceptServer);
326 g_mutexAcceptServer = NULL;
329 if (g_mutexServerSocket)
331 ca_mutex_free(g_mutexServerSocket);
332 g_mutexServerSocket = NULL;
335 if (g_mutexStateList)
337 ca_mutex_free(g_mutexStateList);
338 g_mutexStateList = NULL;
341 if (g_mutexObjectList)
343 ca_mutex_free(g_mutexObjectList);
344 g_mutexObjectList = NULL;
348 static CAResult_t CAEDRServerCreateMutex()
350 g_mutexReceiveServer = ca_mutex_new();
351 if (!g_mutexReceiveServer)
353 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
354 return CA_STATUS_FAILED;
357 g_mutexAcceptServer = ca_mutex_new();
358 if (!g_mutexAcceptServer)
360 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
362 CAEDRServerDestroyMutex();
363 return CA_STATUS_FAILED;
366 g_mutexServerSocket = ca_mutex_new();
367 if (!g_mutexServerSocket)
369 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
371 CAEDRServerDestroyMutex();
372 return CA_STATUS_FAILED;
375 g_mutexStateList = ca_mutex_new();
376 if (!g_mutexStateList)
378 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
380 CAEDRServerDestroyMutex();
381 return CA_STATUS_FAILED;
384 g_mutexObjectList = ca_mutex_new();
385 if (!g_mutexObjectList)
387 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
389 CAEDRServerDestroyMutex();
390 return CA_STATUS_FAILED;
396 void CAEDRServerJniInit()
398 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
399 g_jvm = CANativeJNIGetJavaVM();
402 CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle)
404 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
405 VERIFY_NON_NULL(handle, TAG, "handle is NULL");
407 g_threadPoolHandle = handle;
408 CAEDRServerJniInit();
410 return CAEDRServerCreateMutex();
413 CAResult_t CAEDRServerStartAcceptThread()
415 bool isAttached = false;
417 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
420 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
421 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
425 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
426 return CA_STATUS_FAILED;
431 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
434 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
435 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
436 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
439 ca_mutex_lock(g_mutexStateList);
440 CAEDRNativeCreateDeviceStateList();
441 ca_mutex_unlock(g_mutexStateList);
443 ca_mutex_lock(g_mutexObjectList);
444 CAEDRNativeCreateDeviceSocketList();
445 ca_mutex_unlock(g_mutexObjectList);
449 (*g_jvm)->DetachCurrentThread(g_jvm);
452 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
453 sizeof(CAAdapterReceiveThreadContext_t));
456 OIC_LOG(ERROR, TAG, "Out of memory!");
457 return CA_MEMORY_ALLOC_FAILED;
460 ctx->stopFlag = &g_stopAccept;
461 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
463 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
464 OICFree((void *) ctx);
465 return CA_STATUS_FAILED;
471 void CAEDRServerTerminate()
473 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
479 bool isAttached = false;
481 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
484 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
485 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
489 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
495 CAEDRNativeSocketCloseToAll(env);
499 (*g_jvm)->DetachCurrentThread(g_jvm);
502 CAEDRNativeRemoveAllDeviceState();
503 CAEDRNativeRemoveAllDeviceSocket(env);
506 CAEDRServerDestroyMutex();
509 CAResult_t CAEDRStartReceiveThread(bool isSecured)
511 OIC_LOG(DEBUG, TAG, "CAEDRStartReceiveThread");
513 ca_mutex_lock(g_mutexReceiveServer);
516 * The task to listen for data from unicast is added to the thread pool.
517 * This is a blocking call is made where we try to receive some data..
518 * We will keep waiting until some data is received.
519 * This task will be terminated when thread pool is freed on stopping the adapters.
520 * Thread context will be freed by thread on exit.
522 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
523 sizeof(CAAdapterReceiveThreadContext_t));
526 OIC_LOG(ERROR, TAG, "Out of memory!");
527 ca_mutex_unlock(g_mutexReceiveServer);
528 return CA_MEMORY_ALLOC_FAILED;
531 g_stopUnicast = false;
532 ctx->stopFlag = &g_stopUnicast;
533 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
534 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
536 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
537 ca_mutex_unlock(g_mutexReceiveServer);
538 OICFree((void *) ctx);
539 return CA_STATUS_FAILED;
541 ca_mutex_unlock(g_mutexReceiveServer);
543 OIC_LOG(DEBUG, TAG, "OUT");
547 CAResult_t CAEDRStopReceiveThread()
549 OIC_LOG(DEBUG, TAG, "CAEDRStopReceiveThread");
551 ca_mutex_lock(g_mutexReceiveServer);
552 g_stopUnicast = true;
553 ca_mutex_unlock(g_mutexReceiveServer);
558 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t idx)
560 if ((*env)->ExceptionCheck(env))
562 (*env)->ExceptionDescribe(env);
563 (*env)->ExceptionClear(env);
564 OIC_LOG(ERROR, TAG, "env error!!");
565 return CA_STATUS_FAILED;
568 jobject jni_obj_inputStream = CAEDRNativeGetInputStream(idx);
569 if (!jni_obj_inputStream)
571 OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
572 return CA_STATUS_FAILED;
575 jmethodID jni_mid_available = CAGetJNIMethodID(env, "java/io/InputStream", "available", "()I");
576 if (!jni_mid_available)
578 OIC_LOG(ERROR, TAG, "jni_mid_available is null");
579 return CA_STATUS_FAILED;
582 jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
586 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(idx);
589 OIC_LOG(ERROR, TAG, "jni_obj_socket is null");
590 return CA_STATUS_FAILED;
593 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
594 if (!jni_str_address)
596 OIC_LOG(ERROR, TAG, "jni_str_address is null");
597 return CA_STATUS_FAILED;
600 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
603 OIC_LOG(ERROR, TAG, "address is null");
604 (*env)->DeleteLocalRef(env, jni_str_address);
605 return CA_STATUS_FAILED;
608 CAConnectedDeviceInfo_t *deviceInfo =
609 (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
612 OIC_LOG(ERROR, TAG, "failed to get device info from list");
613 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
614 (*env)->DeleteLocalRef(env, jni_str_address);
615 return CA_STATUS_FAILED;
618 jint bufSize = (deviceInfo->totalDataLen == 0) ? EDR_MAX_HEADER_LEN
619 : deviceInfo->totalDataLen;
620 if (!deviceInfo->recvData)
622 deviceInfo->recvData = OICCalloc(1, bufSize);
623 if (!deviceInfo->recvData)
625 OIC_LOG(ERROR, TAG, "out of memory");
626 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
627 (*env)->DeleteLocalRef(env, jni_str_address);
628 return CA_STATUS_FAILED;
632 jint remainSize = (jint) bufSize - deviceInfo->recvDataLen;
635 OIC_LOG(ERROR, TAG, "remainSize value is invalid.");
636 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
637 (*env)->DeleteLocalRef(env, jni_str_address);
638 return CA_STATUS_FAILED;
641 jbyteArray jbuf = (*env)->NewByteArray(env, remainSize);
644 OIC_LOG(ERROR, TAG, "jbuf is null");
645 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
646 (*env)->DeleteLocalRef(env, jni_str_address);
647 return CA_STATUS_FAILED;
650 jmethodID jni_mid_read = CAGetJNIMethodID(env, "java/io/InputStream", "read", "([BII)I");
653 OIC_LOG(ERROR, TAG, "jni_mid_read is null");
654 (*env)->DeleteLocalRef(env, jbuf);
655 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
656 (*env)->DeleteLocalRef(env, jni_str_address);
657 return CA_STATUS_FAILED;
660 OIC_LOG_V(DEBUG, TAG, "read InputStream (idx:%d, addr:%s)", idx, address);
661 jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read,
662 jbuf, (jint) 0, remainSize);
665 OIC_LOG(ERROR, TAG, "recvLen is -1");
666 (*env)->DeleteLocalRef(env, jbuf);
667 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
668 (*env)->DeleteLocalRef(env, jni_str_address);
669 return CA_STATUS_FAILED;
671 OIC_LOG_V(DEBUG, TAG, "read success (length: %d bytes)", recvLen);
673 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
676 OIC_LOG(ERROR, TAG, "buf is null");
677 (*env)->DeleteLocalRef(env, jbuf);
678 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
679 (*env)->DeleteLocalRef(env, jni_str_address);
680 return CA_STATUS_FAILED;
682 memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen);
683 deviceInfo->recvDataLen += recvLen;
685 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
686 (*env)->DeleteLocalRef(env, jbuf);
688 if (!deviceInfo->totalDataLen)
690 coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
691 ((unsigned char *) deviceInfo->recvData)[0] >> 4);
692 size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
693 if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen)
695 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
696 deviceInfo->recvDataLen);
697 OIC_LOG_V(DEBUG, TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
699 uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
702 OIC_LOG(ERROR, TAG, "out of memory");
703 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
704 (*env)->DeleteLocalRef(env, jni_str_address);
705 return CA_STATUS_FAILED;
707 deviceInfo->recvData = newBuf;
711 if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
713 if ((*env)->ExceptionCheck(env))
715 OIC_LOG(ERROR, TAG, "read Error!!!");
716 (*env)->ExceptionDescribe(env);
717 (*env)->ExceptionClear(env);
719 // update state to disconnect
720 // the socket will be close next read thread routine
721 ca_mutex_lock(g_mutexStateList);
722 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
723 ca_mutex_unlock(g_mutexStateList);
725 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
726 (*env)->DeleteLocalRef(env, jni_str_address);
727 return CA_STATUS_FAILED;
730 if (g_edrPacketReceivedCallback)
732 OIC_LOG_V(DEBUG, TAG, "data will be sent to callback routine: %s, %d",
733 deviceInfo->recvData, deviceInfo->recvDataLen);
735 uint32_t sentLength = 0;
736 g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData,
737 deviceInfo->recvDataLen, &sentLength);
739 OICFree(deviceInfo->recvData);
740 deviceInfo->recvData = NULL;
741 deviceInfo->recvDataLen = 0;
742 deviceInfo->totalDataLen = 0;
746 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
747 (*env)->DeleteLocalRef(env, jni_str_address);
753 void CANativeStartListenTask(JNIEnv *env)
755 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
756 if (!jni_obj_BTServerSocket)
758 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
762 ca_mutex_lock(g_mutexServerSocket);
763 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
764 ca_mutex_unlock(g_mutexServerSocket);
767 jobject CAEDRNativeListen(JNIEnv *env)
769 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - IN");
771 if (!CAEDRNativeIsEnableBTAdapter(env))
773 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
777 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
778 if (!jni_cid_BTAdapter)
780 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
785 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
787 METHODID_OBJECTNONPARAM);
788 if (!jni_mid_getDefaultAdapter)
790 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
794 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
795 jni_mid_getDefaultAdapter);
796 if (!jni_obj_BTAdapter)
798 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
802 // get listen method ID
803 jmethodID jni_mid_listen = (*env)->GetMethodID(
804 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
805 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
808 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
811 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
813 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
816 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
820 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
821 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
822 if (!jni_mid_fromString)
824 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
828 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
831 OIC_LOG(ERROR, TAG, "jni_uuid is null");
834 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
838 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
843 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
846 OIC_LOG(ERROR, TAG, "jni_name is null");
849 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
850 jni_name, jni_obj_uuid);
851 if (!jni_obj_BTServerSocket)
853 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
857 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT");
859 return jni_obj_BTServerSocket;
862 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
864 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - IN");
866 if (NULL != serverSocketObject)
868 jmethodID jni_mid_accept = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
870 "()Landroid/bluetooth/BluetoothSocket;");
873 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
877 OIC_LOG(DEBUG, TAG, "waiting for the new connection request...");
879 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
881 if (!jni_obj_BTSocket)
883 OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null");
885 if ((*env)->ExceptionCheck(env))
887 OIC_LOG(ERROR, TAG, "socket might closed or timeout!!!");
888 (*env)->ExceptionDescribe(env);
889 (*env)->ExceptionClear(env);
894 // get remote address
895 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
898 OIC_LOG(ERROR, TAG, "j_str_address is null");
902 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
904 OIC_LOG_V(INFO, TAG, "accept a new connection from [%s]", address);
907 ca_mutex_lock(g_mutexStateList);
908 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
909 ca_mutex_unlock(g_mutexStateList);
911 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
912 (*env)->DeleteLocalRef(env, j_str_address);
914 // set socket to list
915 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
918 OIC_LOG(ERROR, TAG, "jni_socket is null");
919 (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
923 ca_mutex_lock(g_mutexObjectList);
924 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
925 ca_mutex_unlock(g_mutexObjectList);
927 (*env)->DeleteGlobalRef(env, jni_socket);
928 (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
932 OIC_LOG(DEBUG, TAG, "serverSocket is close previously");
935 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - OUT");
939 * InputStream & BluetoothServerSocket will be close for Terminating.
941 void CAEDRNatvieCloseServerTask(JNIEnv* env)
945 OIC_LOG(DEBUG, TAG, "Accept Resource will be close");
947 jmethodID jni_mid_close = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
951 OIC_LOG(ERROR, TAG, "jni_mid_close is null");
955 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_close);
956 (*env)->DeleteGlobalRef(env, g_serverSocket);
957 g_serverSocket = NULL;
959 OIC_LOG(DEBUG, TAG, "close accept obj");