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("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 new socket object is added in socket list after below logic is ran.
154 // new socket will be started to read after next while loop
155 uint32_t length = CAEDRGetSocketListLength();
158 for (uint32_t idx = 0; idx < length; idx++)
160 CAEDRNativeReadData(env, idx, ctx->type);
167 (*g_jvm)->DetachCurrentThread(g_jvm);
172 OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
175 static void CAAcceptHandler(void *data)
177 OIC_LOG(DEBUG, TAG, "AcceptThread start");
179 VERIFY_NON_NULL_VOID(data, TAG, "CAAcceptHandler: data is null");
181 bool isAttached = false;
183 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
186 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
187 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
191 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
197 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
198 if (!jni_obj_BTServerSocket)
200 OIC_LOG(ERROR, TAG, "AcceptThread: jni_obj_BTServerSocket is null");
204 (*g_jvm)->DetachCurrentThread(g_jvm);
210 ca_mutex_lock(g_mutexServerSocket);
211 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
212 ca_mutex_unlock(g_mutexServerSocket);
214 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
216 // it should be initialized for restart accept thread
217 ca_mutex_lock(g_mutexAcceptServer);
218 g_stopAccept = false;
219 ca_mutex_unlock(g_mutexAcceptServer);
221 while (true != *(ctx->stopFlag))
223 OIC_LOG(DEBUG, TAG, "AcceptThread running");
225 // when BT state is changed with Off. its thread will be stopped
226 if (!CAEDRNativeIsEnableBTAdapter(env))
228 OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
229 ca_mutex_lock(g_mutexAcceptServer);
231 ca_mutex_unlock(g_mutexAcceptServer);
232 ca_mutex_lock(g_mutexServerSocket);
233 g_serverSocket = NULL;
234 ca_mutex_unlock(g_mutexServerSocket);
238 CAEDRNativeAccept(env, g_serverSocket);
244 (*g_jvm)->DetachCurrentThread(g_jvm);
249 OIC_LOG(DEBUG, TAG, "AcceptThread finish");
254 CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
256 CAResult_t res = CAEDRServerInitialize(handle);
257 if (CA_STATUS_OK != res)
259 OIC_LOG(ERROR, TAG, "CAEDRServerInitialize failed");
261 return CA_STATUS_FAILED;
264 res = CAEDRStartUnicastServer(false);
265 if (CA_STATUS_OK != res)
267 OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
269 return CA_STATUS_FAILED;
275 CAResult_t CAEDRServerStop()
277 CAEDRStopUnicastServer();
278 CAEDRStopMulticastServer();
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_mutexUnicastServer)
325 ca_mutex_free(g_mutexUnicastServer);
326 g_mutexUnicastServer = NULL;
329 if (g_mutexMulticastServer)
331 ca_mutex_free(g_mutexMulticastServer);
332 g_mutexMulticastServer = NULL;
335 if (g_mutexAcceptServer)
337 ca_mutex_free(g_mutexAcceptServer);
338 g_mutexAcceptServer = NULL;
341 if (g_mutexServerSocket)
343 ca_mutex_free(g_mutexServerSocket);
344 g_mutexServerSocket = NULL;
347 if (g_mutexStateList)
349 ca_mutex_free(g_mutexStateList);
350 g_mutexStateList = NULL;
353 if (g_mutexObjectList)
355 ca_mutex_free(g_mutexObjectList);
356 g_mutexObjectList = NULL;
360 static CAResult_t CAEDRServerCreateMutex()
362 g_mutexUnicastServer = ca_mutex_new();
363 if (!g_mutexUnicastServer)
365 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
366 return CA_STATUS_FAILED;
369 g_mutexMulticastServer = ca_mutex_new();
370 if (!g_mutexMulticastServer)
372 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
374 CAEDRServerDestroyMutex();
375 return CA_STATUS_FAILED;
378 g_mutexAcceptServer = ca_mutex_new();
379 if (!g_mutexAcceptServer)
381 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
383 CAEDRServerDestroyMutex();
384 return CA_STATUS_FAILED;
387 g_mutexServerSocket = ca_mutex_new();
388 if (!g_mutexServerSocket)
390 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
392 CAEDRServerDestroyMutex();
393 return CA_STATUS_FAILED;
396 g_mutexStateList = ca_mutex_new();
397 if (!g_mutexStateList)
399 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
401 CAEDRServerDestroyMutex();
402 return CA_STATUS_FAILED;
405 g_mutexObjectList = ca_mutex_new();
406 if (!g_mutexObjectList)
408 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
410 CAEDRServerDestroyMutex();
411 return CA_STATUS_FAILED;
417 void CAEDRServerJniInit()
419 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
420 g_jvm = CANativeJNIGetJavaVM();
423 CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle)
425 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
427 g_threadPoolHandle = handle;
429 CAResult_t res = CAEDRServerStartAcceptThread();
430 if (CA_STATUS_OK != res)
432 OIC_LOG(ERROR, TAG, "CAEDRServerCreateMutex failed");
436 OIC_LOG(DEBUG, TAG, "OUT");
441 CAResult_t CAEDRServerStartAcceptThread()
443 CAEDRServerJniInit();
446 CAResult_t ret = CAEDRServerCreateMutex();
447 if (CA_STATUS_OK != ret)
449 OIC_LOG(ERROR, TAG, "CAEDRServerCreateMutex failed");
453 bool isAttached = false;
455 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
458 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
459 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
463 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
464 return CA_STATUS_FAILED;
469 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
472 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
473 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
474 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
477 ca_mutex_lock(g_mutexStateList);
478 CAEDRNativeCreateDeviceStateList();
479 ca_mutex_unlock(g_mutexStateList);
481 ca_mutex_lock(g_mutexObjectList);
482 CAEDRNativeCreateDeviceSocketList();
483 ca_mutex_unlock(g_mutexObjectList);
487 (*g_jvm)->DetachCurrentThread(g_jvm);
490 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
491 sizeof(CAAdapterReceiveThreadContext_t));
494 OIC_LOG(ERROR, TAG, "Out of memory!");
495 return CA_MEMORY_ALLOC_FAILED;
498 ctx->stopFlag = &g_stopAccept;
499 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
501 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
502 OICFree((void *) ctx);
503 return CA_STATUS_FAILED;
509 void CAEDRServerTerminate()
511 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
517 bool isAttached = false;
519 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
522 OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
523 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
527 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
533 CAEDRNativeSocketCloseToAll(env);
537 (*g_jvm)->DetachCurrentThread(g_jvm);
540 CAEDRNativeRemoveAllDeviceState();
541 CAEDRNativeRemoveAllDeviceSocket(env);
544 CAEDRServerDestroyMutex();
547 CAResult_t CAEDRStartUnicastServer(bool isSecured)
549 OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
551 ca_mutex_lock(g_mutexUnicastServer);
554 * The task to listen for data from unicast is added to the thread pool.
555 * This is a blocking call is made where we try to receive some data..
556 * We will keep waiting until some data is received.
557 * This task will be terminated when thread pool is freed on stopping the adapters.
558 * Thread context will be freed by thread on exit.
560 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
561 sizeof(CAAdapterReceiveThreadContext_t));
564 OIC_LOG(ERROR, TAG, "Out of memory!");
565 ca_mutex_unlock(g_mutexUnicastServer);
566 return CA_MEMORY_ALLOC_FAILED;
569 ctx->stopFlag = &g_stopUnicast;
570 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
571 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
573 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
574 ca_mutex_unlock(g_mutexUnicastServer);
575 OICFree((void *) ctx);
576 return CA_STATUS_FAILED;
578 ca_mutex_unlock(g_mutexUnicastServer);
580 OIC_LOG(DEBUG, TAG, "OUT");
584 CAResult_t CAEDRStartMulticastServer()
586 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
588 ca_mutex_lock(g_mutexMulticastServer);
591 * The task to listen to data from multicast socket is added to the thread pool.
592 * This is a blocking call is made where we try to receive some data.
593 * We will keep waiting until some data is received.
594 * This task will be terminated when thread pool is freed on stopping the adapters.
595 * Thread context will be freed by thread on exit.
597 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
598 sizeof(CAAdapterReceiveThreadContext_t));
601 OIC_LOG(ERROR, TAG, "Out of memory!");
602 ca_mutex_unlock(g_mutexMulticastServer);
604 return CA_MEMORY_ALLOC_FAILED;
607 ctx->stopFlag = &g_stopMulticast;
608 ctx->type = CA_MULTICAST_SERVER;
610 g_stopMulticast = false;
611 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
613 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
615 g_stopMulticast = true;
616 ca_mutex_unlock(g_mutexMulticastServer);
617 OICFree((void *) ctx);
619 return CA_STATUS_FAILED;
621 ca_mutex_unlock(g_mutexMulticastServer);
623 OIC_LOG(DEBUG, TAG, "OUT");
627 CAResult_t CAEDRStopUnicastServer()
629 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
631 ca_mutex_lock(g_mutexUnicastServer);
632 g_stopUnicast = true;
633 ca_mutex_unlock(g_mutexUnicastServer);
638 CAResult_t CAEDRStopMulticastServer()
640 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
642 ca_mutex_lock(g_mutexMulticastServer);
643 g_stopMulticast = true;
644 ca_mutex_unlock(g_mutexMulticastServer);
646 OIC_LOG(INFO, TAG, "Multicast server stopped");
651 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
653 if (!CAEDRNativeIsEnableBTAdapter(env))
655 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
656 return CA_STATUS_INVALID_PARAM;
659 if ((*env)->ExceptionCheck(env))
661 (*env)->ExceptionDescribe(env);
662 (*env)->ExceptionClear(env);
663 OIC_LOG(ERROR, TAG, "env error!!");
664 return CA_STATUS_FAILED;
667 // check whether this socket object is connected or not.
668 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
671 return CA_STATUS_INVALID_PARAM;
674 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
675 if (!jni_str_address)
677 OIC_LOG(ERROR, TAG, "jni_str_address is null");
678 return CA_STATUS_FAILED;
680 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
682 // check it whether is still connected or not through google api
683 jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
686 OIC_LOG(ERROR, TAG, "it is not connected yet.");
688 // remove socket to list
689 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
690 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
691 (*env)->DeleteLocalRef(env, jni_str_address);
693 return CA_STATUS_FAILED;
696 // start to read through InputStream
697 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
698 if (!jni_cid_BTsocket)
700 OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null");
701 (*env)->DeleteLocalRef(env, jni_str_address);
702 return CA_STATUS_FAILED;
704 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
706 "()Ljava/io/InputStream;");
708 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
709 jni_mid_getInputStream);
710 if (!jni_obj_inputStream)
712 OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
713 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
714 (*env)->DeleteLocalRef(env, jni_str_address);
715 return CA_STATUS_FAILED;
718 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
719 if (!jni_cid_InputStream)
721 OIC_LOG(ERROR, TAG, "jni_cid_InputStream is null");
725 jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream,
727 if (!jni_mid_available)
729 OIC_LOG(ERROR, TAG, "jni_mid_available is null");
733 jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
735 CAConnectedDeviceInfo_t *deviceInfo = NULL;
738 OIC_LOG_V(DEBUG, TAG, "get InputStream..%d, %s", id, address);
739 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream,
743 OIC_LOG(ERROR, TAG, "jni_mid_read is null");
747 deviceInfo = (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
750 OIC_LOG(ERROR, TAG, "failed to get device info from list");
754 jint bufSize = (deviceInfo->totalDataLen == 0) ?
755 EDR_MAX_HEADER_LEN : deviceInfo->totalDataLen;
756 if (!deviceInfo->recvData)
758 deviceInfo->recvData = OICCalloc(1, bufSize);
759 if (!deviceInfo->recvData)
761 OIC_LOG(ERROR, TAG, "out of memory");
766 jbyteArray jbuf = (*env)->NewByteArray(env, (jint) bufSize - deviceInfo->recvDataLen);
767 jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read,
769 (jint) bufSize - deviceInfo->recvDataLen);
772 (*env)->DeleteLocalRef(env, jbuf);
776 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
779 (*env)->DeleteLocalRef(env, jbuf);
782 memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen);
783 deviceInfo->recvDataLen += recvLen;
785 OIC_LOG(DEBUG, TAG, "read something from InputStream");
787 if (!deviceInfo->totalDataLen)
789 coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
790 ((unsigned char *) deviceInfo->recvData)[0] >> 4);
791 size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
792 if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen)
794 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
795 deviceInfo->recvDataLen);
796 OIC_LOG_V(DEBUG, TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
798 uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
801 OIC_LOG(ERROR, TAG, "out of memory");
802 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
803 (*env)->DeleteLocalRef(env, jbuf);
806 deviceInfo->recvData = newBuf;
810 if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
812 if ((*env)->ExceptionCheck(env))
814 OIC_LOG(ERROR, TAG, "read Error!!!");
815 (*env)->ExceptionDescribe(env);
816 (*env)->ExceptionClear(env);
818 // update state to disconnect
819 // the socket will be close next read thread routine
820 ca_mutex_lock(g_mutexStateList);
821 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
822 ca_mutex_unlock(g_mutexStateList);
824 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
825 (*env)->DeleteLocalRef(env, jbuf);
829 if (g_edrPacketReceivedCallback)
831 OIC_LOG_V(DEBUG, TAG,"data will be sent to callback routine: \
832 %s, %d", deviceInfo->recvData, deviceInfo->recvDataLen);
834 uint32_t sentLength = 0;
835 g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData,
836 deviceInfo->recvDataLen, &sentLength);
838 OICFree(deviceInfo->recvData);
839 deviceInfo->recvData = NULL;
840 deviceInfo->recvDataLen = 0;
841 deviceInfo->totalDataLen = 0;
844 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
845 (*env)->DeleteLocalRef(env, jbuf);
847 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
848 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
849 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
850 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
851 (*env)->DeleteLocalRef(env, jni_str_address);
856 (*env)->DeleteLocalRef(env, jni_obj_inputStream);
857 (*env)->DeleteLocalRef(env, jni_cid_InputStream);
858 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
859 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
860 (*env)->DeleteLocalRef(env, jni_str_address);
862 return CA_STATUS_FAILED;
865 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
869 OIC_LOG(ERROR, TAG, "socket is null");
873 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
874 if (!jni_cid_BTsocket)
876 OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null");
880 jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
882 if (!jni_mid_isConnected)
884 OIC_LOG(ERROR, TAG, "jni_mid_isConnected is null.");
885 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
889 jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
891 (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
893 return jni_isConnected;
896 void CANativeStartListenTask(JNIEnv *env)
898 jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
899 if (!jni_obj_BTServerSocket)
901 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
905 ca_mutex_lock(g_mutexServerSocket);
906 g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
907 ca_mutex_unlock(g_mutexServerSocket);
910 jobject CAEDRNativeListen(JNIEnv *env)
912 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - IN");
914 if (!CAEDRNativeIsEnableBTAdapter(env))
916 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
920 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
921 if (!jni_cid_BTAdapter)
923 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
928 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
930 METHODID_OBJECTNONPARAM);
931 if (!jni_mid_getDefaultAdapter)
933 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
937 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
938 jni_mid_getDefaultAdapter);
939 if (!jni_obj_BTAdapter)
941 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
945 // get listen method ID
946 jmethodID jni_mid_listen = (*env)->GetMethodID(
947 env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
948 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
951 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
954 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
956 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
959 OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
963 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
964 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
965 if (!jni_mid_fromString)
967 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
971 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
974 OIC_LOG(ERROR, TAG, "jni_uuid is null");
977 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
981 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
986 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
989 OIC_LOG(ERROR, TAG, "jni_name is null");
992 jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
993 jni_name, jni_obj_uuid);
994 if (!jni_obj_BTServerSocket)
996 OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
1000 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1002 OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT");
1004 return jni_obj_BTServerSocket;
1007 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1009 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - IN");
1011 if (NULL != serverSocketObject)
1013 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1014 env, "android/bluetooth/BluetoothServerSocket");
1015 if (!jni_cid_BTServerSocket)
1017 OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null");
1021 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1022 "()Landroid/bluetooth/BluetoothSocket;");
1023 if (!jni_mid_accept)
1025 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
1029 OIC_LOG(DEBUG, TAG, "initiating accept...");
1031 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1033 if (!jni_obj_BTSocket)
1035 OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null");
1037 if ((*env)->ExceptionCheck(env))
1039 OIC_LOG(ERROR, TAG, "socket might closed or timeout!!!");
1040 (*env)->ExceptionDescribe(env);
1041 (*env)->ExceptionClear(env);
1046 // get remote address
1047 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1050 OIC_LOG(ERROR, TAG, "j_str_address is null");
1054 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1055 OIC_LOG_V(DEBUG, TAG, "address is %s", address);
1057 // set socket to list
1058 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1059 ca_mutex_lock(g_mutexObjectList);
1060 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1061 ca_mutex_unlock(g_mutexObjectList);
1063 OIC_LOG(DEBUG, TAG, "Accepted!!");
1066 ca_mutex_lock(g_mutexStateList);
1067 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1068 ca_mutex_unlock(g_mutexStateList);
1070 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1071 (*env)->DeleteLocalRef(env, j_str_address);
1075 OIC_LOG(DEBUG, TAG, "serverSocket is close previously");
1078 OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - OUT");
1082 * InputStream & BluetoothServerSocket will be close for Terminating.
1084 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1088 OIC_LOG(DEBUG, TAG, "Accept Resource will be close");
1090 jclass jni_cid_BTServerSocket = (*env)->FindClass(
1091 env, "android/bluetooth/BluetoothServerSocket");
1092 if (!jni_cid_BTServerSocket)
1094 OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null");
1098 jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1099 if (!jni_mid_accept)
1101 OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
1104 (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1105 (*env)->DeleteGlobalRef(env, g_serverSocket);
1106 g_serverSocket = NULL;
1108 OIC_LOG(DEBUG, TAG, "close accept obj");