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"
28 #include "caleserver.h"
30 #include "oic_malloc.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_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;";
40 static const char *METHODID_STRINGNONPARAM = "()Ljava/lang/String;";
41 static const char *CLASSPATH_BT_ADPATER = "android/bluetooth/BluetoothAdapter";
42 static const char *CLASSPATH_BT_UUID = "java/util/UUID";
44 static const uint32_t MAX_PDU_BUFFER = 1024;
46 static u_arraylist_t *g_deviceStateList = NULL;
47 static u_arraylist_t *g_deviceObjectList = NULL;
49 static ca_thread_pool_t g_threadPoolHandle = NULL;
52 static jobject g_context;
54 static jbyteArray g_sendBuffer;
57 * @var g_mutexSocketListManager
58 * @brief Mutex to synchronize socket list update
60 static ca_mutex g_mutexSocketListManager;
62 // server socket instance
63 static jobject g_serverSocketObject = NULL;
66 * @var g_mutexUnicastServer
67 * @brief Mutex to synchronize unicast server
69 static ca_mutex g_mutexUnicastServer = NULL;
73 * @brief Flag to control the Receive Unicast Data Thread
75 static bool g_stopUnicast = false;
78 * @var g_mutexMulticastServer
79 * @brief Mutex to synchronize secure multicast server
81 static ca_mutex g_mutexMulticastServer = NULL;
84 * @var g_stopMulticast
85 * @brief Flag to control the Receive Multicast Data Thread
87 static bool g_stopMulticast = false;
91 * @brief Flag to control the Accept Thread
93 static bool g_stopAccept = false;
95 typedef struct send_data {
102 @brief Thread context information for unicast, multicast and secured unicast server
107 CAAdapterServerType_t type;
108 } CAAdapterReceiveThreadContext_t;
113 } CAAdapterAcceptThreadContext_t;
116 // TODO: It will be updated when android EDR support is added
117 CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
119 OIC_LOG(DEBUG, TAG, "IN");
121 OIC_LOG(DEBUG, TAG, "OUT");
125 void CAEDRClientTerminate()
127 OIC_LOG(DEBUG, TAG, "IN");
129 OIC_LOG(DEBUG, TAG, "OUT");
132 CAResult_t CAEDRManagerReadData(void)
134 OIC_LOG(DEBUG, TAG, "IN");
135 OIC_LOG(DEBUG, TAG, "OUT");
136 return CA_NOT_SUPPORTED;
139 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
140 const void *data, uint32_t dataLength, uint32_t *sentLength)
142 OIC_LOG(DEBUG, TAG, "IN");
143 CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength);
144 OIC_LOG(DEBUG, TAG, "OUT");
149 CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data,
150 uint32_t dataLength, uint32_t *sentLength)
152 OIC_LOG(DEBUG, TAG, "IN");
153 CAEDRSendMulticastMessage((const char*) data, dataLength);
154 OIC_LOG(DEBUG, TAG, "OUT");
158 // TODO: It will be updated when android EDR support is added
159 void CAEDRClientUnsetCallbacks(void)
161 OIC_LOG(DEBUG, TAG, "IN");
163 OIC_LOG(DEBUG, TAG, "OUT");
166 // TODO: It will be updated when android EDR support is added
167 void CAEDRClientDisconnectAll(void)
169 OIC_LOG(DEBUG, TAG, "IN");
171 OIC_LOG(DEBUG, TAG, "OUT");
174 CAResult_t CAEDRGetAdapterEnableState(bool *state)
176 OIC_LOG(DEBUG, TAG, "IN");
179 OIC_LOG(ERROR, TAG, "g_jvm is null");
180 return CA_STATUS_INVALID_PARAM;
182 jboolean isAttached = JNI_FALSE;
184 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
187 OIC_LOG(DEBUG, TAG, "CAEDRGetAdapterEnableState - Could not get JNIEnv pointer");
188 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
192 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
193 return CA_STATUS_INVALID_PARAM;
195 isAttached = JNI_TRUE;
197 jboolean ret = CAEDRNativeIsEnableBTAdapter(env);
208 (*g_jvm)->DetachCurrentThread(g_jvm);
210 OIC_LOG(DEBUG, TAG, "OUT");
214 ////////////////////////////////////////////////////////////////////////////////////////////////////
215 //FIXME getting context
217 void CAEDRJniSetContext(jobject context)
219 OIC_LOG(DEBUG, TAG, "caedrSetObject");
223 OIC_LOG(ERROR, TAG, "context is null");
226 jboolean isAttached = JNI_FALSE;
228 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
231 OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
232 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
236 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
239 isAttached = JNI_TRUE;
242 g_context = (*env)->NewGlobalRef(env, context);
245 (*g_jvm)->DetachCurrentThread(g_jvm);
248 void CAEDRCreateJNIInterfaceObject(jobject context)
251 OIC_LOG(DEBUG, TAG, "[EDRCore] CAEDRCreateJNIInterfaceObject");
253 if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
255 OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get JNIEnv pointer");
259 //getApplicationContext
260 jclass contextClass = (*env)->FindClass(env, "android/content/Context");
261 if (contextClass == 0)
263 OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get context object class");
267 jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
268 "getApplicationContext", "()Landroid/content/Context;");
269 if (getApplicationContextMethod == 0)
271 OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get getApplicationContext method");
275 jobject gApplicationContext = (*env)->CallObjectMethod(env, context,
276 getApplicationContextMethod);
277 OIC_LOG_V(DEBUG, TAG,
278 "[WIFICore] Saving Android application context object %p", gApplicationContext);
280 //Create WiFiInterface instance
281 jclass WiFiJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CAEDRInterface");
282 if (!WiFiJniInterface)
284 OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get CAWiFiInterface class");
288 jmethodID WiFiInterfaceConstructorMethod = (*env)->GetMethodID(env,
289 WiFiJniInterface, "<init>", "(Landroid/content/Context;)V");
290 if (!WiFiInterfaceConstructorMethod)
292 OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CAWiFiInterface constructor method");
296 (*env)->NewObject(env, WiFiJniInterface, WiFiInterfaceConstructorMethod, gApplicationContext);
297 OIC_LOG(DEBUG, TAG, "[EDRCore] Create CAWiFiInterface instance");
298 OIC_LOG(DEBUG, TAG, "[EDRCore] NewObject Success");
302 static void CAEDRDestroyMutex()
304 OIC_LOG(DEBUG, TAG, "IN");
306 if (g_mutexUnicastServer)
308 ca_mutex_free(g_mutexUnicastServer);
309 g_mutexUnicastServer = NULL;
312 if (g_mutexMulticastServer)
314 ca_mutex_free(g_mutexMulticastServer);
315 g_mutexMulticastServer = NULL;
318 if(g_mutexSocketListManager)
320 ca_mutex_free(g_mutexSocketListManager);
321 g_mutexSocketListManager = NULL;
324 OIC_LOG(DEBUG, TAG, "OUT");
327 static CAResult_t CAEDRCreateMutex()
329 OIC_LOG(DEBUG, TAG, "IN");
331 g_mutexUnicastServer = ca_mutex_new();
332 if (!g_mutexUnicastServer)
334 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
335 return CA_STATUS_FAILED;
338 g_mutexMulticastServer = ca_mutex_new();
339 if (!g_mutexMulticastServer)
341 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
344 return CA_STATUS_FAILED;
347 g_mutexSocketListManager = ca_mutex_new();
348 if (!g_mutexSocketListManager)
350 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
353 return CA_STATUS_FAILED;
356 OIC_LOG(DEBUG, TAG, "OUT");
360 void CAEDRInitialize(ca_thread_pool_t handle)
362 OIC_LOG(DEBUG, TAG, "CAEDRInitialize");
364 g_threadPoolHandle = handle;
369 jboolean isAttached = JNI_FALSE;
371 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
374 OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
375 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
379 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
382 isAttached = JNI_TRUE;
385 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
388 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
389 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
392 CAEDRNativeCreateDeviceStateList();
393 CAEDRNativeCreateDeviceSocketList();
396 (*g_jvm)->DetachCurrentThread(g_jvm);
398 // CAEDRCreateJNIInterfaceObject(gContext); /* create java CAEDRInterface instance*/
400 OIC_LOG(DEBUG, TAG, "OUT");
403 void CAEDRTerminate()
405 OIC_LOG(DEBUG, TAG, "CAEDRTerminate");
407 jboolean isAttached = JNI_FALSE;
409 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
412 OIC_LOG(DEBUG, TAG, "CAEDRTerminate - Could not get JNIEnv pointer");
413 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
417 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
420 isAttached = JNI_TRUE;
424 g_stopMulticast = true;
425 g_stopUnicast = true;
428 (*g_jvm)->DetachCurrentThread(g_jvm);
432 (*env)->DeleteGlobalRef(env, g_context);
437 CAEDRNativeRemoveAllDeviceState();
438 CAEDRNativeRemoveAllDeviceSocket(env);
441 void CAEDRCoreJniInit(JNIEnv *env, JavaVM *jvm)
443 OIC_LOG(DEBUG, TAG, "CAEdrClientJniInit");
446 CAEDRServerJniInit(env, jvm);
449 CAResult_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
451 OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data);
453 CAEDRSendUnicastMessageImpl(address, data, dataLen);
457 CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
459 OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage(%s)", data);
461 jboolean isAttached = JNI_FALSE;
463 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
466 OIC_LOG(DEBUG, TAG, "CAEDRSendMulticastMessage - Could not get JNIEnv pointer");
467 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
471 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
472 return CA_STATUS_INVALID_PARAM;
474 isAttached = JNI_TRUE;
477 CAEDRSendMulticastMessageImpl(env, data, dataLen);
479 OIC_LOG(DEBUG, TAG, "sent data");
483 OIC_LOG(DEBUG, TAG, "DetachCurrentThread");
484 (*g_jvm)->DetachCurrentThread(g_jvm);
487 OIC_LOG(DEBUG, TAG, "OUT - CAEDRSendMulticastMessage");
491 CAResult_t CAEDRGetInterfaceInfo(char **address)
493 CAEDRGetLocalAddress(address);
497 void CAEDRGetLocalAddress(char **address)
499 jboolean isAttached = JNI_FALSE;
501 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
504 OIC_LOG(DEBUG, TAG, "CAEDRGetLocalAddress - Could not get JNIEnv pointer");
505 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
508 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
511 isAttached = JNI_TRUE;
514 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
517 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
518 *address = (char*)OICMalloc(strlen(localAddress) + 1);
519 if (*address == NULL)
522 (*g_jvm)->DetachCurrentThread(g_jvm);
525 memcpy(*address, localAddress, strlen(localAddress));
528 OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
530 (*g_jvm)->DetachCurrentThread(g_jvm);
533 CAResult_t CAEDRSendUnicastMessageImpl(const char* address, const char* data,
536 OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessageImpl, address: %s, data: %s", address, data);
538 jboolean isAttached = JNI_FALSE;
540 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
543 OIC_LOG(DEBUG, TAG, "CAEDRSendUnicastMessageImpl - Could not get JNIEnv pointer");
544 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
547 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
548 return CA_STATUS_INVALID_PARAM;
550 isAttached = JNI_TRUE;
553 OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data");
556 (*env)->DeleteGlobalRef(env, g_sendBuffer);
558 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
559 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data);
560 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
562 // get bonded device list
563 jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
564 if(!jni_arrayPairedDevices)
566 OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
568 (*g_jvm)->DetachCurrentThread(g_jvm);
569 return CA_STATUS_INVALID_PARAM;
571 // Get information from array of devices
572 jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
574 for( i = 0 ; i < length ; i++ )
576 OIC_LOG(DEBUG, TAG, "[EDR][Native] start to check device");
577 // get name, address from BT device
578 jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
580 jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
581 jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice,
582 "getName", "()Ljava/lang/String;");
583 jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice,
584 "getAddress", "()Ljava/lang/String;");
586 jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
590 const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
591 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
592 (*env)->ReleaseStringUTFChars(env, j_str_name, name);
595 jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
596 const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
597 OIC_LOG_V(DEBUG, TAG,
598 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
600 if (!remoteAddress) {
601 OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
603 (*g_jvm)->DetachCurrentThread(g_jvm);
604 return CA_STATUS_INVALID_PARAM;
607 OIC_LOG(ERROR, TAG, "[EDR][Native] address is null");
609 (*g_jvm)->DetachCurrentThread(g_jvm);
610 return CA_STATUS_INVALID_PARAM;
613 if(!strcmp(remoteAddress, address))
615 CAEDRNativeSendData(env, remoteAddress, data, i);
620 (*g_jvm)->DetachCurrentThread(g_jvm);
625 CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
627 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
629 // get bonded device list
630 jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
631 if(!jni_arrayPairedDevices)
633 OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
634 return CA_STATUS_INVALID_PARAM;
636 // Get information from array of devices
637 jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
639 for( i = 0 ; i < length ; i++ )
641 // get name, address from BT device
642 jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
644 jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
645 jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice,
646 "getName", "()Ljava/lang/String;");
647 jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice,
648 "getAddress", "()Ljava/lang/String;");
650 jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
654 const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
655 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
656 (*env)->ReleaseStringUTFChars(env, j_str_name, name);
659 jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
660 const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
661 OIC_LOG_V(DEBUG, TAG,
662 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
665 CAEDRNativeSendData(env, remoteAddress, data, i);
674 void CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data, uint32_t id)
676 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData logic start");
678 if(STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
680 // connect before send data
681 OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data");
685 OIC_LOG(ERROR, TAG, "[EDR][Native] remote address is empty");
690 CAEDRNativeConnect(env, address, id);
694 if(STATE_CONNECTED == CAEDRIsConnectedDevice(address))
696 if(!((*env)->ExceptionCheck(env)))
698 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
699 if(!jni_cid_BTsocket)
701 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null");
705 jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env,
706 jni_cid_BTsocket, "getOutputStream",
707 "()Ljava/io/OutputStream;");
708 if(!jni_mid_getOutputStream)
710 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null");
713 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream..%d", id);
715 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
718 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_socket is not available");
722 jobject jni_obj_outputStream = (*env)->CallObjectMethod(env,
723 jni_obj_socket, jni_mid_getOutputStream);
724 if(!jni_obj_outputStream)
726 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null");
730 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream..");
732 jclass jni_cid_OutputStream = (*env)->FindClass(env, "java/io/OutputStream");
733 if(!jni_cid_OutputStream)
735 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null");
739 jmethodID jni_mid_write = (*env)->GetMethodID(env,
740 jni_cid_OutputStream, "write", "([BII)V");
743 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_write is null");
748 int length = strlen(data);
749 jbuf = (*env)->NewByteArray(env, length);
750 (*env)->SetByteArrayRegion(env, jbuf, 0, length, (jbyte*)data);
752 (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write,
753 jbuf, (jint) 0, (jint) length);
755 if((*env)->ExceptionCheck(env))
757 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: Write Error!!!");
758 (*env)->ExceptionDescribe(env);
759 (*env)->ExceptionClear(env);
763 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success");
765 // remove socket to list
766 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
769 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
773 (*env)->ExceptionDescribe(env);
774 (*env)->ExceptionClear(env);
775 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: error!!");
781 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!");
785 void CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id)
787 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect..");
789 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
790 if(!jni_cid_BTAdapter)
792 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null");
797 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env,
798 jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
799 if(!jni_mid_getDefaultAdapter)
801 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getDefaultAdapter is null");
805 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env,
806 jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
807 if(!jni_obj_BTAdapter)
809 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_BTAdapter is null");
813 // get remote bluetooth device
814 jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env,
815 jni_cid_BTAdapter, "getRemoteDevice",
816 "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;");
817 if(!jni_mid_getRemoteDevice)
819 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null");
823 //jstring jni_address = (*env)->NewStringUTF(env, "B8:5E:7B:54:52:1C");
824 jstring jni_address = (*env)->NewStringUTF(env, address);
825 jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env,
826 jni_obj_BTAdapter, jni_mid_getRemoteDevice, jni_address);
827 if(!jni_obj_remoteBTDevice)
829 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null");
833 // get create Rfcomm Socket method ID
834 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
835 if(!jni_cid_BluetoothDevice)
837 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null");
841 jmethodID jni_mid_createSocket = (*env)->GetMethodID(env,
842 jni_cid_BluetoothDevice,
843 "createInsecureRfcommSocketToServiceRecord",
844 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;");
845 if(!jni_mid_createSocket) {
846 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_createSocket is null");
850 // createInsecureRfcommSocketToServiceRecord / createRfcommSocketToServiceRecord
852 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
855 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null");
859 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
860 "(Ljava/lang/String;)Ljava/util/UUID;");
861 if(!jni_mid_fromString)
863 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_fromString is null");
867 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid,
868 jni_mid_fromString, OIC_EDR_SERVICE_ID);
871 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null");
875 jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env,
876 jni_obj_remoteBTDevice, jni_mid_createSocket, jni_obj_uuid);
877 if(!jni_obj_BTSocket)
879 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_BTSocket is null");
884 jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
885 if(!jni_cid_BTSocket)
887 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null");
891 jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V");
894 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_connect is null");
898 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: initiating connection...");
899 (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect);
901 if((*env)->ExceptionCheck(env))
903 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: Connect is Failed!!!");
904 (*env)->ExceptionDescribe(env);
905 (*env)->ExceptionClear(env);
909 // set socket to list
910 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
911 CAEDRNativeAddDeviceSocketToList(env, jni_socket);
914 CAEDRUpdateDeviceState(STATE_CONNECTED, address);
916 OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: connected");
919 void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id)
922 jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
923 if(!jni_cid_BTSocket)
925 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
929 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
932 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null");
936 jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
939 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_obj_socket is not available");
943 (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
945 if((*env)->ExceptionCheck(env))
947 OIC_LOG(DEBUG, TAG, "[EDR][Native] close: close is Failed!!!");
948 (*env)->ExceptionDescribe(env);
949 (*env)->ExceptionClear(env);
953 // remove socket to list
954 CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
957 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
959 OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
966 void CAEDRNativeCreateDeviceStateList()
968 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceStateList");
970 // create new object array
971 if (g_deviceStateList == NULL)
973 OIC_LOG(DEBUG, TAG, "Create device list");
975 g_deviceStateList = u_arraylist_create();
979 void CAEDRUpdateDeviceState(CAConnectedState_t state, const char *address)
981 state_t *newstate = (state_t*) OICCalloc(1, sizeof(state_t));
983 OIC_LOG(ERROR, TAG, "[EDR][Native] newstate is null");
986 strcpy(newstate->address, address);
987 newstate->state = state;
989 CAEDRNativeAddDeviceStateToList(newstate);
992 void CAEDRNativeAddDeviceStateToList(state_t *state)
996 OIC_LOG(ERROR, TAG, "[EDR][Native] device is null");
1000 if(!g_deviceStateList)
1002 OIC_LOG(ERROR, TAG, "[EDR][Native] gdevice_list is null");
1006 if(CAEDRNativeIsDeviceInList(state->address)) {
1007 CAEDRNativeRemoveDevice(state->address); // delete previous state for update new state
1009 u_arraylist_add(g_deviceStateList, state); // update new state
1010 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d", state->state);
1013 jboolean CAEDRNativeIsDeviceInList(const char* remoteAddress){
1016 if (!remoteAddress) {
1017 OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
1020 for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
1022 state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
1025 OIC_LOG(ERROR, TAG, "[EDR][Native] state_t object is null");
1029 if(!strcmp(remoteAddress, state->address))
1031 OIC_LOG(DEBUG, TAG, "the device is already set");
1040 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
1044 void CAEDRNativeRemoveAllDeviceState()
1046 OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveAllDevices");
1048 if(!g_deviceStateList)
1050 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
1055 for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
1057 state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
1060 OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
1066 OICFree(g_deviceStateList);
1067 g_deviceStateList = NULL;
1071 void CAEDRNativeRemoveDevice(const char *remoteAddress)
1073 OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceforStateList");
1075 if(!g_deviceStateList)
1077 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
1080 if (!remoteAddress) {
1081 OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
1086 for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
1088 state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
1091 OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
1095 if(!strcmp(state->address, remoteAddress))
1097 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove state : %s", remoteAddress);
1100 CAEDRReorderingDeviceList(index);
1107 CAConnectedState_t CAEDRIsConnectedDevice(const char *remoteAddress)
1109 OIC_LOG(DEBUG, TAG, "CAEDRIsConnectedDevice");
1111 if(!g_deviceStateList)
1113 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
1114 return STATE_DISCONNECTED;
1118 for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
1120 state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
1123 OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
1127 if(!strcmp(state->address, remoteAddress))
1129 OIC_LOG(DEBUG, TAG, "[EDR][Native] check whether it is connected or not");
1131 return state->state;
1134 return STATE_DISCONNECTED;
1137 void CAEDRReorderingDeviceList(uint32_t index)
1139 if (index >= g_deviceStateList->length)
1144 if (index < g_deviceStateList->length - 1)
1146 memmove(&g_deviceStateList->data[index], &g_deviceStateList->data[index + 1],
1147 (g_deviceStateList->length - index - 1) * sizeof(void *));
1150 g_deviceStateList->size--;
1151 g_deviceStateList->length--;
1155 * Device Socket Object List
1157 void CAEDRNativeCreateDeviceSocketList()
1159 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceSocketList");
1161 // create new object array
1162 if (g_deviceObjectList == NULL)
1164 OIC_LOG(DEBUG, TAG, "Create Device object list");
1166 g_deviceObjectList = u_arraylist_create();
1170 void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket)
1172 OIC_LOG(DEBUG, TAG, "[EDR][Native] CANativeAddDeviceobjToList");
1176 OIC_LOG(ERROR, TAG, "[EDR][Native] Device is null");
1180 if(!g_deviceObjectList)
1182 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1186 jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
1187 if(!jni_remoteAddress)
1189 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_remoteAddress is null");
1193 ca_mutex_lock(g_mutexSocketListManager);
1195 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1197 if(!CAEDRNativeIsDeviceSocketInList(env, remoteAddress))
1199 jobject gDeviceSocker = (*env)->NewGlobalRef(env, deviceSocket);
1200 u_arraylist_add(g_deviceObjectList, gDeviceSocker);
1201 OIC_LOG(DEBUG, TAG, "Set Socket Object to Array");
1204 ca_mutex_unlock(g_mutexSocketListManager);
1207 jboolean CAEDRNativeIsDeviceSocketInList(JNIEnv *env, const char* remoteAddress)
1209 OIC_LOG(DEBUG, TAG, "[EDR][Native] CANativeIsDeviceObjInList");
1213 if (!remoteAddress) {
1214 OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
1217 for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1220 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1223 OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
1227 jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
1230 OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_setAddress is null");
1234 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1237 OIC_LOG(DEBUG, TAG, "[EDR][Native] setAddress is null");
1241 if(!strcmp(remoteAddress, setAddress))
1243 OIC_LOG(DEBUG, TAG, "the device is already set");
1252 OIC_LOG(DEBUG, TAG, "there are no the Device obejct in list. we can add");
1256 void CAEDRNativeRemoveAllDeviceSocket(JNIEnv *env)
1258 OIC_LOG(DEBUG, TAG, "CANativeRemoveAllDeviceObjsList");
1260 if(!g_deviceObjectList)
1262 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1267 for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1269 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1272 OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
1275 (*env)->DeleteGlobalRef(env, jarrayObj);
1278 OICFree(g_deviceObjectList);
1279 g_deviceObjectList = NULL;
1283 void CAEDRNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket)
1285 OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceSocket");
1287 if(!g_deviceObjectList)
1289 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1293 ca_mutex_lock(g_mutexSocketListManager);
1296 for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1298 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1301 OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
1305 jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
1308 OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_setAddress is null");
1311 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1313 jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
1314 if(!jni_remoteAddress)
1316 OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_remoteAddress is null");
1319 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1321 if(!strcmp(setAddress, remoteAddress))
1323 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove object : %s", remoteAddress);
1324 (*env)->DeleteGlobalRef(env, jarrayObj);
1326 CAEDRReorderingDeviceSocketList(index);
1330 ca_mutex_unlock(g_mutexSocketListManager);
1332 OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object");
1336 jobject CAEDRNativeGetDeviceSocket(uint32_t idx)
1338 OIC_LOG(DEBUG, TAG, "CAEDRNativeGetDeviceSocket");
1342 OIC_LOG(DEBUG, TAG, "[EDR][Native] index is not available");
1346 if(!g_deviceObjectList)
1348 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1352 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, idx);
1355 OIC_LOG(ERROR, TAG, "[EDR][Native] jarrayObj is not available");
1361 uint32_t CAEDRGetSocketListLength()
1363 if(!g_deviceObjectList)
1365 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1369 uint32_t length = u_arraylist_length(g_deviceObjectList);
1374 void CAEDRReorderingDeviceSocketList(uint32_t index)
1376 if (index >= g_deviceObjectList->length)
1381 if (index < g_deviceObjectList->length - 1)
1383 memmove(&g_deviceObjectList->data[index], &g_deviceObjectList->data[index + 1],
1384 (g_deviceObjectList->length - index - 1) * sizeof(void *));
1387 g_deviceObjectList->size--;
1388 g_deviceObjectList->length--;
1391 void CAEDRInitializeClient(ca_thread_pool_t handle)
1393 OIC_LOG(DEBUG, TAG, "IN");
1394 CAEDRInitialize(handle);
1395 OIC_LOG(DEBUG, TAG, "OUT");