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 "caedrclient.h"
29 #include "oic_malloc.h"
30 #include "oic_string.h"
31 #include "cathreadpool.h" /* for thread pool */
33 #include "uarraylist.h"
34 #include "caadapterutils.h"
37 #define TAG PCF("CA_EDR_CLIENT")
39 static const char METHODID_CONTEXTNONPARAM[] = "()Landroid/content/Context;";
40 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
41 static const char METHODID_OUTPUTNONPARAM[] = "()Ljava/io/OutputStream;";
42 static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;";
43 static const char METHODID_BT_DEVICEPARAM[] =
44 "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;";
45 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
46 static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice";
47 static const char CLASSPATH_BT_INTERFACE[] = "org/iotivity/ca/CaEdrInterface";
48 static const char CLASSPATH_BT_SOCKET[] = "android/bluetooth/BluetoothSocket";
49 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
50 static const char CLASSPATH_CONTEXT[] = "android/content/Context";
51 static const char CLASSPATH_OUTPUT[] = "java/io/OutputStream";
53 static ca_thread_pool_t g_threadPoolHandle = NULL;
56 static jobject g_context;
59 * @var g_mutexUnicastServer
60 * @brief Mutex to synchronize unicast server
62 static ca_mutex g_mutexUnicastServer = NULL;
66 * @brief Flag to control the Receive Unicast Data Thread
68 static bool g_stopUnicast = false;
71 * @var g_mutexMulticastServer
72 * @brief Mutex to synchronize secure multicast server
74 static ca_mutex g_mutexMulticastServer = NULL;
77 * @var g_stopMulticast
78 * @brief Flag to control the Receive Multicast Data Thread
80 static bool g_stopMulticast = false;
84 * @brief Flag to control the Accept Thread
86 static bool g_stopAccept = false;
89 * @var g_mutexStateList
90 * @brief Mutex to synchronize device state list
92 static ca_mutex g_mutexStateList = NULL;
95 * @var g_mutexObjectList
96 * @brief Mutex to synchronize device object list
98 static ca_mutex g_mutexObjectList = NULL;
101 * @var g_edrErrorHandler
102 * @brief Error callback to update error in EDR
104 static CAEDRErrorHandleCallback g_edrErrorHandler = NULL;
106 typedef struct send_data
114 @brief Thread context information for unicast, multicast and secured unicast server
119 CAAdapterServerType_t type;
120 } CAAdapterReceiveThreadContext_t;
125 } CAAdapterAcceptThreadContext_t;
128 * implement for BT-EDR adapter common method
130 CAResult_t CAEDRGetInterfaceInformation(CAEndpoint_t **info)
132 OIC_LOG(DEBUG, TAG, "IN - CAEDRGetInterfaceInformation");
136 OIC_LOG(ERROR, TAG, "endpoint info is null");
137 return CA_STATUS_FAILED;
140 int32_t netInfoSize = 1;
142 char *macAddress = NULL;
143 CAResult_t ret = CAEDRGetInterfaceInfo(&macAddress);
144 OIC_LOG_V(ERROR, TAG, "address : %s", macAddress);
145 if (NULL == macAddress)
147 OIC_LOG(ERROR, TAG, "mac address is null");
149 return CA_STATUS_FAILED;
151 if (CA_STATUS_OK != ret)
153 OIC_LOG_V(ERROR, TAG, "Failed to get interface info [%d]", ret);
159 // Create local endpoint using util function
160 CAEndpoint_t *endpoint = CAAdapterCreateEndpoint(CA_DEFAULT_FLAGS,
161 CA_ADAPTER_RFCOMM_BTEDR, macAddress, 0);
162 if (NULL == endpoint)
164 OIC_LOG(ERROR, TAG, "Failed to create Local Endpoint!");
166 return CA_STATUS_FAILED;
169 // copy unicast server information
170 CAEndpoint_t *netInfo = (CAEndpoint_t *)OICMalloc(sizeof(CAEndpoint_t) * netInfoSize);
173 OIC_LOG(ERROR, TAG, "Invalid input..");
175 CAAdapterFreeEndpoint(endpoint);
176 return CA_MEMORY_ALLOC_FAILED;
178 *netInfo = *endpoint;
182 CAAdapterFreeEndpoint(endpoint);
184 OIC_LOG(DEBUG, TAG, "OUT - CAEDRGetInterfaceInformation");
188 void CAEDRClientTerminate()
190 OIC_LOG(DEBUG, TAG, "IN");
192 OIC_LOG(DEBUG, TAG, "OUT");
195 CAResult_t CAEDRManagerReadData(void)
197 OIC_LOG(DEBUG, TAG, "IN");
199 OIC_LOG(DEBUG, TAG, "OUT");
200 return CA_NOT_SUPPORTED;
203 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
204 const void *data, uint32_t dataLength, uint32_t *sentLength)
206 OIC_LOG(DEBUG, TAG, "IN");
207 CAResult_t result = CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength);
208 OIC_LOG(DEBUG, TAG, "OUT");
212 CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data,
213 uint32_t dataLength, uint32_t *sentLength)
215 OIC_LOG(DEBUG, TAG, "IN");
216 CAResult_t result = CAEDRSendMulticastMessage((const char*) data, dataLength);
217 OIC_LOG(DEBUG, TAG, "OUT");
221 // It will be updated when android EDR support is added
222 void CAEDRClientUnsetCallbacks(void)
224 OIC_LOG(DEBUG, TAG, "IN");
226 OIC_LOG(DEBUG, TAG, "OUT");
229 // It will be updated when android EDR support is added
230 void CAEDRClientDisconnectAll(void)
232 OIC_LOG(DEBUG, TAG, "IN");
234 OIC_LOG(DEBUG, TAG, "OUT");
237 CAResult_t CAEDRGetAdapterEnableState(bool *state)
239 OIC_LOG(DEBUG, TAG, "IN");
242 OIC_LOG(ERROR, TAG, "g_jvm is null");
243 return CA_STATUS_INVALID_PARAM;
245 bool isAttached = false;
247 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
250 OIC_LOG(DEBUG, TAG, "CAEDRGetAdapterEnableState - Could not get JNIEnv pointer");
251 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
255 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
256 return CA_STATUS_INVALID_PARAM;
260 jboolean ret = CAEDRNativeIsEnableBTAdapter(env);
272 (*g_jvm)->DetachCurrentThread(g_jvm);
275 OIC_LOG(DEBUG, TAG, "OUT");
279 void CAEDRJniInitContext()
281 OIC_LOG(DEBUG, TAG, "CAEDRJniInitContext");
283 g_context = (jobject) CANativeJNIGetContext();
286 CAResult_t CAEDRCreateJNIInterfaceObject(jobject context)
289 OIC_LOG(DEBUG, TAG, "[EDRCore] CAEDRCreateJNIInterfaceObject");
291 if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
293 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get JNIEnv pointer");
294 return CA_STATUS_FAILED;
297 //getApplicationContext
298 jclass contextClass = (*env)->FindClass(env, CLASSPATH_CONTEXT);
301 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get context object class");
302 return CA_STATUS_FAILED;
305 jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
306 "getApplicationContext",
307 METHODID_CONTEXTNONPARAM);
308 if (!getApplicationContextMethod)
310 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get getApplicationContext method");
311 return CA_STATUS_FAILED;
314 //Create EDRJniInterface instance
315 jclass EDRJniInterface = (*env)->FindClass(env, CLASSPATH_BT_INTERFACE);
316 if (!EDRJniInterface)
318 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CaEdrInterface class");
319 return CA_STATUS_FAILED;
322 jmethodID EDRInterfaceConstructorMethod = (*env)->GetMethodID(env, EDRJniInterface, "<init>",
323 "(Landroid/content/Context;)V");
324 if (!EDRInterfaceConstructorMethod)
326 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CaEdrInterface constructor method");
327 return CA_STATUS_FAILED;
330 (*env)->NewObject(env, EDRJniInterface, EDRInterfaceConstructorMethod, context);
331 OIC_LOG(DEBUG, TAG, "[EDRCore] NewObject Success");
337 static void CAEDRDestroyMutex()
339 OIC_LOG(DEBUG, TAG, "IN");
341 if (g_mutexUnicastServer)
343 ca_mutex_free(g_mutexUnicastServer);
344 g_mutexUnicastServer = NULL;
347 if (g_mutexMulticastServer)
349 ca_mutex_free(g_mutexMulticastServer);
350 g_mutexMulticastServer = NULL;
353 if (g_mutexStateList)
355 ca_mutex_free(g_mutexStateList);
356 g_mutexStateList = NULL;
359 if (g_mutexObjectList)
361 ca_mutex_free(g_mutexObjectList);
362 g_mutexObjectList = NULL;
364 OIC_LOG(DEBUG, TAG, "OUT");
367 static CAResult_t CAEDRCreateMutex()
369 OIC_LOG(DEBUG, TAG, "IN");
371 g_mutexUnicastServer = ca_mutex_new();
372 if (!g_mutexUnicastServer)
374 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
375 return CA_STATUS_FAILED;
378 g_mutexMulticastServer = ca_mutex_new();
379 if (!g_mutexMulticastServer)
381 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
384 return CA_STATUS_FAILED;
387 g_mutexStateList = ca_mutex_new();
388 if (!g_mutexStateList)
390 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
393 return CA_STATUS_FAILED;
396 g_mutexObjectList = ca_mutex_new();
397 if (!g_mutexObjectList)
399 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
402 return CA_STATUS_FAILED;
405 OIC_LOG(DEBUG, TAG, "OUT");
409 void CAEDRInitialize(ca_thread_pool_t handle)
411 OIC_LOG(DEBUG, TAG, "CAEDRInitialize");
413 g_threadPoolHandle = handle;
417 CAEDRJniInitContext();
422 bool isAttached = false;
424 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
427 OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
428 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
432 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
437 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
440 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
441 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
442 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
445 ca_mutex_lock(g_mutexStateList);
446 CAEDRNativeCreateDeviceStateList();
447 ca_mutex_unlock(g_mutexStateList);
449 ca_mutex_lock(g_mutexObjectList);
450 CAEDRNativeCreateDeviceSocketList();
451 ca_mutex_unlock(g_mutexObjectList);
455 (*g_jvm)->DetachCurrentThread(g_jvm);
460 CAEDRCreateJNIInterfaceObject(g_context); /* create java CaEdrInterface instance*/
463 OIC_LOG(DEBUG, TAG, "OUT");
466 void CAEDRTerminate()
468 OIC_LOG(DEBUG, TAG, "CAEDRTerminate");
470 bool isAttached = false;
472 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
475 OIC_LOG(DEBUG, TAG, "CAEDRTerminate - Could not get JNIEnv pointer");
476 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
480 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
487 g_stopMulticast = true;
488 g_stopUnicast = true;
492 (*g_jvm)->DetachCurrentThread(g_jvm);
497 (*env)->DeleteGlobalRef(env, g_context);
500 CAEDRNativeSocketCloseToAll(env);
505 CAEDRNativeRemoveAllDeviceState();
506 CAEDRNativeRemoveAllDeviceSocket(env);
509 void CAEDRCoreJniInit()
511 OIC_LOG(DEBUG, TAG, "CAEdrClientJniInit");
512 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
515 CAResult_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
517 OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data);
519 CAResult_t result = CAEDRSendUnicastMessageImpl(address, data, dataLen);
523 CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
525 OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage(%s)", data);
527 bool isAttached = false;
529 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
532 OIC_LOG(DEBUG, TAG, "CAEDRSendMulticastMessage - Could not get JNIEnv pointer");
533 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
537 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
538 return CA_STATUS_INVALID_PARAM;
543 CAResult_t result = CAEDRSendMulticastMessageImpl(env, data, dataLen);
544 if(CA_STATUS_OK != result)
546 OIC_LOG(ERROR, TAG, "CAEDRSendMulticastMessage - could not send multicast message");
550 OIC_LOG(DEBUG, TAG, "sent data");
554 OIC_LOG(DEBUG, TAG, "DetachCurrentThread");
555 (*g_jvm)->DetachCurrentThread(g_jvm);
558 OIC_LOG(DEBUG, TAG, "OUT - CAEDRSendMulticastMessage");
562 CAResult_t CAEDRGetInterfaceInfo(char **address)
564 CAEDRGetLocalAddress(address);
568 void CAEDRGetLocalAddress(char **address)
570 bool isAttached = false;
572 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
575 OIC_LOG(DEBUG, TAG, "CAEDRGetLocalAddress - Could not get JNIEnv pointer");
576 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
579 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
585 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
588 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
589 *address = OICStrdup(localAddress);
590 if (*address == NULL)
594 (*g_jvm)->DetachCurrentThread(g_jvm);
599 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
602 OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
605 (*g_jvm)->DetachCurrentThread(g_jvm);
609 CAResult_t CAEDRSendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen)
611 OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessageImpl, address: %s, data: %s", address, data);
613 bool isAttached = false;
615 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
618 OIC_LOG(DEBUG, TAG, "CAEDRSendUnicastMessageImpl - Could not get JNIEnv pointer");
619 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
622 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
623 return CA_STATUS_INVALID_PARAM;
628 OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data");
630 // get bonded device list
631 jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
632 if (!jni_arrayPairedDevices)
634 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
637 (*g_jvm)->DetachCurrentThread(g_jvm);
639 return CA_STATUS_INVALID_PARAM;
641 // Get information from array of devices
642 jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
643 jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName",
644 METHODID_STRINGNONPARAM);
645 jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress",
646 METHODID_STRINGNONPARAM);
648 jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
650 for (i = 0; i < length; i++)
652 OIC_LOG(DEBUG, TAG, "[EDR][Native] start to check device");
653 // get name, address from BT device
654 jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
655 jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
659 const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
660 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
661 (*env)->ReleaseStringUTFChars(env, j_str_name, name);
664 jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
665 const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
666 OIC_LOG_V(DEBUG, TAG,
667 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
671 OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
674 (*g_jvm)->DetachCurrentThread(g_jvm);
676 return CA_STATUS_INVALID_PARAM;
680 OIC_LOG(ERROR, TAG, "[EDR][Native] address is null");
683 (*g_jvm)->DetachCurrentThread(g_jvm);
685 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
686 return CA_STATUS_INVALID_PARAM;
689 if (!strcmp(remoteAddress, address))
691 CAResult_t res = CAEDRNativeSendData(env, remoteAddress, data, dataLen, i);
692 if (CA_STATUS_OK != res)
694 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
698 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
703 (*g_jvm)->DetachCurrentThread(g_jvm);
709 CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
711 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
713 // get bonded device list
714 jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
715 if (!jni_arrayPairedDevices)
717 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
718 return CA_STATUS_INVALID_PARAM;
720 // Get information from array of devices
721 jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
722 jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName",
723 METHODID_STRINGNONPARAM);
724 jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress",
725 METHODID_STRINGNONPARAM);
727 jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
729 for (i = 0; i < length; i++)
731 // get name, address from BT device
732 jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
733 jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
737 const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
738 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
739 (*env)->ReleaseStringUTFChars(env, j_str_name, name);
742 jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
743 const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
744 OIC_LOG_V(DEBUG, TAG,
745 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
748 CAResult_t res = CAEDRNativeSendData(env, remoteAddress, data, dataLen, i);
749 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
750 if (CA_STATUS_OK != res)
752 OIC_LOG_V(ERROR, TAG, "CASendMulticastMessageImpl, failed to send message to : %s",
754 g_edrErrorHandler(remoteAddress, OIC_EDR_SERVICE_ID, data, dataLen, res);
765 CAResult_t CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data,
766 uint32_t dataLength, uint32_t id)
768 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData logic start : %s, %d", data, dataLength);
770 if (!CAEDRNativeIsEnableBTAdapter(env))
772 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
773 return CA_STATUS_INVALID_PARAM;
776 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
778 // connect before send data
779 OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data");
783 OIC_LOG(ERROR, TAG, "[EDR][Native] remote address is empty");
784 return CA_STATUS_INVALID_PARAM;
788 CAResult_t res = CAEDRNativeConnect(env, address, id);
789 if (CA_STATUS_OK != res)
796 if (STATE_CONNECTED == CAEDRIsConnectedDevice(address))
798 if (!((*env)->ExceptionCheck(env)))
800 jclass jni_cid_BTsocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET);
801 if (!jni_cid_BTsocket)
803 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null");
804 return CA_STATUS_FAILED;
807 jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
809 METHODID_OUTPUTNONPARAM);
810 if (!jni_mid_getOutputStream)
812 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null");
813 return CA_STATUS_FAILED;
816 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream");
818 jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address);
821 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_socket is not available");
822 return CA_STATUS_FAILED;
825 jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
826 jni_mid_getOutputStream);
827 if (!jni_obj_outputStream)
829 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null");
830 return CA_STATUS_FAILED;
833 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream..");
835 jclass jni_cid_OutputStream = (*env)->FindClass(env, CLASSPATH_OUTPUT);
836 if (!jni_cid_OutputStream)
838 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null");
839 return CA_STATUS_FAILED;
842 jmethodID jni_mid_write = (*env)->GetMethodID(env, jni_cid_OutputStream, "write",
846 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_write is null");
847 return CA_STATUS_FAILED;
851 jbuf = (*env)->NewByteArray(env, dataLength);
852 (*env)->SetByteArrayRegion(env, jbuf, 0, dataLength, (jbyte*) data);
854 (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, jbuf, (jint) 0,
857 if ((*env)->ExceptionCheck(env))
859 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: Write Error!!!");
860 (*env)->ExceptionDescribe(env);
861 (*env)->ExceptionClear(env);
862 return CA_STATUS_FAILED;
865 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success");
869 (*env)->ExceptionDescribe(env);
870 (*env)->ExceptionClear(env);
871 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: error!!");
872 return CA_STATUS_FAILED;
877 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!");
883 CAResult_t CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id)
885 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect..");
887 if (!CAEDRNativeIsEnableBTAdapter(env))
889 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
890 return CA_STATUS_INVALID_PARAM;
893 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
894 if (!jni_cid_BTAdapter)
896 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null");
897 return CA_STATUS_FAILED;
901 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
903 METHODID_OBJECTNONPARAM);
904 if (!jni_mid_getDefaultAdapter)
906 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_getDefaultAdapter is null");
907 return CA_STATUS_FAILED;
910 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
911 jni_mid_getDefaultAdapter);
912 if (!jni_obj_BTAdapter)
914 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_BTAdapter is null");
915 return CA_STATUS_FAILED;
918 // get remote bluetooth device
919 jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter,
921 METHODID_BT_DEVICEPARAM);
922 if (!jni_mid_getRemoteDevice)
924 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null");
925 return CA_STATUS_FAILED;
928 jstring jni_address = (*env)->NewStringUTF(env, address);
929 jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
930 jni_mid_getRemoteDevice, jni_address);
931 if (!jni_obj_remoteBTDevice)
933 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null");
934 return CA_STATUS_FAILED;
937 // get create Rfcomm Socket method ID
938 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
939 if (!jni_cid_BluetoothDevice)
941 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null");
942 return CA_STATUS_FAILED;
945 jmethodID jni_mid_createSocket = (*env)->GetMethodID(
946 env, jni_cid_BluetoothDevice, "createInsecureRfcommSocketToServiceRecord",
947 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;");
948 if (!jni_mid_createSocket)
950 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_createSocket is null");
951 return CA_STATUS_FAILED;
955 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
958 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null");
959 return CA_STATUS_FAILED;
962 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
963 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
964 if (!jni_mid_fromString)
966 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_fromString is null");
967 return CA_STATUS_FAILED;
970 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
973 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_uuid is null");
974 return CA_STATUS_FAILED;
976 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
980 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null");
981 return CA_STATUS_FAILED;
984 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice,
985 jni_mid_createSocket, jni_obj_uuid);
986 if (!jni_obj_BTSocket)
988 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_BTSocket is null");
989 return CA_STATUS_FAILED;
993 jclass jni_cid_BTSocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET);
994 if (!jni_cid_BTSocket)
996 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null");
997 return CA_STATUS_FAILED;
1000 jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V");
1001 if (!jni_mid_connect)
1003 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_connect is null");
1004 return CA_STATUS_FAILED;
1007 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: initiating connection...");
1008 (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect);
1010 if ((*env)->ExceptionCheck(env))
1012 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: Connect is Failed!!!");
1013 (*env)->ExceptionDescribe(env);
1014 (*env)->ExceptionClear(env);
1015 return CA_STATUS_FAILED;
1018 // set socket to list
1019 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1022 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_socket is null");
1023 return CA_STATUS_FAILED;
1025 ca_mutex_lock(g_mutexObjectList);
1026 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1027 ca_mutex_unlock(g_mutexObjectList);
1030 ca_mutex_lock(g_mutexStateList);
1031 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1032 ca_mutex_unlock(g_mutexStateList);
1034 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: connected");
1036 return CA_STATUS_OK;
1039 void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id)
1042 jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
1043 if (!jni_cid_BTSocket)
1045 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
1049 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
1052 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null");
1056 jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address);
1057 if (!jni_obj_socket)
1059 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_obj_socket is not available");
1063 (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
1065 if ((*env)->ExceptionCheck(env))
1067 OIC_LOG(ERROR, TAG, "[EDR][Native] close: close is Failed!!!");
1068 (*env)->ExceptionDescribe(env);
1069 (*env)->ExceptionClear(env);
1073 // remove socket to list
1074 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
1077 ca_mutex_lock(g_mutexStateList);
1078 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
1079 ca_mutex_unlock(g_mutexStateList);
1081 OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
1084 void CAEDRInitializeClient(ca_thread_pool_t handle)
1086 OIC_LOG(DEBUG, TAG, "IN");
1087 CAEDRInitialize(handle);
1088 OIC_LOG(DEBUG, TAG, "OUT");
1091 void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback)
1093 g_edrErrorHandler = errorHandleCallback;