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";
43 static ca_thread_pool_t g_threadPoolHandle = NULL;
48 * Maximum CoAP over TCP header length
49 * to know the total data length.
51 #define EDR_MAX_HEADER_LEN 6
54 * server socket instance.
56 static jobject g_serverSocketObject = NULL;
59 * Mutex to synchronize receive server.
61 static ca_mutex g_mutexReceiveServer = NULL;
64 * Flag to control the Receive Unicast Data Thread.
66 static bool g_stopUnicast = false;
69 * Mutex to synchronize accept server.
71 static ca_mutex g_mutexAcceptServer = NULL;
74 * Flag to control the Accept Thread.
76 static bool g_stopAccept = false;
79 * Mutex to synchronize server socket.
81 static ca_mutex g_mutexServerSocket = NULL;
84 * Flag to control the server socket.
86 static jobject g_serverSocket = NULL;
89 * Mutex to synchronize device state list.
91 static ca_mutex g_mutexStateList = NULL;
94 * Mutex to synchronize device object list.
96 static ca_mutex g_mutexObjectList = NULL;
99 * Thread context information for unicast, multicast and secured unicast server.
104 CAAdapterServerType_t type;
105 } CAAdapterReceiveThreadContext_t;
110 } CAAdapterAcceptThreadContext_t;
113 * Maintains the callback to be notified when data received from remote
116 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
118 static void CAReceiveHandler(void *data)
120 OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
122 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
124 bool isAttached = false;
126 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
129 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
130 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
134 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
140 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
142 while (true != *(ctx->stopFlag))
144 if (!CAEDRNativeIsEnableBTAdapter(env))
146 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
150 // if new socket object is added in socket list after below logic is ran.
151 // new socket will be started to read after next while loop
152 uint32_t length = CAEDRGetSocketListLength();
155 for (uint32_t idx = 0; idx < length; idx++)
157 CAEDRNativeReadData(env, idx);
164 (*g_jvm)->DetachCurrentThread(g_jvm);
169 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
172 static void CAAcceptHandler(void *data)
174 OIC_LOG(DEBUG, TAG, "AcceptThread start");
176 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
178 bool isAttached = false;
180 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
183 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
184 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
188 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
194 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
195 if (!jni_obj_BTServerSocket)
197 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
201 (*g_jvm)->DetachCurrentThread(g_jvm);
207 ca_mutex_lock(g_mutexServerSocket);
208 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
209 ca_mutex_unlock(g_mutexServerSocket);
211 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
213 // it should be initialized for restart accept thread
214 ca_mutex_lock(g_mutexAcceptServer);
215 g_stopAccept = false;
216 ca_mutex_unlock(g_mutexAcceptServer);
218 while (true != *(ctx->stopFlag))
220 // when BT state is changed with Off. its thread will be stopped
221 if (!CAEDRNativeIsEnableBTAdapter(env))
223 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
224 ca_mutex_lock(g_mutexAcceptServer);
226 ca_mutex_unlock(g_mutexAcceptServer);
227 ca_mutex_lock(g_mutexServerSocket);
228 g_serverSocket = NULL;
229 ca_mutex_unlock(g_mutexServerSocket);
233 CAEDRNativeAccept(env, g_serverSocket);
239 (*g_jvm)->DetachCurrentThread(g_jvm);
244 OIC_LOG(DEBUG, TAG, "AcceptThread finish");
250 * implement for adapter common method.
252 CAResult_t CAEDRServerStart()
254 if (!g_threadPoolHandle)
256 return CA_STATUS_NOT_INITIALIZED;
259 CAResult_t res = CAEDRServerStartAcceptThread();
260 if (CA_STATUS_OK == res)
262 res = CAEDRStartReceiveThread(false);
263 if (CA_STATUS_OK != res)
265 OIC_LOG(ERROR, TAG, "failed to start receive thread");
267 return CA_STATUS_FAILED;
274 CAResult_t CAEDRServerStop()
276 CAEDRStopReceiveThread();
278 ca_mutex_lock(g_mutexAcceptServer);
280 ca_mutex_unlock(g_mutexAcceptServer);
284 OIC_LOG(DEBUG, TAG, "g_jvm is null");
285 return CA_STATUS_FAILED;
288 bool isAttached = false;
290 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
293 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
294 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
298 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
299 return CA_STATUS_FAILED;
304 CAEDRNatvieCloseServerTask(env);
308 (*g_jvm)->DetachCurrentThread(g_jvm);
314 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
316 g_edrPacketReceivedCallback = packetReceivedCallback;
319 static void CAEDRServerDestroyMutex()
321 if (g_mutexReceiveServer)
323 ca_mutex_free(g_mutexReceiveServer);
324 g_mutexReceiveServer = NULL;
327 if (g_mutexAcceptServer)
329 ca_mutex_free(g_mutexAcceptServer);
330 g_mutexAcceptServer = NULL;
333 if (g_mutexServerSocket)
335 ca_mutex_free(g_mutexServerSocket);
336 g_mutexServerSocket = NULL;
339 if (g_mutexStateList)
341 ca_mutex_free(g_mutexStateList);
342 g_mutexStateList = NULL;
345 if (g_mutexObjectList)
347 ca_mutex_free(g_mutexObjectList);
348 g_mutexObjectList = NULL;
352 static CAResult_t CAEDRServerCreateMutex()
354 g_mutexReceiveServer = ca_mutex_new();
355 if (!g_mutexReceiveServer)
357 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
358 return CA_STATUS_FAILED;
361 g_mutexAcceptServer = ca_mutex_new();
362 if (!g_mutexAcceptServer)
364 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
366 CAEDRServerDestroyMutex();
367 return CA_STATUS_FAILED;
370 g_mutexServerSocket = ca_mutex_new();
371 if (!g_mutexServerSocket)
373 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
375 CAEDRServerDestroyMutex();
376 return CA_STATUS_FAILED;
379 g_mutexStateList = ca_mutex_new();
380 if (!g_mutexStateList)
382 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
384 CAEDRServerDestroyMutex();
385 return CA_STATUS_FAILED;
388 g_mutexObjectList = ca_mutex_new();
389 if (!g_mutexObjectList)
391 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
393 CAEDRServerDestroyMutex();
394 return CA_STATUS_FAILED;
400 void CAEDRServerJniInit()
402 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
403 g_jvm = CANativeJNIGetJavaVM();
406 CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle)
408 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
409 VERIFY_NON_NULL(handle, TAG, "handle is NULL");
411 g_threadPoolHandle = handle;
412 CAEDRServerJniInit();
414 return CAEDRServerCreateMutex();
417 CAResult_t CAEDRServerStartAcceptThread()
419 bool isAttached = false;
421 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
424 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
425 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
429 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
430 return CA_STATUS_FAILED;
435 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
438 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
439 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
440 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
443 ca_mutex_lock(g_mutexStateList);
444 CAEDRNativeCreateDeviceStateList();
445 ca_mutex_unlock(g_mutexStateList);
447 ca_mutex_lock(g_mutexObjectList);
448 CAEDRNativeCreateDeviceSocketList();
449 ca_mutex_unlock(g_mutexObjectList);
453 (*g_jvm)->DetachCurrentThread(g_jvm);
456 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
457 sizeof(CAAdapterReceiveThreadContext_t));
460 OIC_LOG(ERROR, TAG, "Out of memory!");
461 return CA_MEMORY_ALLOC_FAILED;
464 ctx->stopFlag = &g_stopAccept;
465 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
467 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
468 OICFree((void *) ctx);
469 return CA_STATUS_FAILED;
475 void CAEDRServerTerminate()
477 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
483 bool isAttached = false;
485 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
488 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
489 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
493 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
499 CAEDRNativeSocketCloseToAll(env);
503 (*g_jvm)->DetachCurrentThread(g_jvm);
506 CAEDRNativeRemoveAllDeviceState();
507 CAEDRNativeRemoveAllDeviceSocket(env);
510 CAEDRServerDestroyMutex();
513 CAResult_t CAEDRStartReceiveThread(bool isSecured)
515 OIC_LOG(DEBUG, TAG, "CAEDRStartReceiveThread");
517 ca_mutex_lock(g_mutexReceiveServer);
520 * The task to listen for data from unicast is added to the thread pool.
521 * This is a blocking call is made where we try to receive some data..
522 * We will keep waiting until some data is received.
523 * This task will be terminated when thread pool is freed on stopping the adapters.
524 * Thread context will be freed by thread on exit.
526 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
527 sizeof(CAAdapterReceiveThreadContext_t));
530 OIC_LOG(ERROR, TAG, "Out of memory!");
531 ca_mutex_unlock(g_mutexReceiveServer);
532 return CA_MEMORY_ALLOC_FAILED;
535 g_stopUnicast = false;
536 ctx->stopFlag = &g_stopUnicast;
537 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
538 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
540 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
541 ca_mutex_unlock(g_mutexReceiveServer);
542 OICFree((void *) ctx);
543 return CA_STATUS_FAILED;
545 ca_mutex_unlock(g_mutexReceiveServer);
547 OIC_LOG(DEBUG, TAG, "OUT");
551 CAResult_t CAEDRStopReceiveThread()
553 OIC_LOG(DEBUG, TAG, "CAEDRStopReceiveThread");
555 ca_mutex_lock(g_mutexReceiveServer);
556 g_stopUnicast = true;
557 ca_mutex_unlock(g_mutexReceiveServer);
562 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id)
564 if ((*env)->ExceptionCheck(env))
566 (*env)->ExceptionDescribe(env);
567 (*env)->ExceptionClear(env);
568 OIC_LOG(ERROR, TAG, "env error!!");
569 return CA_STATUS_FAILED;
572 // check whether this socket object is connected or not.
573 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
576 return CA_STATUS_INVALID_PARAM;
579 // start to read through InputStream
580 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
581 if (!jni_cid_BTsocket)
583 OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null");
584 return CA_STATUS_FAILED;
586 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
588 "()Ljava/io/InputStream;");
590 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
591 jni_mid_getInputStream);
592 if (!jni_obj_inputStream)
594 OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
595 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
596 return CA_STATUS_FAILED;
599 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
600 if (!jni_cid_InputStream)
602 OIC_LOG(ERROR, TAG, "jni_cid_InputStream is null");
603 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
604 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
605 return CA_STATUS_FAILED;
608 jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream,
610 if (!jni_mid_available)
612 OIC_LOG(ERROR, TAG, "jni_mid_available is null");
616 jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
618 CAConnectedDeviceInfo_t *deviceInfo = NULL;
621 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
622 if (!jni_str_address)
624 OIC_LOG(ERROR, TAG, "jni_str_address is null");
628 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
631 OIC_LOG(ERROR, TAG, "address is null");
632 (*env)->DeleteLocalRef(env, jni_str_address);
636 OIC_LOG_V(DEBUG, TAG, "get InputStream..%d, %s", id, address);
637 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream,
641 OIC_LOG(ERROR, TAG, "jni_mid_read is null");
642 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
643 (*env)->DeleteLocalRef(env, jni_str_address);
647 deviceInfo = (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
650 OIC_LOG(ERROR, TAG, "failed to get device info from list");
651 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
652 (*env)->DeleteLocalRef(env, jni_str_address);
656 jint bufSize = (deviceInfo->totalDataLen == 0) ?
657 EDR_MAX_HEADER_LEN : deviceInfo->totalDataLen;
658 if (!deviceInfo->recvData)
660 deviceInfo->recvData = OICCalloc(1, bufSize);
661 if (!deviceInfo->recvData)
663 OIC_LOG(ERROR, TAG, "out of memory");
664 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
665 (*env)->DeleteLocalRef(env, jni_str_address);
670 jbyteArray jbuf = (*env)->NewByteArray(env, (jint) bufSize - deviceInfo->recvDataLen);
673 OIC_LOG(ERROR, TAG, "jbuf is null");
674 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
675 (*env)->DeleteLocalRef(env, jni_str_address);
679 jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read,
681 (jint) bufSize - deviceInfo->recvDataLen);
684 OIC_LOG(ERROR, TAG, "recvLen is -1");
685 (*env)->DeleteLocalRef(env, jbuf);
686 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
687 (*env)->DeleteLocalRef(env, jni_str_address);
691 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
694 OIC_LOG(ERROR, TAG, "buf is null");
695 (*env)->DeleteLocalRef(env, jbuf);
696 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
697 (*env)->DeleteLocalRef(env, jni_str_address);
700 memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen);
701 deviceInfo->recvDataLen += recvLen;
703 OIC_LOG(DEBUG, TAG, "read something from InputStream");
705 if (!deviceInfo->totalDataLen)
707 coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
708 ((unsigned char *) deviceInfo->recvData)[0] >> 4);
709 size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
710 if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen)
712 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
713 deviceInfo->recvDataLen);
714 OIC_LOG_V(DEBUG, TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
716 uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
719 OIC_LOG(ERROR, TAG, "out of memory");
720 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
721 (*env)->DeleteLocalRef(env, jbuf);
722 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
723 (*env)->DeleteLocalRef(env, jni_str_address);
726 deviceInfo->recvData = newBuf;
730 if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
732 if ((*env)->ExceptionCheck(env))
734 OIC_LOG(ERROR, TAG, "read Error!!!");
735 (*env)->ExceptionDescribe(env);
736 (*env)->ExceptionClear(env);
738 // update state to disconnect
739 // the socket will be close next read thread routine
740 ca_mutex_lock(g_mutexStateList);
741 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
742 ca_mutex_unlock(g_mutexStateList);
744 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
745 (*env)->DeleteLocalRef(env, jbuf);
746 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
747 (*env)->DeleteLocalRef(env, jni_str_address);
751 if (g_edrPacketReceivedCallback)
753 OIC_LOG_V(DEBUG, TAG,"data will be sent to callback routine: \
754 %s, %d", deviceInfo->recvData, deviceInfo->recvDataLen);
756 uint32_t sentLength = 0;
757 g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData,
758 deviceInfo->recvDataLen, &sentLength);
760 OICFree(deviceInfo->recvData);
761 deviceInfo->recvData = NULL;
762 deviceInfo->recvDataLen = 0;
763 deviceInfo->totalDataLen = 0;
766 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
767 (*env)->DeleteLocalRef(env, jbuf);
768 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
769 (*env)->DeleteLocalRef(env, jni_str_address);
771 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
772 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
773 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
778 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
779 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
780 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
782 return CA_STATUS_FAILED;
785 void CANativeStartListenTask(JNIEnv *env)
787 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
788 if (!jni_obj_BTServerSocket)
790 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
794 ca_mutex_lock(g_mutexServerSocket);
795 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
796 ca_mutex_unlock(g_mutexServerSocket);
799 jobject CAEDRNativeListen(JNIEnv *env)
801 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - IN");
803 if (!CAEDRNativeIsEnableBTAdapter(env))
805 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
809 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
810 if (!jni_cid_BTAdapter)
812 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
817 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
819 METHODID_OBJECTNONPARAM);
820 if (!jni_mid_getDefaultAdapter)
822 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
826 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
827 jni_mid_getDefaultAdapter);
828 if (!jni_obj_BTAdapter)
830 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
834 // get listen method ID
835 jmethodID jni_mid_listen = (*env)->GetMethodID(
836 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
837 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
840 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
843 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
845 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
848 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
852 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
853 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
854 if (!jni_mid_fromString)
856 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
860 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
863 OIC_LOG(ERROR, TAG, "jni_uuid is null");
866 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
870 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
875 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
878 OIC_LOG(ERROR, TAG, "jni_name is null");
881 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
882 jni_name, jni_obj_uuid);
883 if (!jni_obj_BTServerSocket)
885 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
889 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
891 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT");
893 return jni_obj_BTServerSocket;
896 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
898 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - IN");
900 if (NULL != serverSocketObject)
902 jclass jni_cid_BTServerSocket = (*env)->FindClass(
903 env, "android/bluetooth/BluetoothServerSocket");
904 if (!jni_cid_BTServerSocket)
906 OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null");
910 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
911 "()Landroid/bluetooth/BluetoothSocket;");
914 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
918 OIC_LOG(DEBUG, TAG, "waiting for the new connection request...");
920 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
922 if (!jni_obj_BTSocket)
924 OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null");
926 if ((*env)->ExceptionCheck(env))
928 OIC_LOG(ERROR, TAG, "socket might closed or timeout!!!");
929 (*env)->ExceptionDescribe(env);
930 (*env)->ExceptionClear(env);
935 // get remote address
936 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
939 OIC_LOG(ERROR, TAG, "j_str_address is null");
943 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
944 OIC_LOG_V(DEBUG, TAG, "received the connection request from [%s]", address);
946 // set socket to list
947 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
948 ca_mutex_lock(g_mutexObjectList);
949 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
950 ca_mutex_unlock(g_mutexObjectList);
953 ca_mutex_lock(g_mutexStateList);
954 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
955 ca_mutex_unlock(g_mutexStateList);
957 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
958 (*env)->DeleteLocalRef(env, j_str_address);
960 OIC_LOG_V(DEBUG, TAG, "connected with [%s]", address);
964 OIC_LOG(DEBUG, TAG, "serverSocket is close previously");
967 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - OUT");
971 * InputStream & BluetoothServerSocket will be close for Terminating.
973 void CAEDRNatvieCloseServerTask(JNIEnv* env)
977 OIC_LOG(DEBUG, TAG, "Accept Resource will be close");
979 jclass jni_cid_BTServerSocket = (*env)->FindClass(
980 env, "android/bluetooth/BluetoothServerSocket");
981 if (!jni_cid_BTServerSocket)
983 OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null");
987 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket,
991 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
994 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
995 (*env)->DeleteGlobalRef(env, g_serverSocket);
996 g_serverSocket = NULL;
998 OIC_LOG(DEBUG, TAG, "close accept obj");