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"
35 #include "caremotehandler.h"
38 #define TAG PCF("CA_EDR_CLIENT")
40 static const char METHODID_CONTEXTNONPARAM[] = "()Landroid/content/Context;";
41 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
42 static const char METHODID_OUTPUTNONPARAM[] = "()Ljava/io/OutputStream;";
43 static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;";
44 static const char METHODID_BT_DEVICEPARAM[] =
45 "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;";
46 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
47 static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice";
48 static const char CLASSPATH_BT_INTERFACE[] = "org/iotivity/ca/CaEdrInterface";
49 static const char CLASSPATH_BT_SOCKET[] = "android/bluetooth/BluetoothSocket";
50 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
51 static const char CLASSPATH_CONTEXT[] = "android/content/Context";
52 static const char CLASSPATH_OUTPUT[] = "java/io/OutputStream";
54 static ca_thread_pool_t g_threadPoolHandle = NULL;
57 static jobject g_context;
60 * @var g_mutexUnicastServer
61 * @brief Mutex to synchronize unicast server
63 static ca_mutex g_mutexUnicastServer = NULL;
67 * @brief Flag to control the Receive Unicast Data Thread
69 static bool g_stopUnicast = false;
72 * @var g_mutexMulticastServer
73 * @brief Mutex to synchronize secure multicast server
75 static ca_mutex g_mutexMulticastServer = NULL;
78 * @var g_stopMulticast
79 * @brief Flag to control the Receive Multicast Data Thread
81 static bool g_stopMulticast = false;
85 * @brief Flag to control the Accept Thread
87 static bool g_stopAccept = false;
90 * @var g_mutexStateList
91 * @brief Mutex to synchronize device state list
93 static ca_mutex g_mutexStateList = NULL;
96 * @var g_mutexObjectList
97 * @brief Mutex to synchronize device object list
99 static ca_mutex g_mutexObjectList = NULL;
102 * @var g_edrErrorHandler
103 * @brief Error callback to update error in EDR
105 static CAEDRErrorHandleCallback g_edrErrorHandler = NULL;
107 typedef struct send_data
115 @brief Thread context information for unicast, multicast and secured unicast server
120 CAAdapterServerType_t type;
121 } CAAdapterReceiveThreadContext_t;
126 } CAAdapterAcceptThreadContext_t;
129 * implement for BT-EDR adapter common method
131 CAResult_t CAEDRGetInterfaceInformation(CAEndpoint_t **info)
133 OIC_LOG(DEBUG, TAG, "IN - CAEDRGetInterfaceInformation");
137 OIC_LOG(ERROR, TAG, "endpoint info is null");
138 return CA_STATUS_FAILED;
141 int32_t netInfoSize = 1;
143 char *macAddress = NULL;
144 CAResult_t ret = CAEDRGetInterfaceInfo(&macAddress);
145 OIC_LOG_V(ERROR, TAG, "address : %s", macAddress);
146 if (NULL == macAddress)
148 OIC_LOG(ERROR, TAG, "mac address is null");
150 return CA_STATUS_FAILED;
152 if (CA_STATUS_OK != ret)
154 OIC_LOG_V(ERROR, TAG, "Failed to get interface info [%d]", ret);
160 // Create local endpoint using util function
161 CAEndpoint_t *endpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_RFCOMM_BTEDR,
163 if (NULL == endpoint)
165 OIC_LOG(ERROR, TAG, "Failed to create Local Endpoint!");
167 return CA_STATUS_FAILED;
170 // copy unicast server information
171 CAEndpoint_t *netInfo = (CAEndpoint_t *)OICMalloc(sizeof(CAEndpoint_t) * netInfoSize);
174 OIC_LOG(ERROR, TAG, "Invalid input..");
176 CAFreeEndpoint(endpoint);
177 return CA_MEMORY_ALLOC_FAILED;
179 *netInfo = *endpoint;
183 CAFreeEndpoint(endpoint);
185 OIC_LOG(DEBUG, TAG, "OUT - CAEDRGetInterfaceInformation");
189 void CAEDRClientTerminate()
191 OIC_LOG(DEBUG, TAG, "IN");
193 OIC_LOG(DEBUG, TAG, "OUT");
196 CAResult_t CAEDRManagerReadData(void)
198 OIC_LOG(DEBUG, TAG, "IN");
200 OIC_LOG(DEBUG, TAG, "OUT");
201 return CA_NOT_SUPPORTED;
204 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
205 const void *data, uint32_t dataLength, uint32_t *sentLength)
207 OIC_LOG(DEBUG, TAG, "IN");
208 CAResult_t result = CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength);
209 OIC_LOG(DEBUG, TAG, "OUT");
213 CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data,
214 uint32_t dataLength, uint32_t *sentLength)
216 OIC_LOG(DEBUG, TAG, "IN");
217 CAResult_t result = CAEDRSendMulticastMessage((const char*) data, dataLength);
218 OIC_LOG(DEBUG, TAG, "OUT");
222 // It will be updated when android EDR support is added
223 void CAEDRClientUnsetCallbacks(void)
225 OIC_LOG(DEBUG, TAG, "IN");
227 OIC_LOG(DEBUG, TAG, "OUT");
230 // It will be updated when android EDR support is added
231 void CAEDRClientDisconnectAll(void)
233 OIC_LOG(DEBUG, TAG, "IN");
235 OIC_LOG(DEBUG, TAG, "OUT");
238 CAResult_t CAEDRGetAdapterEnableState(bool *state)
240 OIC_LOG(DEBUG, TAG, "IN");
243 OIC_LOG(ERROR, TAG, "g_jvm is null");
244 return CA_STATUS_INVALID_PARAM;
246 bool isAttached = false;
248 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
251 OIC_LOG(DEBUG, TAG, "CAEDRGetAdapterEnableState - Could not get JNIEnv pointer");
252 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
256 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
257 return CA_STATUS_INVALID_PARAM;
261 jboolean ret = CAEDRNativeIsEnableBTAdapter(env);
273 (*g_jvm)->DetachCurrentThread(g_jvm);
276 OIC_LOG(DEBUG, TAG, "OUT");
280 void CAEDRJniInitContext()
282 OIC_LOG(DEBUG, TAG, "CAEDRJniInitContext");
284 g_context = (jobject) CANativeJNIGetContext();
287 CAResult_t CAEDRCreateJNIInterfaceObject(jobject context)
290 OIC_LOG(DEBUG, TAG, "[EDRCore] CAEDRCreateJNIInterfaceObject");
292 if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
294 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get JNIEnv pointer");
295 return CA_STATUS_FAILED;
298 //getApplicationContext
299 jclass contextClass = (*env)->FindClass(env, CLASSPATH_CONTEXT);
302 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get context object class");
303 return CA_STATUS_FAILED;
306 jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
307 "getApplicationContext",
308 METHODID_CONTEXTNONPARAM);
309 if (!getApplicationContextMethod)
311 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get getApplicationContext method");
312 return CA_STATUS_FAILED;
315 //Create EDRJniInterface instance
316 jclass EDRJniInterface = (*env)->FindClass(env, CLASSPATH_BT_INTERFACE);
317 if (!EDRJniInterface)
319 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CaEdrInterface class");
320 return CA_STATUS_FAILED;
323 jmethodID EDRInterfaceConstructorMethod = (*env)->GetMethodID(env, EDRJniInterface, "<init>",
324 "(Landroid/content/Context;)V");
325 if (!EDRInterfaceConstructorMethod)
327 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CaEdrInterface constructor method");
328 return CA_STATUS_FAILED;
331 (*env)->NewObject(env, EDRJniInterface, EDRInterfaceConstructorMethod, context);
332 OIC_LOG(DEBUG, TAG, "[EDRCore] NewObject Success");
338 static void CAEDRDestroyMutex()
340 OIC_LOG(DEBUG, TAG, "IN");
342 if (g_mutexUnicastServer)
344 ca_mutex_free(g_mutexUnicastServer);
345 g_mutexUnicastServer = NULL;
348 if (g_mutexMulticastServer)
350 ca_mutex_free(g_mutexMulticastServer);
351 g_mutexMulticastServer = NULL;
354 if (g_mutexStateList)
356 ca_mutex_free(g_mutexStateList);
357 g_mutexStateList = NULL;
360 if (g_mutexObjectList)
362 ca_mutex_free(g_mutexObjectList);
363 g_mutexObjectList = NULL;
365 OIC_LOG(DEBUG, TAG, "OUT");
368 static CAResult_t CAEDRCreateMutex()
370 OIC_LOG(DEBUG, TAG, "IN");
372 g_mutexUnicastServer = ca_mutex_new();
373 if (!g_mutexUnicastServer)
375 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
376 return CA_STATUS_FAILED;
379 g_mutexMulticastServer = ca_mutex_new();
380 if (!g_mutexMulticastServer)
382 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
385 return CA_STATUS_FAILED;
388 g_mutexStateList = ca_mutex_new();
389 if (!g_mutexStateList)
391 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
394 return CA_STATUS_FAILED;
397 g_mutexObjectList = ca_mutex_new();
398 if (!g_mutexObjectList)
400 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
403 return CA_STATUS_FAILED;
406 OIC_LOG(DEBUG, TAG, "OUT");
410 void CAEDRInitialize(ca_thread_pool_t handle)
412 OIC_LOG(DEBUG, TAG, "CAEDRInitialize");
414 g_threadPoolHandle = handle;
418 CAEDRJniInitContext();
423 bool isAttached = false;
425 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
428 OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
429 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
433 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
438 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
441 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
442 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
443 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
446 ca_mutex_lock(g_mutexStateList);
447 CAEDRNativeCreateDeviceStateList();
448 ca_mutex_unlock(g_mutexStateList);
450 ca_mutex_lock(g_mutexObjectList);
451 CAEDRNativeCreateDeviceSocketList();
452 ca_mutex_unlock(g_mutexObjectList);
456 (*g_jvm)->DetachCurrentThread(g_jvm);
461 CAEDRCreateJNIInterfaceObject(g_context); /* create java CaEdrInterface instance*/
464 OIC_LOG(DEBUG, TAG, "OUT");
467 void CAEDRTerminate()
469 OIC_LOG(DEBUG, TAG, "CAEDRTerminate");
471 bool isAttached = false;
473 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
476 OIC_LOG(DEBUG, TAG, "CAEDRTerminate - Could not get JNIEnv pointer");
477 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
481 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
488 g_stopMulticast = true;
489 g_stopUnicast = true;
493 (*g_jvm)->DetachCurrentThread(g_jvm);
498 (*env)->DeleteGlobalRef(env, g_context);
501 CAEDRNativeSocketCloseToAll(env);
506 CAEDRNativeRemoveAllDeviceState();
507 CAEDRNativeRemoveAllDeviceSocket(env);
510 void CAEDRCoreJniInit()
512 OIC_LOG(DEBUG, TAG, "CAEdrClientJniInit");
513 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
516 CAResult_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
518 OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data);
520 CAResult_t result = CAEDRSendUnicastMessageImpl(address, data, dataLen);
524 CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
526 OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage(%s)", data);
528 bool isAttached = false;
530 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
533 OIC_LOG(DEBUG, TAG, "CAEDRSendMulticastMessage - Could not get JNIEnv pointer");
534 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
538 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
539 return CA_STATUS_INVALID_PARAM;
544 CAResult_t result = CAEDRSendMulticastMessageImpl(env, data, dataLen);
545 if(CA_STATUS_OK != result)
547 OIC_LOG(ERROR, TAG, "CAEDRSendMulticastMessage - could not send multicast message");
551 OIC_LOG(DEBUG, TAG, "sent data");
555 OIC_LOG(DEBUG, TAG, "DetachCurrentThread");
556 (*g_jvm)->DetachCurrentThread(g_jvm);
559 OIC_LOG(DEBUG, TAG, "OUT - CAEDRSendMulticastMessage");
563 CAResult_t CAEDRGetInterfaceInfo(char **address)
565 CAEDRGetLocalAddress(address);
569 void CAEDRGetLocalAddress(char **address)
571 bool isAttached = false;
573 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
576 OIC_LOG(DEBUG, TAG, "CAEDRGetLocalAddress - Could not get JNIEnv pointer");
577 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
580 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
586 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
589 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
590 *address = OICStrdup(localAddress);
591 if (*address == NULL)
595 (*g_jvm)->DetachCurrentThread(g_jvm);
600 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
603 OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
606 (*g_jvm)->DetachCurrentThread(g_jvm);
610 CAResult_t CAEDRSendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen)
612 OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessageImpl, address: %s, data: %s", address, data);
614 bool isAttached = false;
616 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
619 OIC_LOG(DEBUG, TAG, "CAEDRSendUnicastMessageImpl - Could not get JNIEnv pointer");
620 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
623 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
624 return CA_STATUS_INVALID_PARAM;
629 OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data");
631 // get bonded device list
632 jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
633 if (!jni_arrayPairedDevices)
635 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
638 (*g_jvm)->DetachCurrentThread(g_jvm);
640 return CA_STATUS_INVALID_PARAM;
642 // Get information from array of devices
643 jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
644 jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName",
645 METHODID_STRINGNONPARAM);
646 jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress",
647 METHODID_STRINGNONPARAM);
649 jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
651 for (i = 0; i < length; i++)
653 OIC_LOG(DEBUG, TAG, "[EDR][Native] start to check device");
654 // get name, address from BT device
655 jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
656 jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
660 const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
661 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
662 (*env)->ReleaseStringUTFChars(env, j_str_name, name);
665 jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
666 const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
667 OIC_LOG_V(DEBUG, TAG,
668 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
672 OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
675 (*g_jvm)->DetachCurrentThread(g_jvm);
677 return CA_STATUS_INVALID_PARAM;
681 OIC_LOG(ERROR, TAG, "[EDR][Native] address is null");
684 (*g_jvm)->DetachCurrentThread(g_jvm);
686 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
687 return CA_STATUS_INVALID_PARAM;
690 if (!strcmp(remoteAddress, address))
692 CAResult_t res = CAEDRNativeSendData(env, remoteAddress, data, dataLen, i);
693 if (CA_STATUS_OK != res)
695 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
699 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
704 (*g_jvm)->DetachCurrentThread(g_jvm);
710 CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
712 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
714 // get bonded device list
715 jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
716 if (!jni_arrayPairedDevices)
718 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
719 return CA_STATUS_INVALID_PARAM;
721 // Get information from array of devices
722 jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
723 jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName",
724 METHODID_STRINGNONPARAM);
725 jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress",
726 METHODID_STRINGNONPARAM);
728 jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
730 for (i = 0; i < length; i++)
732 // get name, address from BT device
733 jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
734 jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
738 const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
739 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
740 (*env)->ReleaseStringUTFChars(env, j_str_name, name);
743 jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
744 const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
745 OIC_LOG_V(DEBUG, TAG,
746 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
749 CAResult_t res = CAEDRNativeSendData(env, remoteAddress, data, dataLen, i);
750 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
751 if (CA_STATUS_OK != res)
753 OIC_LOG_V(ERROR, TAG, "CASendMulticastMessageImpl, failed to send message to : %s",
755 g_edrErrorHandler(remoteAddress, OIC_EDR_SERVICE_ID, data, dataLen, res);
766 CAResult_t CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data,
767 uint32_t dataLength, uint32_t id)
769 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData logic start : %s, %d", data, dataLength);
771 if (!CAEDRNativeIsEnableBTAdapter(env))
773 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
774 return CA_STATUS_INVALID_PARAM;
777 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
779 // connect before send data
780 OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data");
784 OIC_LOG(ERROR, TAG, "[EDR][Native] remote address is empty");
785 return CA_STATUS_INVALID_PARAM;
789 CAResult_t res = CAEDRNativeConnect(env, address, id);
790 if (CA_STATUS_OK != res)
797 if (STATE_CONNECTED == CAEDRIsConnectedDevice(address))
799 if (!((*env)->ExceptionCheck(env)))
801 jclass jni_cid_BTsocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET);
802 if (!jni_cid_BTsocket)
804 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null");
805 return CA_STATUS_FAILED;
808 jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
810 METHODID_OUTPUTNONPARAM);
811 if (!jni_mid_getOutputStream)
813 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null");
814 return CA_STATUS_FAILED;
817 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream");
819 jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address);
822 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_socket is not available");
823 return CA_STATUS_FAILED;
826 jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
827 jni_mid_getOutputStream);
828 if (!jni_obj_outputStream)
830 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null");
831 return CA_STATUS_FAILED;
834 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream..");
836 jclass jni_cid_OutputStream = (*env)->FindClass(env, CLASSPATH_OUTPUT);
837 if (!jni_cid_OutputStream)
839 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null");
840 return CA_STATUS_FAILED;
843 jmethodID jni_mid_write = (*env)->GetMethodID(env, jni_cid_OutputStream, "write",
847 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_write is null");
848 return CA_STATUS_FAILED;
852 jbuf = (*env)->NewByteArray(env, dataLength);
853 (*env)->SetByteArrayRegion(env, jbuf, 0, dataLength, (jbyte*) data);
855 (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, jbuf, (jint) 0,
858 if ((*env)->ExceptionCheck(env))
860 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: Write Error!!!");
861 (*env)->ExceptionDescribe(env);
862 (*env)->ExceptionClear(env);
863 return CA_STATUS_FAILED;
866 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success");
870 (*env)->ExceptionDescribe(env);
871 (*env)->ExceptionClear(env);
872 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: error!!");
873 return CA_STATUS_FAILED;
878 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!");
884 CAResult_t CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id)
886 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect..");
888 if (!CAEDRNativeIsEnableBTAdapter(env))
890 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
891 return CA_STATUS_INVALID_PARAM;
894 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
895 if (!jni_cid_BTAdapter)
897 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null");
898 return CA_STATUS_FAILED;
902 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
904 METHODID_OBJECTNONPARAM);
905 if (!jni_mid_getDefaultAdapter)
907 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_getDefaultAdapter is null");
908 return CA_STATUS_FAILED;
911 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
912 jni_mid_getDefaultAdapter);
913 if (!jni_obj_BTAdapter)
915 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_BTAdapter is null");
916 return CA_STATUS_FAILED;
919 // get remote bluetooth device
920 jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter,
922 METHODID_BT_DEVICEPARAM);
923 if (!jni_mid_getRemoteDevice)
925 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null");
926 return CA_STATUS_FAILED;
929 jstring jni_address = (*env)->NewStringUTF(env, address);
930 jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
931 jni_mid_getRemoteDevice, jni_address);
932 if (!jni_obj_remoteBTDevice)
934 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null");
935 return CA_STATUS_FAILED;
938 // get create Rfcomm Socket method ID
939 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
940 if (!jni_cid_BluetoothDevice)
942 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null");
943 return CA_STATUS_FAILED;
946 jmethodID jni_mid_createSocket = (*env)->GetMethodID(
947 env, jni_cid_BluetoothDevice, "createInsecureRfcommSocketToServiceRecord",
948 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;");
949 if (!jni_mid_createSocket)
951 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_createSocket is null");
952 return CA_STATUS_FAILED;
956 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
959 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null");
960 return CA_STATUS_FAILED;
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, "[EDR][Native] btConnect: jni_mid_fromString is null");
968 return CA_STATUS_FAILED;
971 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
974 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_uuid is null");
975 return CA_STATUS_FAILED;
977 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
981 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null");
982 return CA_STATUS_FAILED;
985 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice,
986 jni_mid_createSocket, jni_obj_uuid);
987 if (!jni_obj_BTSocket)
989 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_BTSocket is null");
990 return CA_STATUS_FAILED;
994 jclass jni_cid_BTSocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET);
995 if (!jni_cid_BTSocket)
997 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null");
998 return CA_STATUS_FAILED;
1001 jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V");
1002 if (!jni_mid_connect)
1004 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_connect is null");
1005 return CA_STATUS_FAILED;
1008 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: initiating connection...");
1009 (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect);
1011 if ((*env)->ExceptionCheck(env))
1013 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: Connect is Failed!!!");
1014 (*env)->ExceptionDescribe(env);
1015 (*env)->ExceptionClear(env);
1016 return CA_STATUS_FAILED;
1019 // set socket to list
1020 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1023 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_socket is null");
1024 return CA_STATUS_FAILED;
1026 ca_mutex_lock(g_mutexObjectList);
1027 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1028 ca_mutex_unlock(g_mutexObjectList);
1031 ca_mutex_lock(g_mutexStateList);
1032 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1033 ca_mutex_unlock(g_mutexStateList);
1035 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: connected");
1037 return CA_STATUS_OK;
1040 void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id)
1043 jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
1044 if (!jni_cid_BTSocket)
1046 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
1050 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
1053 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null");
1057 jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address);
1058 if (!jni_obj_socket)
1060 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_obj_socket is not available");
1064 (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
1066 if ((*env)->ExceptionCheck(env))
1068 OIC_LOG(ERROR, TAG, "[EDR][Native] close: close is Failed!!!");
1069 (*env)->ExceptionDescribe(env);
1070 (*env)->ExceptionClear(env);
1074 // remove socket to list
1075 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
1078 ca_mutex_lock(g_mutexStateList);
1079 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
1080 ca_mutex_unlock(g_mutexStateList);
1082 OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
1085 void CAEDRInitializeClient(ca_thread_pool_t handle)
1087 OIC_LOG(DEBUG, TAG, "IN");
1088 CAEDRInitialize(handle);
1089 OIC_LOG(DEBUG, TAG, "OUT");
1092 void CAEDRSetErrorHandler(CAEDRErrorHandleCallback errorHandleCallback)
1094 g_edrErrorHandler = errorHandleCallback;