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 * when Both Mode(server and client) in App is set,
50 * startDiscoveryServer and startListenningServer is calling.
51 * and then both accept thread and receive thread is running redundantly.
53 static bool g_isStartServer = false;
56 * Maximum CoAP over TCP header length
57 * to know the total data length.
59 #define EDR_MAX_HEADER_LEN 6
62 * Mutex to synchronize receive server.
64 static oc_mutex g_mutexReceiveServer = NULL;
67 * Flag to control the Receive Unicast Data Thread.
69 static bool g_stopUnicast = false;
72 * Mutex to synchronize accept server.
74 static oc_mutex g_mutexAcceptServer = NULL;
77 * Flag to control the Accept Thread.
79 static bool g_stopAccept = false;
82 * Mutex to synchronize server socket.
84 static oc_mutex g_mutexServerSocket = NULL;
87 * Flag to control the server socket.
89 static jobject g_serverSocket = NULL;
92 * Mutex to synchronize device state list.
94 static oc_mutex g_mutexStateList = NULL;
97 * Mutex to synchronize device object list.
99 static oc_mutex g_mutexObjectList = NULL;
102 * Mutex to synchronize start server state.
104 static oc_mutex g_mutexStartServerState = NULL;
107 * Thread context information for unicast, multicast and secured unicast server.
112 CAAdapterServerType_t type;
113 } CAAdapterReceiveThreadContext_t;
118 } CAAdapterAcceptThreadContext_t;
121 * Maintains the callback to be notified when data received from remote
124 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
126 static void CAReceiveHandler(void *data)
128 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
130 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
132 bool isAttached = false;
134 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
137 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
138 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
142 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
148 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
150 while (true != *(ctx->stopFlag))
152 if (!CAEDRNativeIsEnableBTAdapter(env))
154 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
158 // if new socket object is added in socket list after below logic is ran.
159 // new socket will be started to read after next while loop
160 uint32_t length = CAEDRGetSocketListLength();
163 for (uint32_t idx = 0; idx < length; idx++)
165 CAEDRNativeReadData(env, idx);
172 (*g_jvm)->DetachCurrentThread(g_jvm);
177 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
180 static void CAAcceptHandler(void *data)
182 OIC_LOG(DEBUG, TAG, "AcceptThread start");
184 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
186 bool isAttached = false;
188 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
191 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
192 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
196 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
202 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
203 if (!jni_obj_BTServerSocket)
205 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
209 (*g_jvm)->DetachCurrentThread(g_jvm);
215 oc_mutex_lock(g_mutexServerSocket);
216 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
217 oc_mutex_unlock(g_mutexServerSocket);
219 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
221 // it should be initialized for restart accept thread
222 oc_mutex_lock(g_mutexAcceptServer);
223 g_stopAccept = false;
224 oc_mutex_unlock(g_mutexAcceptServer);
226 while (true != *(ctx->stopFlag))
228 // when BT state is changed with Off. its thread will be stopped
229 if (!CAEDRNativeIsEnableBTAdapter(env))
231 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
232 oc_mutex_lock(g_mutexAcceptServer);
234 oc_mutex_unlock(g_mutexAcceptServer);
235 oc_mutex_lock(g_mutexServerSocket);
236 g_serverSocket = NULL;
237 oc_mutex_unlock(g_mutexServerSocket);
241 CAEDRNativeAccept(env, g_serverSocket);
247 (*g_jvm)->DetachCurrentThread(g_jvm);
252 OIC_LOG(DEBUG, TAG, "AcceptThread finish");
258 * implement for adapter common method.
260 CAResult_t CAEDRServerStart()
262 if (!g_threadPoolHandle)
264 return CA_STATUS_NOT_INITIALIZED;
267 oc_mutex_lock(g_mutexStartServerState);
270 OIC_LOG(DEBUG, TAG, "server already started");
271 oc_mutex_unlock(g_mutexStartServerState);
274 oc_mutex_unlock(g_mutexStartServerState);
276 CAResult_t res = CAEDRServerStartAcceptThread();
277 if (CA_STATUS_OK == res)
279 res = CAEDRStartReceiveThread(false);
280 if (CA_STATUS_OK != res)
282 OIC_LOG(ERROR, TAG, "failed to start receive thread");
284 return CA_STATUS_FAILED;
286 oc_mutex_lock(g_mutexStartServerState);
287 g_isStartServer = true;
288 oc_mutex_unlock(g_mutexStartServerState);
294 CAResult_t CAEDRServerStop()
296 CAEDRStopReceiveThread();
298 oc_mutex_lock(g_mutexAcceptServer);
300 oc_mutex_unlock(g_mutexAcceptServer);
304 OIC_LOG(DEBUG, TAG, "g_jvm is null");
305 return CA_STATUS_FAILED;
308 bool isAttached = false;
310 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
313 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
314 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
318 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
319 return CA_STATUS_FAILED;
324 CAEDRNatvieCloseServerTask(env);
325 oc_mutex_lock(g_mutexStartServerState);
326 g_isStartServer = false;
327 oc_mutex_unlock(g_mutexStartServerState);
331 (*g_jvm)->DetachCurrentThread(g_jvm);
337 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
339 g_edrPacketReceivedCallback = packetReceivedCallback;
342 static void CAEDRServerDestroyMutex()
344 if (g_mutexReceiveServer)
346 oc_mutex_free(g_mutexReceiveServer);
347 g_mutexReceiveServer = NULL;
350 if (g_mutexAcceptServer)
352 oc_mutex_free(g_mutexAcceptServer);
353 g_mutexAcceptServer = NULL;
356 if (g_mutexServerSocket)
358 oc_mutex_free(g_mutexServerSocket);
359 g_mutexServerSocket = NULL;
362 if (g_mutexStateList)
364 oc_mutex_free(g_mutexStateList);
365 g_mutexStateList = NULL;
368 if (g_mutexObjectList)
370 oc_mutex_free(g_mutexObjectList);
371 g_mutexObjectList = NULL;
374 if (g_mutexStartServerState)
376 oc_mutex_free(g_mutexStartServerState);
377 g_mutexStartServerState = NULL;
381 static CAResult_t CAEDRServerCreateMutex()
383 g_mutexReceiveServer = oc_mutex_new();
384 if (!g_mutexReceiveServer)
386 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
387 return CA_STATUS_FAILED;
390 g_mutexAcceptServer = oc_mutex_new();
391 if (!g_mutexAcceptServer)
393 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
395 CAEDRServerDestroyMutex();
396 return CA_STATUS_FAILED;
399 g_mutexServerSocket = oc_mutex_new();
400 if (!g_mutexServerSocket)
402 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
404 CAEDRServerDestroyMutex();
405 return CA_STATUS_FAILED;
408 g_mutexStateList = oc_mutex_new();
409 if (!g_mutexStateList)
411 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
413 CAEDRServerDestroyMutex();
414 return CA_STATUS_FAILED;
417 g_mutexObjectList = oc_mutex_new();
418 if (!g_mutexObjectList)
420 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
422 CAEDRServerDestroyMutex();
423 return CA_STATUS_FAILED;
426 g_mutexStartServerState = oc_mutex_new();
427 if (!g_mutexStartServerState)
429 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
431 CAEDRServerDestroyMutex();
432 return CA_STATUS_FAILED;
438 void CAEDRServerJniInit()
440 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
441 g_jvm = CANativeJNIGetJavaVM();
444 CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle)
446 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
447 VERIFY_NON_NULL(handle, TAG, "handle is NULL");
449 g_threadPoolHandle = handle;
450 CAEDRServerJniInit();
452 return CAEDRServerCreateMutex();
455 CAResult_t CAEDRServerStartAcceptThread()
457 bool isAttached = false;
459 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
462 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
463 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
467 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
468 return CA_STATUS_FAILED;
473 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
476 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
477 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
478 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
481 oc_mutex_lock(g_mutexStateList);
482 CAEDRNativeCreateDeviceStateList();
483 oc_mutex_unlock(g_mutexStateList);
485 oc_mutex_lock(g_mutexObjectList);
486 CAEDRNativeCreateDeviceSocketList();
487 oc_mutex_unlock(g_mutexObjectList);
491 (*g_jvm)->DetachCurrentThread(g_jvm);
494 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
495 sizeof(CAAdapterReceiveThreadContext_t));
498 OIC_LOG(ERROR, TAG, "Out of memory!");
499 return CA_MEMORY_ALLOC_FAILED;
502 ctx->stopFlag = &g_stopAccept;
503 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler,
506 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
507 OICFree((void *) ctx);
508 return CA_STATUS_FAILED;
514 void CAEDRServerTerminate()
516 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
522 bool isAttached = false;
524 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
527 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
528 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
532 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
538 CAEDRNativeSocketCloseToAll(env);
542 (*g_jvm)->DetachCurrentThread(g_jvm);
545 CAEDRNativeRemoveAllDeviceState();
546 CAEDRNativeRemoveAllDeviceSocket(env);
549 CAEDRServerDestroyMutex();
552 CAResult_t CAEDRStartReceiveThread(bool isSecured)
554 OIC_LOG(DEBUG, TAG, "CAEDRStartReceiveThread");
556 oc_mutex_lock(g_mutexReceiveServer);
559 * The task to listen for data from unicast is added to the thread pool.
560 * This is a blocking call is made where we try to receive some data..
561 * We will keep waiting until some data is received.
562 * This task will be terminated when thread pool is freed on stopping the adapters.
563 * Thread context will be freed by thread on exit.
565 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
566 sizeof(CAAdapterReceiveThreadContext_t));
569 OIC_LOG(ERROR, TAG, "Out of memory!");
570 oc_mutex_unlock(g_mutexReceiveServer);
571 return CA_MEMORY_ALLOC_FAILED;
574 g_stopUnicast = false;
575 ctx->stopFlag = &g_stopUnicast;
576 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
577 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler,
580 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
581 oc_mutex_unlock(g_mutexReceiveServer);
582 OICFree((void *) ctx);
583 return CA_STATUS_FAILED;
585 oc_mutex_unlock(g_mutexReceiveServer);
587 OIC_LOG(DEBUG, TAG, "OUT");
591 CAResult_t CAEDRStopReceiveThread()
593 OIC_LOG(DEBUG, TAG, "CAEDRStopReceiveThread");
595 oc_mutex_lock(g_mutexReceiveServer);
596 g_stopUnicast = true;
597 oc_mutex_unlock(g_mutexReceiveServer);
602 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t idx)
604 if ((*env)->ExceptionCheck(env))
606 (*env)->ExceptionDescribe(env);
607 (*env)->ExceptionClear(env);
608 OIC_LOG(ERROR, TAG, "env error!!");
609 return CA_STATUS_FAILED;
612 jobject jni_obj_inputStream = CAEDRNativeGetInputStream(idx);
613 if (!jni_obj_inputStream)
615 OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
616 return CA_STATUS_FAILED;
619 jmethodID jni_mid_available = CAGetJNIMethodID(env, "java/io/InputStream", "available", "()I");
620 if (!jni_mid_available)
622 OIC_LOG(ERROR, TAG, "jni_mid_available is null");
623 return CA_STATUS_FAILED;
626 jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
630 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(idx);
633 OIC_LOG(ERROR, TAG, "jni_obj_socket is null");
634 return CA_STATUS_FAILED;
637 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
638 if (!jni_str_address)
640 OIC_LOG(ERROR, TAG, "jni_str_address is null");
641 return CA_STATUS_FAILED;
644 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
647 OIC_LOG(ERROR, TAG, "address is null");
648 (*env)->DeleteLocalRef(env, jni_str_address);
649 return CA_STATUS_FAILED;
652 CAConnectedDeviceInfo_t *deviceInfo =
653 (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
656 OIC_LOG(ERROR, TAG, "failed to get device info from list");
657 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
658 (*env)->DeleteLocalRef(env, jni_str_address);
659 return CA_STATUS_FAILED;
662 jint bufSize = (deviceInfo->totalDataLen == 0) ? EDR_MAX_HEADER_LEN
663 : deviceInfo->totalDataLen;
664 if (!deviceInfo->recvData)
666 deviceInfo->recvData = OICCalloc(1, bufSize);
667 if (!deviceInfo->recvData)
669 OIC_LOG(ERROR, TAG, "out of memory");
670 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
671 (*env)->DeleteLocalRef(env, jni_str_address);
672 return CA_STATUS_FAILED;
676 jint remainSize = (jint) bufSize - deviceInfo->recvDataLen;
679 OIC_LOG(ERROR, TAG, "remainSize value is invalid.");
680 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
681 (*env)->DeleteLocalRef(env, jni_str_address);
682 return CA_STATUS_FAILED;
685 jbyteArray jbuf = (*env)->NewByteArray(env, remainSize);
688 OIC_LOG(ERROR, TAG, "jbuf is null");
689 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
690 (*env)->DeleteLocalRef(env, jni_str_address);
691 return CA_STATUS_FAILED;
694 jmethodID jni_mid_read = CAGetJNIMethodID(env, "java/io/InputStream", "read", "([BII)I");
697 OIC_LOG(ERROR, TAG, "jni_mid_read is null");
698 (*env)->DeleteLocalRef(env, jbuf);
699 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
700 (*env)->DeleteLocalRef(env, jni_str_address);
701 return CA_STATUS_FAILED;
704 OIC_LOG_V(DEBUG, TAG, "read InputStream (idx:%d, addr:%s)", idx, address);
705 jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read,
706 jbuf, (jint) 0, remainSize);
709 OIC_LOG(ERROR, TAG, "recvLen is -1");
710 (*env)->DeleteLocalRef(env, jbuf);
711 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
712 (*env)->DeleteLocalRef(env, jni_str_address);
713 return CA_STATUS_FAILED;
715 OIC_LOG_V(DEBUG, TAG, "read success (length: %d bytes)", recvLen);
717 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
720 OIC_LOG(ERROR, TAG, "buf is null");
721 (*env)->DeleteLocalRef(env, jbuf);
722 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
723 (*env)->DeleteLocalRef(env, jni_str_address);
724 return CA_STATUS_FAILED;
726 memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen);
727 deviceInfo->recvDataLen += recvLen;
729 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
730 (*env)->DeleteLocalRef(env, jbuf);
732 if (!deviceInfo->totalDataLen && deviceInfo->recvData)
734 coap_transport_t transport = coap_get_tcp_header_type_from_initbyte(
735 ((unsigned char *) deviceInfo->recvData)[0] >> 4);
736 size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
737 if (deviceInfo->recvDataLen >= headerLen)
739 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
740 deviceInfo->recvDataLen);
741 OIC_LOG_V(DEBUG, TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
743 uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
746 OIC_LOG(ERROR, TAG, "out of memory");
747 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
748 (*env)->DeleteLocalRef(env, jni_str_address);
749 return CA_STATUS_FAILED;
751 deviceInfo->recvData = newBuf;
755 if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
757 if ((*env)->ExceptionCheck(env))
759 OIC_LOG(ERROR, TAG, "read Error!!!");
760 (*env)->ExceptionDescribe(env);
761 (*env)->ExceptionClear(env);
763 // update state to disconnect
764 // the socket will be close next read thread routine
765 oc_mutex_lock(g_mutexStateList);
766 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
767 oc_mutex_unlock(g_mutexStateList);
769 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
770 (*env)->DeleteLocalRef(env, jni_str_address);
771 return CA_STATUS_FAILED;
774 if (g_edrPacketReceivedCallback)
776 OIC_LOG_V(DEBUG, TAG, "data will be sent to callback routine: %s, %d",
777 deviceInfo->recvData, deviceInfo->recvDataLen);
779 uint32_t sentLength = 0;
780 g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData,
781 deviceInfo->recvDataLen, &sentLength);
783 OICFree(deviceInfo->recvData);
784 deviceInfo->recvData = NULL;
785 deviceInfo->recvDataLen = 0;
786 deviceInfo->totalDataLen = 0;
790 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
791 (*env)->DeleteLocalRef(env, jni_str_address);
797 void CANativeStartListenTask(JNIEnv *env)
799 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
800 if (!jni_obj_BTServerSocket)
802 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
806 oc_mutex_lock(g_mutexServerSocket);
807 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
808 oc_mutex_unlock(g_mutexServerSocket);
811 jobject CAEDRNativeListen(JNIEnv *env)
813 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - IN");
815 if (!CAEDRNativeIsEnableBTAdapter(env))
817 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
821 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
822 if (!jni_cid_BTAdapter)
824 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
829 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
831 METHODID_OBJECTNONPARAM);
832 if (!jni_mid_getDefaultAdapter)
834 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
838 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
839 jni_mid_getDefaultAdapter);
840 if (!jni_obj_BTAdapter)
842 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
846 // get listen method ID
847 jmethodID jni_mid_listen = (*env)->GetMethodID(
848 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
849 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
852 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
855 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
857 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
860 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
864 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
865 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
866 if (!jni_mid_fromString)
868 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
872 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
875 OIC_LOG(ERROR, TAG, "jni_uuid is null");
878 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
882 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
887 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
890 OIC_LOG(ERROR, TAG, "jni_name is null");
893 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
894 jni_name, jni_obj_uuid);
895 if (!jni_obj_BTServerSocket)
897 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
901 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT");
903 return jni_obj_BTServerSocket;
906 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
908 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - IN");
910 if (NULL != serverSocketObject)
912 jmethodID jni_mid_accept = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
914 "()Landroid/bluetooth/BluetoothSocket;");
917 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
921 OIC_LOG(DEBUG, TAG, "waiting for the new connection request...");
923 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
925 if (!jni_obj_BTSocket)
927 OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null");
929 if ((*env)->ExceptionCheck(env))
931 OIC_LOG(ERROR, TAG, "socket might closed or timeout!!!");
932 (*env)->ExceptionDescribe(env);
933 (*env)->ExceptionClear(env);
938 // get remote address
939 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
942 OIC_LOG(ERROR, TAG, "j_str_address is null");
946 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
948 OIC_LOG_V(INFO, TAG, "accept a new connection from [%s]", address);
951 oc_mutex_lock(g_mutexStateList);
952 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
953 oc_mutex_unlock(g_mutexStateList);
955 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
956 (*env)->DeleteLocalRef(env, j_str_address);
958 // set socket to list
959 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
962 OIC_LOG(ERROR, TAG, "jni_socket is null");
963 (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
967 oc_mutex_lock(g_mutexObjectList);
968 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
969 oc_mutex_unlock(g_mutexObjectList);
971 (*env)->DeleteGlobalRef(env, jni_socket);
972 (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
976 OIC_LOG(DEBUG, TAG, "serverSocket is close previously");
979 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - OUT");
983 * InputStream & BluetoothServerSocket will be close for Terminating.
985 void CAEDRNatvieCloseServerTask(JNIEnv* env)
989 OIC_LOG(DEBUG, TAG, "Accept Resource will be close");
991 jmethodID jni_mid_close = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
995 OIC_LOG(ERROR, TAG, "jni_mid_close is null");
999 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_close);
1000 (*env)->DeleteGlobalRef(env, g_serverSocket);
1001 g_serverSocket = NULL;
1003 OIC_LOG(DEBUG, TAG, "close accept obj");