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 "cathreadpool.h" /* for thread pool */
32 #include "uarraylist.h"
33 #include "caadapterutils.h"
36 #define TAG PCF("CA_EDR_CLIENT")
38 static const char METHODID_CONTEXTNONPARAM[] = "()Landroid/content/Context;";
39 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
40 static const char METHODID_OUTPUTNONPARAM[] = "()Ljava/io/OutputStream;";
41 static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;";
42 static const char METHODID_BT_DEVICEPARAM[] =
43 "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;";
44 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
45 static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice";
46 static const char CLASSPATH_BT_INTERFACE[] = "org/iotivity/ca/CaEdrInterface";
47 static const char CLASSPATH_BT_SOCKET[] = "android/bluetooth/BluetoothSocket";
48 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
49 static const char CLASSPATH_CONTEXT[] = "android/content/Context";
50 static const char CLASSPATH_OUTPUT[] = "java/io/OutputStream";
52 static ca_thread_pool_t g_threadPoolHandle = NULL;
55 static jobject g_context;
58 * @var g_mutexUnicastServer
59 * @brief Mutex to synchronize unicast server
61 static ca_mutex g_mutexUnicastServer = NULL;
65 * @brief Flag to control the Receive Unicast Data Thread
67 static bool g_stopUnicast = false;
70 * @var g_mutexMulticastServer
71 * @brief Mutex to synchronize secure multicast server
73 static ca_mutex g_mutexMulticastServer = NULL;
76 * @var g_stopMulticast
77 * @brief Flag to control the Receive Multicast Data Thread
79 static bool g_stopMulticast = false;
83 * @brief Flag to control the Accept Thread
85 static bool g_stopAccept = false;
88 * @var g_mutexStateList
89 * @brief Mutex to synchronize device state list
91 static ca_mutex g_mutexStateList = NULL;
94 * @var g_mutexObjectList
95 * @brief Mutex to synchronize device object list
97 static ca_mutex g_mutexObjectList = NULL;
99 typedef struct send_data
107 @brief Thread context information for unicast, multicast and secured unicast server
112 CAAdapterServerType_t type;
113 } CAAdapterReceiveThreadContext_t;
118 } CAAdapterAcceptThreadContext_t;
121 * implement for BT-EDR adapter common method
123 CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
125 OIC_LOG(DEBUG, TAG, "IN - CAEDRGetInterfaceInformation");
129 OIC_LOG(ERROR, TAG, "LocalConnectivity info is null");
130 return CA_STATUS_FAILED;
133 int32_t netInfoSize = 1;
135 char *macAddress = NULL;
136 CAResult_t ret = CAEDRGetInterfaceInfo(&macAddress);
137 OIC_LOG_V(ERROR, TAG, "address : %s", macAddress);
138 if (NULL == macAddress)
140 OIC_LOG(ERROR, TAG, "mac address is null");
142 return CA_STATUS_FAILED;
144 if (CA_STATUS_OK != ret)
146 OIC_LOG_V(ERROR, TAG, "Failed to get interface info [%d]", ret);
152 // Create local endpoint using util function
153 CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_EDR, macAddress);
154 if (NULL == endpoint)
156 OIC_LOG(ERROR, TAG, "Failed to create Local Endpoint!");
158 return CA_STATUS_FAILED;
161 // copy unicast server information
162 endpoint->isSecured = false;
163 CALocalConnectivity_t *netInfo = (CALocalConnectivity_t *) OICMalloc(
164 sizeof(CALocalConnectivity_t) * netInfoSize);
167 OIC_LOG(ERROR, TAG, "Invalid input..");
169 CAAdapterFreeLocalEndpoint(endpoint);
170 return CA_MEMORY_ALLOC_FAILED;
172 memcpy(netInfo, endpoint, sizeof(CALocalConnectivity_t));
176 CAAdapterFreeLocalEndpoint(endpoint);
178 OIC_LOG(DEBUG, TAG, "OUT - CAEDRGetInterfaceInformation");
182 void CAEDRClientTerminate()
184 OIC_LOG(DEBUG, TAG, "IN");
186 OIC_LOG(DEBUG, TAG, "OUT");
189 CAResult_t CAEDRManagerReadData(void)
191 OIC_LOG(DEBUG, TAG, "IN");
193 OIC_LOG(DEBUG, TAG, "OUT");
194 return CA_NOT_SUPPORTED;
197 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
198 const void *data, uint32_t dataLength, uint32_t *sentLength)
200 OIC_LOG(DEBUG, TAG, "IN");
201 CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength);
202 OIC_LOG(DEBUG, TAG, "OUT");
206 CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data,
207 uint32_t dataLength, uint32_t *sentLength)
209 OIC_LOG(DEBUG, TAG, "IN");
210 CAEDRSendMulticastMessage((const char*) data, dataLength);
211 OIC_LOG(DEBUG, TAG, "OUT");
215 // It will be updated when android EDR support is added
216 void CAEDRClientUnsetCallbacks(void)
218 OIC_LOG(DEBUG, TAG, "IN");
220 OIC_LOG(DEBUG, TAG, "OUT");
223 // It will be updated when android EDR support is added
224 void CAEDRClientDisconnectAll(void)
226 OIC_LOG(DEBUG, TAG, "IN");
228 OIC_LOG(DEBUG, TAG, "OUT");
231 CAResult_t CAEDRGetAdapterEnableState(bool *state)
233 OIC_LOG(DEBUG, TAG, "IN");
236 OIC_LOG(ERROR, TAG, "g_jvm is null");
237 return CA_STATUS_INVALID_PARAM;
239 bool isAttached = false;
241 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
244 OIC_LOG(DEBUG, TAG, "CAEDRGetAdapterEnableState - Could not get JNIEnv pointer");
245 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
249 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
250 return CA_STATUS_INVALID_PARAM;
254 jboolean ret = CAEDRNativeIsEnableBTAdapter(env);
266 (*g_jvm)->DetachCurrentThread(g_jvm);
269 OIC_LOG(DEBUG, TAG, "OUT");
273 void CAEDRJniInitContext()
275 OIC_LOG(DEBUG, TAG, "CAEDRJniInitContext");
277 g_context = (jobject) CANativeJNIGetContext();
280 CAResult_t CAEDRCreateJNIInterfaceObject(jobject context)
283 OIC_LOG(DEBUG, TAG, "[EDRCore] CAEDRCreateJNIInterfaceObject");
285 if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
287 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get JNIEnv pointer");
288 return CA_STATUS_FAILED;
291 //getApplicationContext
292 jclass contextClass = (*env)->FindClass(env, CLASSPATH_CONTEXT);
295 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get context object class");
296 return CA_STATUS_FAILED;
299 jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
300 "getApplicationContext",
301 METHODID_CONTEXTNONPARAM);
302 if (!getApplicationContextMethod)
304 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get getApplicationContext method");
305 return CA_STATUS_FAILED;
308 //Create EDRJniInterface instance
309 jclass EDRJniInterface = (*env)->FindClass(env, CLASSPATH_BT_INTERFACE);
310 if (!EDRJniInterface)
312 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CaEdrInterface class");
313 return CA_STATUS_FAILED;
316 jmethodID EDRInterfaceConstructorMethod = (*env)->GetMethodID(env, EDRJniInterface, "<init>",
317 "(Landroid/content/Context;)V");
318 if (!EDRInterfaceConstructorMethod)
320 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CaEdrInterface constructor method");
321 return CA_STATUS_FAILED;
324 (*env)->NewObject(env, EDRJniInterface, EDRInterfaceConstructorMethod, context);
325 OIC_LOG(DEBUG, TAG, "[EDRCore] NewObject Success");
331 static void CAEDRDestroyMutex()
333 OIC_LOG(DEBUG, TAG, "IN");
335 if (g_mutexUnicastServer)
337 ca_mutex_free(g_mutexUnicastServer);
338 g_mutexUnicastServer = NULL;
341 if (g_mutexMulticastServer)
343 ca_mutex_free(g_mutexMulticastServer);
344 g_mutexMulticastServer = 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;
358 OIC_LOG(DEBUG, TAG, "OUT");
361 static CAResult_t CAEDRCreateMutex()
363 OIC_LOG(DEBUG, TAG, "IN");
365 g_mutexUnicastServer = ca_mutex_new();
366 if (!g_mutexUnicastServer)
368 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
369 return CA_STATUS_FAILED;
372 g_mutexMulticastServer = ca_mutex_new();
373 if (!g_mutexMulticastServer)
375 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
378 return CA_STATUS_FAILED;
381 g_mutexStateList = ca_mutex_new();
382 if (!g_mutexStateList)
384 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
387 return CA_STATUS_FAILED;
390 g_mutexObjectList = ca_mutex_new();
391 if (!g_mutexObjectList)
393 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
396 return CA_STATUS_FAILED;
399 OIC_LOG(DEBUG, TAG, "OUT");
403 void CAEDRInitialize(ca_thread_pool_t handle)
405 OIC_LOG(DEBUG, TAG, "CAEDRInitialize");
407 g_threadPoolHandle = handle;
411 CAEDRJniInitContext();
416 bool isAttached = false;
418 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
421 OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
422 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
426 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
431 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
434 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
435 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
436 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
439 ca_mutex_lock(g_mutexStateList);
440 CAEDRNativeCreateDeviceStateList();
441 ca_mutex_unlock(g_mutexStateList);
443 ca_mutex_lock(g_mutexObjectList);
444 CAEDRNativeCreateDeviceSocketList();
445 ca_mutex_unlock(g_mutexObjectList);
449 (*g_jvm)->DetachCurrentThread(g_jvm);
454 CAEDRCreateJNIInterfaceObject(g_context); /* create java CaEdrInterface instance*/
457 OIC_LOG(DEBUG, TAG, "OUT");
460 void CAEDRTerminate()
462 OIC_LOG(DEBUG, TAG, "CAEDRTerminate");
464 bool isAttached = false;
466 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
469 OIC_LOG(DEBUG, TAG, "CAEDRTerminate - Could not get JNIEnv pointer");
470 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
474 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
481 g_stopMulticast = true;
482 g_stopUnicast = true;
486 (*g_jvm)->DetachCurrentThread(g_jvm);
491 (*env)->DeleteGlobalRef(env, g_context);
494 CAEDRNativeSocketCloseToAll(env);
499 CAEDRNativeRemoveAllDeviceState();
500 CAEDRNativeRemoveAllDeviceSocket(env);
503 void CAEDRCoreJniInit()
505 OIC_LOG(DEBUG, TAG, "CAEdrClientJniInit");
506 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
509 CAResult_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
511 OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data);
513 CAEDRSendUnicastMessageImpl(address, data, dataLen);
517 CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
519 OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage(%s)", data);
521 bool isAttached = false;
523 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
526 OIC_LOG(DEBUG, TAG, "CAEDRSendMulticastMessage - Could not get JNIEnv pointer");
527 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
531 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
532 return CA_STATUS_INVALID_PARAM;
537 CAEDRSendMulticastMessageImpl(env, data, dataLen);
539 OIC_LOG(DEBUG, TAG, "sent data");
543 OIC_LOG(DEBUG, TAG, "DetachCurrentThread");
544 (*g_jvm)->DetachCurrentThread(g_jvm);
547 OIC_LOG(DEBUG, TAG, "OUT - CAEDRSendMulticastMessage");
551 CAResult_t CAEDRGetInterfaceInfo(char **address)
553 CAEDRGetLocalAddress(address);
557 void CAEDRGetLocalAddress(char **address)
559 bool isAttached = false;
561 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
564 OIC_LOG(DEBUG, TAG, "CAEDRGetLocalAddress - Could not get JNIEnv pointer");
565 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
568 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
574 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
577 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
578 *address = (char*) OICMalloc(strlen(localAddress) + 1);
579 if (*address == NULL)
583 (*g_jvm)->DetachCurrentThread(g_jvm);
587 memcpy(*address, localAddress, strlen(localAddress));
588 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
591 OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
594 (*g_jvm)->DetachCurrentThread(g_jvm);
598 CAResult_t CAEDRSendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen)
600 OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessageImpl, address: %s, data: %s", address, data);
602 bool isAttached = false;
604 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
607 OIC_LOG(DEBUG, TAG, "CAEDRSendUnicastMessageImpl - Could not get JNIEnv pointer");
608 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
611 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
612 return CA_STATUS_INVALID_PARAM;
617 OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data");
619 // get bonded device list
620 jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
621 if (!jni_arrayPairedDevices)
623 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
626 (*g_jvm)->DetachCurrentThread(g_jvm);
628 return CA_STATUS_INVALID_PARAM;
630 // Get information from array of devices
631 jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
632 jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName",
633 METHODID_STRINGNONPARAM);
634 jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress",
635 METHODID_STRINGNONPARAM);
637 jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
639 for (i = 0; i < length; i++)
641 OIC_LOG(DEBUG, TAG, "[EDR][Native] start to check device");
642 // get name, address from BT device
643 jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
644 jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
648 const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
649 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
650 (*env)->ReleaseStringUTFChars(env, j_str_name, name);
653 jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
654 const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
655 OIC_LOG_V(DEBUG, TAG,
656 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
660 OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
663 (*g_jvm)->DetachCurrentThread(g_jvm);
665 return CA_STATUS_INVALID_PARAM;
669 OIC_LOG(ERROR, TAG, "[EDR][Native] address is null");
672 (*g_jvm)->DetachCurrentThread(g_jvm);
674 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
675 return CA_STATUS_INVALID_PARAM;
678 if (!strcmp(remoteAddress, address))
680 CAResult_t res = CAEDRNativeSendData(env, remoteAddress, data, dataLen, i);
681 if (CA_STATUS_OK != res)
683 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
687 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
692 (*g_jvm)->DetachCurrentThread(g_jvm);
698 CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
700 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
702 // get bonded device list
703 jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
704 if (!jni_arrayPairedDevices)
706 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
707 return CA_STATUS_INVALID_PARAM;
709 // Get information from array of devices
710 jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
711 jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName",
712 METHODID_STRINGNONPARAM);
713 jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress",
714 METHODID_STRINGNONPARAM);
716 jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
718 for (i = 0; i < length; i++)
720 // get name, address from BT device
721 jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
722 jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
726 const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
727 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
728 (*env)->ReleaseStringUTFChars(env, j_str_name, name);
731 jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
732 const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
733 OIC_LOG_V(DEBUG, TAG,
734 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
737 CAResult_t res = CAEDRNativeSendData(env, remoteAddress, data, dataLen, i);
738 (*env)->ReleaseStringUTFChars(env, j_str_address, remoteAddress);
739 if (CA_STATUS_OK != res)
751 CAResult_t CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data,
752 uint32_t dataLength, uint32_t id)
754 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData logic start : %s, %d", data, dataLength);
756 if (!CAEDRNativeIsEnableBTAdapter(env))
758 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
759 return CA_STATUS_INVALID_PARAM;
762 if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
764 // connect before send data
765 OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data");
769 OIC_LOG(ERROR, TAG, "[EDR][Native] remote address is empty");
770 return CA_STATUS_INVALID_PARAM;
774 CAResult_t res = CAEDRNativeConnect(env, address, id);
775 if (CA_STATUS_OK != res)
782 if (STATE_CONNECTED == CAEDRIsConnectedDevice(address))
784 if (!((*env)->ExceptionCheck(env)))
786 jclass jni_cid_BTsocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET);
787 if (!jni_cid_BTsocket)
789 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null");
790 return CA_STATUS_FAILED;
793 jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
795 METHODID_OUTPUTNONPARAM);
796 if (!jni_mid_getOutputStream)
798 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null");
799 return CA_STATUS_FAILED;
802 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream");
804 jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address);
807 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_socket is not available");
808 return CA_STATUS_FAILED;
811 jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
812 jni_mid_getOutputStream);
813 if (!jni_obj_outputStream)
815 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null");
816 return CA_STATUS_FAILED;
819 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream..");
821 jclass jni_cid_OutputStream = (*env)->FindClass(env, CLASSPATH_OUTPUT);
822 if (!jni_cid_OutputStream)
824 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null");
825 return CA_STATUS_FAILED;
828 jmethodID jni_mid_write = (*env)->GetMethodID(env, jni_cid_OutputStream, "write",
832 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_write is null");
833 return CA_STATUS_FAILED;
837 jbuf = (*env)->NewByteArray(env, dataLength);
838 (*env)->SetByteArrayRegion(env, jbuf, 0, dataLength, (jbyte*) data);
840 (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, jbuf, (jint) 0,
843 if ((*env)->ExceptionCheck(env))
845 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: Write Error!!!");
846 (*env)->ExceptionDescribe(env);
847 (*env)->ExceptionClear(env);
848 return CA_STATUS_FAILED;
851 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success");
855 (*env)->ExceptionDescribe(env);
856 (*env)->ExceptionClear(env);
857 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: error!!");
858 return CA_STATUS_FAILED;
863 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!");
869 CAResult_t CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id)
871 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect..");
873 if (!CAEDRNativeIsEnableBTAdapter(env))
875 OIC_LOG(ERROR, TAG, "BT adpater is not enable");
876 return CA_STATUS_INVALID_PARAM;
879 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
880 if (!jni_cid_BTAdapter)
882 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null");
883 return CA_STATUS_FAILED;
887 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
889 METHODID_OBJECTNONPARAM);
890 if (!jni_mid_getDefaultAdapter)
892 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_getDefaultAdapter is null");
893 return CA_STATUS_FAILED;
896 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
897 jni_mid_getDefaultAdapter);
898 if (!jni_obj_BTAdapter)
900 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_BTAdapter is null");
901 return CA_STATUS_FAILED;
904 // get remote bluetooth device
905 jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter,
907 METHODID_BT_DEVICEPARAM);
908 if (!jni_mid_getRemoteDevice)
910 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null");
911 return CA_STATUS_FAILED;
914 jstring jni_address = (*env)->NewStringUTF(env, address);
915 jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
916 jni_mid_getRemoteDevice, jni_address);
917 if (!jni_obj_remoteBTDevice)
919 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null");
920 return CA_STATUS_FAILED;
923 // get create Rfcomm Socket method ID
924 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
925 if (!jni_cid_BluetoothDevice)
927 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null");
928 return CA_STATUS_FAILED;
931 jmethodID jni_mid_createSocket = (*env)->GetMethodID(
932 env, jni_cid_BluetoothDevice, "createInsecureRfcommSocketToServiceRecord",
933 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;");
934 if (!jni_mid_createSocket)
936 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_createSocket is null");
937 return CA_STATUS_FAILED;
941 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
944 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null");
945 return CA_STATUS_FAILED;
948 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
949 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
950 if (!jni_mid_fromString)
952 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_fromString is null");
953 return CA_STATUS_FAILED;
956 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
959 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_uuid is null");
960 return CA_STATUS_FAILED;
962 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
966 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null");
967 return CA_STATUS_FAILED;
970 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice,
971 jni_mid_createSocket, jni_obj_uuid);
972 if (!jni_obj_BTSocket)
974 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_obj_BTSocket is null");
975 return CA_STATUS_FAILED;
979 jclass jni_cid_BTSocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET);
980 if (!jni_cid_BTSocket)
982 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null");
983 return CA_STATUS_FAILED;
986 jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V");
987 if (!jni_mid_connect)
989 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_mid_connect is null");
990 return CA_STATUS_FAILED;
993 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: initiating connection...");
994 (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect);
996 if ((*env)->ExceptionCheck(env))
998 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: Connect is Failed!!!");
999 (*env)->ExceptionDescribe(env);
1000 (*env)->ExceptionClear(env);
1001 return CA_STATUS_FAILED;
1004 // set socket to list
1005 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1008 OIC_LOG(ERROR, TAG, "[EDR][Native] btConnect: jni_socket is null");
1009 return CA_STATUS_FAILED;
1011 ca_mutex_lock(g_mutexObjectList);
1012 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1013 ca_mutex_unlock(g_mutexObjectList);
1016 ca_mutex_lock(g_mutexStateList);
1017 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1018 ca_mutex_unlock(g_mutexStateList);
1020 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: connected");
1022 return CA_STATUS_OK;
1025 void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id)
1028 jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
1029 if (!jni_cid_BTSocket)
1031 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
1035 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
1038 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null");
1042 jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address);
1043 if (!jni_obj_socket)
1045 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_obj_socket is not available");
1049 (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
1051 if ((*env)->ExceptionCheck(env))
1053 OIC_LOG(ERROR, TAG, "[EDR][Native] close: close is Failed!!!");
1054 (*env)->ExceptionDescribe(env);
1055 (*env)->ExceptionClear(env);
1059 // remove socket to list
1060 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
1063 ca_mutex_lock(g_mutexStateList);
1064 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
1065 ca_mutex_unlock(g_mutexStateList);
1067 OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
1070 void CAEDRInitializeClient(ca_thread_pool_t handle)
1072 OIC_LOG(DEBUG, TAG, "IN");
1073 CAEDRInitialize(handle);
1074 OIC_LOG(DEBUG, TAG, "OUT");