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 ******************************************************************/
27 #include "caleserver.h"
28 #include "caleutils.h"
31 #include "oic_malloc.h"
32 #include "cathreadpool.h" /* for thread pool */
34 #include "uarraylist.h"
35 #include "com_iotivity_jar_caleinterface.h"
38 #define TAG PCF("CA_LE_CLIENT")
40 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
41 static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;";
42 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
43 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
44 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
46 static const char IOTIVITY_GATT_SERVIE_UUID[] = "713d0000-503e-4c75-ba94-3148f18d941e";
47 static const char IOTIVITY_GATT_TX_UUID[] = "713d0003-503e-4c75-ba94-3148f18d941e";
48 static const char IOTIVITY_GATT_RX_UUID[] = "713d0002-503e-4c75-ba94-3148f18d941e";
50 static const uint32_t STATE_CONNECTED = 2;
51 static const uint32_t STATE_DISCONNECTED = 0;
52 static const uint32_t GATT_SUCCESS = 0;
54 static const size_t MAX_PDU_BUFFER = 1400;
57 static u_arraylist_t *g_deviceList = NULL;
58 static u_arraylist_t *g_gattObjectList = NULL;
59 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
60 static ca_thread_pool_t g_threadPoolHandle = NULL;
61 static jobject g_leScanCallback;
62 static jobject g_leGattCallback;
63 static jobject g_context;
64 static jobjectArray g_UUIDList;
65 static jboolean g_isStartServer;
66 static jboolean g_isFinishSendData;
68 static jbyteArray g_sendBuffer;
69 static uint32_t g_targetCnt = 0;
70 static uint32_t g_currentSentCnt = 0;
72 /** mutex for synchrnoization **/
73 static ca_mutex g_threadMutex;
74 /** conditional mutex for synchrnoization **/
75 static ca_cond g_threadCond;
77 ///////////////////////////////////////////////////////////////////////////////////////////////////
78 //FIXME getting context
79 void CALEClientJNISetContext(JNIEnv *env, jobject context)
81 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
85 OIC_LOG(ERROR, TAG, "context is null");
89 g_context = (*env)->NewGlobalRef(env, context);
92 void CALeCreateJniInterfaceObject()
94 OIC_LOG(DEBUG, TAG, "CALeCreateJniInterfaceObject");
96 jboolean isAttached = JNI_FALSE;
98 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
101 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
102 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
106 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
109 isAttached = JNI_TRUE;
112 jclass LeJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CALeInterface");
115 OIC_LOG(DEBUG, TAG, "Could not get CALeInterface class");
119 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, LeJniInterface, "<init>",
120 "(Landroid/content/Context;)V");
121 if (!LeInterfaceConstructorMethod)
123 OIC_LOG(DEBUG, TAG, "Could not get CALeInterface constructor method");
127 (*env)->NewObject(env, LeJniInterface, LeInterfaceConstructorMethod, g_context);
128 OIC_LOG(DEBUG, TAG, "Create CALeInterface instance");
132 (*g_jvm)->DetachCurrentThread(g_jvm);
136 JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
138 OIC_LOG(DEBUG, TAG, "JNI_OnLoad in calecore");
141 if ((*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
145 g_jvm = jvm; /* cache the JavaVM pointer */
147 //JVM required for WifiCore to work with JNI interface
149 CALeServerJniInit(env, jvm);
150 CAEDRCoreJniInit(env, jvm);
152 return JNI_VERSION_1_6;
155 void JNI_OnUnload(JavaVM *jvm, void *reserved)
157 OIC_LOG(DEBUG, TAG, "JNI_OnUnload in calecore");
160 if ((*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
168 void CALEInitialize(ca_thread_pool_t handle)
170 OIC_LOG(DEBUG, TAG, "CALEInitialize");
172 g_threadPoolHandle = handle;
174 // init mutex for send logic
175 g_threadMutex = ca_mutex_new();
176 g_threadCond = ca_cond_new();
178 CANativeCreateUUIDList();
180 CALeCreateJniInterfaceObject(); /* create java CALeInterface instance*/
185 OIC_LOG(DEBUG, TAG, "CALETerminate");
187 jboolean isAttached = JNI_FALSE;
189 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
192 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
193 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
197 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
200 isAttached = JNI_TRUE;
203 CANativeLEDisconnectAll(env);
205 if (g_leScanCallback)
207 CANativeLEStopScanImpl(env, g_leScanCallback);
211 if (g_leScanCallback)
213 (*env)->DeleteGlobalRef(env, g_leScanCallback);
216 if (g_leGattCallback)
218 (*env)->DeleteGlobalRef(env, g_leGattCallback);
223 (*env)->DeleteGlobalRef(env, g_context);
228 (*env)->DeleteGlobalRef(env, g_sendBuffer);
233 (*env)->DeleteGlobalRef(env, g_UUIDList);
236 CANativeRemoveAllDevices(env);
237 CANativeRemoveAllGattObjsList(env);
238 g_isStartServer = JNI_FALSE;
239 g_isFinishSendData = JNI_FALSE;
243 (*g_jvm)->DetachCurrentThread(g_jvm);
246 // delete mutex object
247 ca_mutex_free(g_threadMutex);
248 g_threadMutex = NULL;
249 ca_cond_signal(g_threadCond);
250 ca_cond_free(g_threadCond);
253 void CANativeSendFinish(JNIEnv *env, jobject gatt)
255 OIC_LOG(DEBUG, TAG, "CANativeSendFinish");
259 CANativeLEDisconnect(env, gatt);
261 CANativeupdateSendCnt(env);
264 CAResult_t CALESendUnicastMessage(const char* address, const char* data, const uint32_t dataLen)
266 OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessage(%s, %s)", address, data);
268 return CALESendUnicastMessageImpl(address, data, dataLen);
271 CAResult_t CALESendMulticastMessage(const char* data, const uint32_t dataLen)
273 OIC_LOG_V(DEBUG, TAG, "CALESendMulticastMessage(%s)", data);
275 return CALESendMulticastMessageImpl(data, dataLen);
278 CAResult_t CALEStartUnicastServer(const char* address)
280 OIC_LOG_V(DEBUG, TAG, "CALEStartUnicastServer(%s)", address);
285 CAResult_t CALEStartMulticastServer()
287 OIC_LOG(DEBUG, TAG, "CALEStartMulticastServer");
291 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
292 return CA_STATUS_FAILED;
295 jboolean isAttached = JNI_FALSE;
297 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
300 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
301 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
305 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
306 return CA_STATUS_FAILED;
308 isAttached = JNI_TRUE;
311 g_isStartServer = JNI_TRUE;
313 CANativeLEStartScan();
317 (*g_jvm)->DetachCurrentThread(g_jvm);
323 void CALEStopUnicastServer()
325 OIC_LOG(DEBUG, TAG, "CALEStopUnicastServer");
328 void CALEStopMulticastServer()
330 OIC_LOG(DEBUG, TAG, "CALEStopMulticastServer");
331 g_isStartServer = JNI_FALSE;
332 CANativeLEStopScan();
335 void CALESetCallback(CAPacketReceiveCallback callback)
337 g_packetReceiveCallback = callback;
340 CAResult_t CALEGetInterfaceInfo(char **address)
342 CALEGetLocalAddress(address);
346 void CALEGetLocalAddress(char** address)
348 jboolean isAttached = JNI_FALSE;
350 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
353 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
354 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
357 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
360 isAttached = JNI_TRUE;
363 jstring jni_address = CALEGetLocalDeviceAddress(env);
366 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
367 uint32_t length = strlen(localAddress);
368 *address = (char*) OICMalloc(length + 1);
369 if (*address == NULL)
373 memcpy(*address, localAddress, length + 1);
376 OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
379 (*g_jvm)->DetachCurrentThread(g_jvm);
383 CAResult_t CALESendUnicastMessageImpl(const char* address, const char* data, const uint32_t dataLen)
385 OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessageImpl, address: %s, data: %s", address, data);
387 jboolean isAttached = JNI_FALSE;
389 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
392 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
393 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
396 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
397 return CA_STATUS_FAILED;
399 isAttached = JNI_TRUE;
402 OIC_LOG(DEBUG, TAG, "[BLE][Native] set byteArray for data");
405 (*env)->DeleteGlobalRef(env, g_sendBuffer);
407 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
408 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
409 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
411 // connect to gatt server
412 CANativeLEStopScanImpl(env, g_leScanCallback);
415 jobject jni_obj_bluetoothDevice = NULL;
416 if (g_context && g_deviceList)
419 for (index = 0; index < u_arraylist_length(g_deviceList); index++)
421 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
424 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
425 return CA_STATUS_FAILED;
428 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
431 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
432 return CA_STATUS_FAILED;
434 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
436 if (!strcmp(setAddress, address))
438 jni_obj_bluetoothDevice = jarrayObj;
443 if (jni_obj_bluetoothDevice)
445 jboolean autoConnect = JNI_FALSE;
446 CANativeLEConnect(env, jni_obj_bluetoothDevice, g_context, autoConnect,
453 (*g_jvm)->DetachCurrentThread(g_jvm);
459 CAResult_t CALESendMulticastMessageImpl(const char* data, const uint32_t dataLen)
461 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
463 jboolean isAttached = JNI_FALSE;
465 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
468 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
469 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
472 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
473 return CA_STATUS_FAILED;
475 isAttached = JNI_TRUE;
480 OIC_LOG(ERROR, TAG, "[BLE][Native] g_deviceList is null");
481 return CA_STATUS_FAILED;
482 }OIC_LOG(DEBUG, TAG, "set wait");
484 g_isFinishSendData = JNI_FALSE;
486 OIC_LOG(DEBUG, TAG, "[BLE][Native] set byteArray for data");
489 (*env)->DeleteGlobalRef(env, g_sendBuffer);
491 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
492 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
493 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
495 // connect to gatt server
496 CANativeLEStopScanImpl(env, g_leScanCallback);
500 CANativeRemoveAllGattObjsList(env);
501 CANativeCreateGattObjList(env);
503 g_targetCnt = u_arraylist_length(g_deviceList);
507 while (index < u_arraylist_length(g_deviceList))
509 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
512 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
517 == CANativeLEConnect(env, jarrayObj, g_context, JNI_FALSE, g_leGattCallback))
519 // connection failure
525 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
526 if (!g_isFinishSendData)
528 ca_mutex_lock(g_threadMutex);
529 ca_cond_wait(g_threadCond, g_threadMutex);
530 OIC_LOG(DEBUG, TAG, "unset wait");
531 ca_mutex_unlock(g_threadMutex);
534 // start LE Scan again
536 CANativeLEStartScan();
541 (*g_jvm)->DetachCurrentThread(g_jvm);
547 jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt)
551 OIC_LOG(ERROR, TAG, "[BLE][Native] gatt is null");
555 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
556 if (!jni_cid_gattdevice_list)
558 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_gattdevice_list is null");
562 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
563 "()Landroid/bluetooth/BluetoothDevice;");
564 if (!jni_mid_getDevice)
566 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getDevice is null");
570 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
573 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_device is null");
577 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
580 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_address is null");
590 void CANativeGattClose(JNIEnv *env, jobject bluetoothGatt)
593 OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT CLOSE");
595 // get BluetoothGatt class
596 OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
597 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
598 if (!jni_cid_BluetoothGatt)
600 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
604 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
605 if (!jni_mid_closeGatt)
607 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_closeGatt is null");
611 // call disconnect gatt method
612 OIC_LOG(DEBUG, TAG, "[BLE][Native] request close Gatt");
613 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
616 void CANativeLEStartScan()
618 if (!g_isStartServer)
620 OIC_LOG(DEBUG, TAG, "server is not started yet..scan will be passed");
624 jboolean isAttached = JNI_FALSE;
626 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
629 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
631 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
634 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
637 isAttached = JNI_TRUE;
640 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStartScan");
642 // scan gatt server with UUID
643 if (g_leScanCallback && g_UUIDList)
645 CANativeLEStartScanWithUUIDImpl(env, g_UUIDList, g_leScanCallback);
650 (*g_jvm)->DetachCurrentThread(g_jvm);
655 void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
657 if (!CALEIsEnableBTAdapter(env))
659 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
663 // get default bt adapter class
664 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
665 if (!jni_cid_BTAdapter)
667 OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
671 // get remote bt adapter method
672 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
674 METHODID_OBJECTNONPARAM);
675 if (!jni_mid_getDefaultAdapter)
677 OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: getDefaultAdapter is null");
681 // get start le scan method
682 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(
683 env, jni_cid_BTAdapter, "startLeScan",
684 "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
685 if (!jni_mid_startLeScan)
687 OIC_LOG(ERROR, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
691 // gat bt adapter object
692 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
693 jni_mid_getDefaultAdapter);
694 if (!jni_obj_BTAdapter)
696 OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
700 // call start le scan method
701 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
702 jni_mid_startLeScan, callback);
703 if (!jni_obj_startLeScan)
705 OIC_LOG(ERROR, TAG, "[BLE][Native] startLeScan is failed");
710 OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan is started");
714 jobject CANativeGetUUIDObject(JNIEnv *env, const char* uuid)
717 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
720 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_uuid is null");
724 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
725 env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
726 if (!jni_mid_fromString)
728 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_fromString is null");
732 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
733 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
737 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_uuid is null");
744 void CANativeLEStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
746 // get default bt adapter class
747 OIC_LOG(DEBUG, TAG, "[BLE][Native] get default bt adapter class");
749 if (!CALEIsEnableBTAdapter(env))
751 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
755 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
756 if (!jni_cid_BTAdapter)
758 OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
762 // get remote bt adapter method
763 OIC_LOG(DEBUG, TAG, "[BLE][Native] get remote bt adapter method");
764 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
766 METHODID_OBJECTNONPARAM);
767 if (!jni_mid_getDefaultAdapter)
769 OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: getDefaultAdapter is null");
773 // get start le scan method
774 OIC_LOG(DEBUG, TAG, "[BLE][Native] get start le scan method");
775 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(
776 env, jni_cid_BTAdapter, "startLeScan",
777 "([Ljava/util/UUID;Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
778 if (!jni_mid_startLeScan)
780 OIC_LOG(ERROR, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
784 // get bt adapter object
785 OIC_LOG(DEBUG, TAG, "[BLE][Native] get bt adapter object");
786 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
787 jni_mid_getDefaultAdapter);
788 if (!jni_obj_BTAdapter)
790 OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
794 // call start le scan method
795 OIC_LOG(DEBUG, TAG, "[BLE][Native] call start le scan service method");
796 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
797 jni_mid_startLeScan, uuids, callback);
798 if (!jni_obj_startLeScan)
800 OIC_LOG(ERROR, TAG, "[BLE][Native] startLeScan With UUID is failed");
805 OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan With UUID is started");
809 void CANativeLEStopScan()
811 jboolean isAttached = JNI_FALSE;
813 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
816 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
817 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
820 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
823 isAttached = JNI_TRUE;
826 CANativeLEStopScanImpl(env, g_leScanCallback);
830 (*g_jvm)->DetachCurrentThread(g_jvm);
835 void CANativeLEStopScanImpl(JNIEnv *env, jobject callback)
837 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStopScan");
839 if (!CALEIsEnableBTAdapter(env))
841 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
845 // get default bt adapter class
846 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
847 if (!jni_cid_BTAdapter)
849 OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
853 // get remote bt adapter method
854 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
856 METHODID_OBJECTNONPARAM);
857 if (!jni_mid_getDefaultAdapter)
859 OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: getDefaultAdapter is null");
863 // get start le scan method
864 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(
865 env, jni_cid_BTAdapter, "stopLeScan",
866 "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)V");
867 if (!jni_mid_stopLeScan)
869 OIC_LOG(ERROR, TAG, "[BLE][Native] stopLeScan: jni_mid_stopLeScan is null");
873 // gat bt adapter object
874 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
875 jni_mid_getDefaultAdapter);
876 if (!jni_obj_BTAdapter)
878 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
882 OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to stop LE Scan");
883 // call start le scan method
884 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
887 CAResult_t CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context,
888 jboolean autoconnect, jobject callback)
890 if (!CALEIsEnableBTAdapter(env))
892 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
893 return CA_STATUS_FAILED;
896 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
897 const char * addr = (*env)->GetStringUTFChars(env, jni_address, NULL);
898 OIC_LOG_V(DEBUG, TAG, "[BLE][Native] request connectGatt to %s", addr);
902 // get BluetoothDevice class
903 OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothDevice class");
904 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
905 if (!jni_cid_BluetoothDevice)
907 OIC_LOG(ERROR, TAG, "[BLE][Native] bleConnect: jni_cid_BluetoothDevice is null");
908 return CA_STATUS_FAILED;
911 // get connectGatt method
912 OIC_LOG(DEBUG, TAG, "[BLE][Native] get connectGatt method");
913 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(
914 env, jni_cid_BluetoothDevice, "connectGatt",
915 "(Landroid/content/Context;ZLandroid/bluetooth/BluetoothGattCallback;)"
916 "Landroid/bluetooth/BluetoothGatt;");
917 if (!jni_mid_connectGatt)
919 OIC_LOG(ERROR, TAG, "[BLE][Native] bleConnect: jni_mid_connectGatt is null");
920 return CA_STATUS_FAILED;
923 OIC_LOG(DEBUG, TAG, "[BLE][Native] Call object method - connectGatt");
924 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
927 autoconnect, callback);
928 if (!jni_obj_connectGatt)
930 OIC_LOG(ERROR, TAG, "[BLE][Native] CALL API - connectGatt was failed.obj will be removed");
931 CANativeRemoveDevice(env, jni_address);
932 CANativeupdateSendCnt(env);
933 return CA_STATUS_FAILED;
937 OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - connecting..");
942 void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt)
944 if (!CALEIsEnableBTAdapter(env))
946 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
951 OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT DISCONNECT");
953 // get BluetoothGatt class
954 OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt classjobject bluetoothGatt");
955 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
956 if (!jni_cid_BluetoothGatt)
958 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
962 OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt disconnect method");
963 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "disconnect",
965 if (!jni_mid_disconnectGatt)
967 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_disconnectGatt is null");
971 // call disconnect gatt method
972 OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request disconnectGatt");
973 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
977 void CANativeLEDisconnectAll(JNIEnv *env)
979 OIC_LOG(DEBUG, TAG, "CANativeLEDisconnectAll");
981 if (!g_gattObjectList)
983 OIC_LOG(ERROR, TAG, "[BLE][Native] g_gattObjectList is null");
988 for (index = 0; index < u_arraylist_length(g_gattObjectList); index++)
990 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
993 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
996 CANativeLEDisconnect(env, jarrayObj);
999 OICFree(g_gattObjectList);
1000 g_gattObjectList = NULL;
1004 void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1006 if (!CALEIsEnableBTAdapter(env))
1008 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
1012 // GATT SERVICE DISCOVERY
1013 OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT SERVICE DISCOVERY");
1015 // get BluetoothGatt class
1016 OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
1017 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1018 if (!jni_cid_BluetoothGatt)
1020 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1024 OIC_LOG(DEBUG, TAG, "[BLE][Native] discovery gatt services method");
1025 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1026 "discoverServices", "()Z");
1027 if (!jni_mid_discoverServices)
1029 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_discoverServices is null");
1032 // call disconnect gatt method
1033 OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request discovery gatt services");
1034 (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1037 CAResult_t CANativeWriteCharacteristic(JNIEnv *env, jobject bluetoothGatt,
1038 jobject gattCharacteristic)
1040 if (!CALEIsEnableBTAdapter(env))
1042 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
1043 return CA_STATUS_FAILED;
1046 // WRITE GATT CHARACTERISTIC
1047 OIC_LOG(DEBUG, TAG, "[BLE][Native] WRITE GATT CHARACTERISTIC");
1049 // get BluetoothGatt class
1050 OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
1051 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1052 if (!jni_cid_BluetoothGatt)
1054 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1055 return CA_STATUS_FAILED;
1058 OIC_LOG(DEBUG, TAG, "[BLE][Native] write characteristic method");
1059 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(
1060 env, jni_cid_BluetoothGatt, "writeCharacteristic",
1061 "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
1062 if (!jni_mid_writeCharacteristic)
1064 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_writeCharacteristic is null");
1065 return CA_STATUS_FAILED;
1068 // call disconnect gatt method
1069 OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to write gatt characteristic");
1070 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1071 jni_mid_writeCharacteristic,
1072 gattCharacteristic);
1075 OIC_LOG(DEBUG, TAG, "[BLE][Native] writeCharacteristic is success");
1079 OIC_LOG(ERROR, TAG, "[BLE][Native] writeCharacteristic is failed");
1080 return CA_STATUS_FAILED;
1082 return CA_STATUS_OK;
1085 void CANativeReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1088 if (!CALEIsEnableBTAdapter(env))
1090 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
1094 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1095 if (!jni_cid_BluetoothGatt)
1097 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1101 jstring jni_uuid = (*env)->NewStringUTF(env, IOTIVITY_GATT_RX_UUID);
1102 jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1103 if (!jni_obj_GattCharacteristic)
1105 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1109 OIC_LOG(DEBUG, TAG, "[BLE][Native] read characteristic method");
1110 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(
1111 env, jni_cid_BluetoothGatt, "readCharacteristic",
1112 "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
1113 if (!jni_mid_readCharacteristic)
1115 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_readCharacteristic is null");
1119 // call disconnect gatt method
1120 OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to read gatt characteristic");
1121 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1122 jni_obj_GattCharacteristic);
1125 OIC_LOG(DEBUG, TAG, "[BLE][Native] readCharacteristic is success");
1129 OIC_LOG(ERROR, TAG, "[BLE][Native] readCharacteristic is failed");
1133 CAResult_t CANativeSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1136 if (!CALEIsEnableBTAdapter(env))
1138 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
1139 return CA_ADAPTER_NOT_ENABLED;
1142 // get BluetoothGatt class
1143 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeSetCharacteristicNotification");
1144 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1145 if (!jni_cid_BluetoothGatt)
1147 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1148 return CA_STATUS_FAILED;
1151 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1152 jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1153 if (!jni_obj_GattCharacteristic)
1155 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1156 return CA_STATUS_FAILED;
1159 // set Characteristic Notification
1160 jmethodID jni_mid_setNotification = (*env)->GetMethodID(
1161 env, jni_cid_BluetoothGatt, "setCharacteristicNotification",
1162 "(Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
1163 if (!jni_mid_setNotification)
1165 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getService is null");
1166 return CA_STATUS_FAILED;
1169 jboolean enable = JNI_TRUE;
1170 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1171 jni_obj_GattCharacteristic, enable);
1174 OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - setCharacteristicNotification is success");
1175 return CA_STATUS_OK;
1179 OIC_LOG(ERROR, TAG, "[BLE][Native] CALL API - setCharacteristicNotification is failed");
1180 return CA_STATUS_FAILED;
1184 jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1186 if (!CALEIsEnableBTAdapter(env))
1188 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
1192 // get BluetoothGatt class
1193 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeGetGattService");
1194 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1195 if (!jni_cid_BluetoothGatt)
1197 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1201 jmethodID jni_mid_getService = (*env)->GetMethodID(
1202 env, jni_cid_BluetoothGatt, "getService",
1203 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1204 if (!jni_mid_getService)
1206 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getService is null");
1210 jobject jni_obj_service_uuid = CANativeGetUUIDObject(env, IOTIVITY_GATT_SERVIE_UUID);
1211 if (!jni_obj_service_uuid)
1213 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_service_uuid is null");
1217 // get bluetooth gatt service
1218 OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get service");
1219 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1220 jni_obj_service_uuid);
1222 // get bluetooth gatt service class
1223 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1224 env, "android/bluetooth/BluetoothGattService");
1225 if (!jni_cid_BluetoothGattService)
1227 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGattService is null");
1231 OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt getCharacteristic method");
1232 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(
1233 env, jni_cid_BluetoothGattService, "getCharacteristic",
1234 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
1235 if (!jni_mid_getCharacteristic)
1237 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getCharacteristic is null");
1241 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1242 jobject jni_obj_tx_uuid = CANativeGetUUIDObject(env, uuid);
1243 if (!jni_obj_tx_uuid)
1245 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_tx_uuid is null");
1249 OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get Characteristic");
1250 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1251 jni_mid_getCharacteristic,
1254 return jni_obj_GattCharacteristic;
1257 jobject CANativeCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1259 if (!CALEIsEnableBTAdapter(env))
1261 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
1265 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattCharacteristic");
1266 jstring jni_uuid = (*env)->NewStringUTF(env, IOTIVITY_GATT_TX_UUID);
1267 jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1268 if (!jni_obj_GattCharacteristic)
1270 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1274 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(
1275 env, "android/bluetooth/BluetoothGattCharacteristic");
1276 if (!jni_cid_BTGattCharacteristic)
1278 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
1282 OIC_LOG(DEBUG, TAG, "[BLE][Native] set value in Characteristic");
1283 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1285 if (!jni_mid_setValue)
1287 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_setValue is null");
1291 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1295 OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value has been set");
1296 return jni_obj_GattCharacteristic;
1300 OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value hasn't been set");
1305 jbyteArray CANativeGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1307 if (!CALEIsEnableBTAdapter(env))
1309 OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
1313 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(
1314 env, "android/bluetooth/BluetoothGattCharacteristic");
1315 if (!jni_cid_BTGattCharacteristic)
1317 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
1321 OIC_LOG(DEBUG, TAG, "[BLE][Native] get value in Characteristic");
1322 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1324 if (!jni_mid_getValue)
1326 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getValue is null");
1330 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic, jni_mid_getValue);
1331 return jni_obj_data_array;
1334 void CANativeCreateUUIDList()
1336 jboolean isAttached = JNI_FALSE;
1338 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1341 OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1342 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1346 OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
1349 isAttached = JNI_TRUE;
1352 // create new object array
1353 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1354 if (!jni_cid_uuid_list)
1356 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_uuid_list is null");
1360 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1, jni_cid_uuid_list,
1362 if (!jni_obj_uuid_list)
1364 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_uuid_list is null");
1368 // remove previous list and create list again
1369 CANativeRemoveAllDevices(env);
1370 CANativeCreateScanDeviceList(env);
1373 jobject jni_obj_uuid = CANativeGetUUIDObject(env, IOTIVITY_GATT_SERVIE_UUID);
1374 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1376 g_UUIDList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1380 (*g_jvm)->DetachCurrentThread(g_jvm);
1384 void CANativeCreateScanDeviceList(JNIEnv *env)
1386 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateScanDeviceList");
1388 // create new object array
1389 if (g_deviceList == NULL)
1391 OIC_LOG(DEBUG, TAG, "Create device list");
1393 g_deviceList = u_arraylist_create();
1397 void CANativeAddScanDeviceToList(JNIEnv *env, jobject device)
1401 OIC_LOG(ERROR, TAG, "[BLE][Native] device is null");
1407 OIC_LOG(ERROR, TAG, "[BLE][Native] gdevice_list is null");
1411 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1412 if (!jni_remoteAddress)
1414 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_remoteAddress is null");
1418 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1420 if (!CANativeIsDeviceInList(env, remoteAddress))
1422 jobject gdevice = (*env)->NewGlobalRef(env, device);
1423 u_arraylist_add(g_deviceList, gdevice);
1424 OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
1428 jboolean CANativeIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1430 // get address value from device list
1433 for (index = 0; index < u_arraylist_length(g_deviceList); index++)
1435 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1438 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
1442 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1443 if (!jni_setAddress)
1445 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
1449 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1451 if (!strcmp(remoteAddress, setAddress))
1453 OIC_LOG(DEBUG, TAG, "the device is already set");
1458 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
1462 void CANativeRemoveAllDevices(JNIEnv *env)
1464 OIC_LOG(DEBUG, TAG, "CANativeRemoveAllDevices");
1468 OIC_LOG(ERROR, TAG, "[BLE][Native] g_deviceList is null");
1473 for (index = 0; index < u_arraylist_length(g_deviceList); index++)
1475 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1478 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
1481 (*env)->DeleteGlobalRef(env, jarrayObj);
1484 OICFree(g_deviceList);
1485 g_deviceList = NULL;
1489 void CANativeRemoveDevice(JNIEnv *env, jstring address)
1491 OIC_LOG(DEBUG, TAG, "CANativeRemoveDevice");
1495 OIC_LOG(ERROR, TAG, "[BLE][Native] g_deviceList is null");
1500 for (index = 0; index < u_arraylist_length(g_deviceList); index++)
1502 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1505 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
1509 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1510 if (!jni_setAddress)
1512 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
1515 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1516 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
1518 if (!strcmp(setAddress, remoteAddress))
1520 OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
1521 (*env)->DeleteGlobalRef(env, jarrayObj);
1523 CAReorderingDeviceList(index);
1526 }OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
1530 void CAReorderingDeviceList(uint32_t index)
1532 if (index >= g_deviceList->length)
1537 if (index < g_deviceList->length - 1)
1539 memmove(&g_deviceList->data[index], &g_deviceList->data[index + 1],
1540 (g_deviceList->length - index - 1) * sizeof(void *));
1543 g_deviceList->size--;
1544 g_deviceList->length--;
1550 void CANativeCreateGattObjList(JNIEnv *env)
1552 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattObjList");
1554 // create new object array
1555 if (g_gattObjectList == NULL)
1557 OIC_LOG(DEBUG, TAG, "Create Gatt object list");
1559 g_gattObjectList = u_arraylist_create();
1563 void CANativeAddGattobjToList(JNIEnv *env, jobject gatt)
1565 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeAddGattobjToList");
1569 OIC_LOG(ERROR, TAG, "[BLE][Native] gatt is null");
1573 if (!g_gattObjectList)
1575 OIC_LOG(ERROR, TAG, "[BLE][Native] g_gattObjectList is null");
1579 jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
1580 if (!jni_remoteAddress)
1582 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_remoteAddress is null");
1586 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1588 if (!CANativeIsGattObjInList(env, remoteAddress))
1590 jobject gGatt = (*env)->NewGlobalRef(env, gatt);
1591 u_arraylist_add(g_gattObjectList, gGatt);
1592 OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
1596 jboolean CANativeIsGattObjInList(JNIEnv *env, const char* remoteAddress)
1598 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsGattObjInList");
1601 for (index = 0; index < u_arraylist_length(g_gattObjectList); index++)
1604 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1607 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
1611 jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
1612 if (!jni_setAddress)
1614 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
1618 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1620 if (!strcmp(remoteAddress, setAddress))
1622 OIC_LOG(DEBUG, TAG, "the device is already set");
1631 OIC_LOG(DEBUG, TAG, "there are no the gatt obejct in list. we can add");
1635 void CANativeRemoveAllGattObjsList(JNIEnv *env)
1637 OIC_LOG(DEBUG, TAG, "CANativeRemoveAllGattObjsList");
1639 if (!g_gattObjectList)
1641 OIC_LOG(ERROR, TAG, "[BLE][Native] g_gattObjectList is null");
1646 for (index = 0; index < u_arraylist_length(g_gattObjectList); index++)
1648 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1651 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
1654 (*env)->DeleteGlobalRef(env, jarrayObj);
1657 OICFree(g_gattObjectList);
1658 g_gattObjectList = NULL;
1662 void CANativeRemoveGattObj(JNIEnv *env, jobject gatt)
1664 OIC_LOG(DEBUG, TAG, "CANativeRemoveGattObj");
1666 if (!g_gattObjectList)
1668 OIC_LOG(ERROR, TAG, "[BLE][Native] g_gattObjectList is null");
1673 for (index = 0; index < u_arraylist_length(g_gattObjectList); index++)
1675 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1678 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
1682 jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
1683 if (!jni_setAddress)
1685 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
1688 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1690 jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
1691 if (!jni_remoteAddress)
1693 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_remoteAddress is null");
1696 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1698 if (!strcmp(setAddress, remoteAddress))
1700 OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
1701 (*env)->DeleteGlobalRef(env, jarrayObj);
1703 CAReorderingGattList(index);
1706 }OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
1710 void CAReorderingGattList(uint32_t index)
1712 if (index >= g_gattObjectList->length)
1717 if (index < g_gattObjectList->length - 1)
1719 memmove(&g_gattObjectList->data[index], &g_gattObjectList->data[index + 1],
1720 (g_gattObjectList->length - index - 1) * sizeof(void *));
1723 g_gattObjectList->size--;
1724 g_gattObjectList->length--;
1728 * Check Sent Count for remove g_sendBuffer
1730 void CANativeupdateSendCnt(JNIEnv *env)
1733 ca_mutex_lock(g_threadMutex);
1737 if (g_targetCnt <= g_currentSentCnt)
1740 g_currentSentCnt = 0;
1744 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1745 g_sendBuffer = NULL;
1747 // notity the thread
1748 ca_cond_signal(g_threadCond);
1749 g_isFinishSendData = JNI_TRUE;
1750 OIC_LOG(DEBUG, TAG, "set signal for send data");
1753 ca_mutex_unlock(g_threadMutex);
1756 JNIEXPORT void JNICALL
1757 Java_com_iotivity_jar_caleinterface_CARegisterLeScanCallback(JNIEnv *env, jobject obj,
1760 OIC_LOG(DEBUG, TAG, "CARegisterLeScanCallback");
1762 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
1765 JNIEXPORT void JNICALL
1766 Java_com_iotivity_jar_caleinterface_CARegisterLeGattCallback(JNIEnv *env, jobject obj,
1769 OIC_LOG(DEBUG, TAG, "CARegisterLeGattCallback");
1771 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
1774 JNIEXPORT void JNICALL
1775 Java_com_iotivity_jar_caleinterface_CALeScanCallback(JNIEnv *env, jobject obj, jobject device,
1776 jint rssi, jbyteArray scanRecord)
1778 CANativeAddScanDeviceToList(env, device);
1782 * Class: com_iotivity_jar_caleinterface
1783 * Method: CALeGattConnectionStateChangeCallback
1784 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
1786 JNIEXPORT void JNICALL
1787 Java_com_iotivity_jar_caleinterface_CALeGattConnectionStateChangeCallback(JNIEnv *env, jobject obj,
1788 jobject gatt, jint status,
1791 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
1794 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
1798 CANativeAddGattobjToList(env, gatt);
1799 CANativeLEDiscoverServices(env, gatt);
1802 else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
1808 CANativeSendFinish(env, gatt);
1813 * Class: com_iotivity_jar_caleinterface
1814 * Method: CALeGattServicesDiscoveredCallback
1815 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
1817 JNIEXPORT void JNICALL
1818 Java_com_iotivity_jar_caleinterface_CALeGattServicesDiscoveredCallback(JNIEnv *env, jobject obj,
1819 jobject gatt, jint status)
1821 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
1823 if (0 != status) // discovery error
1825 CANativeSendFinish(env, gatt);
1829 // read Characteristic
1830 // CANativeReadCharacteristic(env, gatt);
1832 CAResult_t ret = CANativeSetCharacteristicNotification(env, gatt, IOTIVITY_GATT_RX_UUID);
1833 if (CA_STATUS_OK != ret) // SetCharacteristicNoti is failed
1835 CANativeSendFinish(env, gatt);
1839 // jstring data = (*env)->NewStringUTF(env, "HelloWorld");
1840 jobject jni_obj_character = CANativeCreateGattCharacteristic(env, gatt, g_sendBuffer);
1841 if (!jni_obj_character)
1843 CANativeSendFinish(env, gatt);
1848 ret = CANativeWriteCharacteristic(env, gatt, jni_obj_character);
1849 if (CA_STATUS_FAILED == ret)
1851 CANativeSendFinish(env, gatt);
1857 * Class: com_iotivity_jar_caleinterface
1858 * Method: CALeGattCharacteristicReadCallback
1859 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
1861 JNIEXPORT void JNICALL
1862 Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicReadCallback(JNIEnv *env, jobject obj,
1864 jobject characteristic,
1865 jbyteArray data, jint status)
1867 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicReadCallback - status : %d", status);
1871 * Class: com_iotivity_jar_caleinterface
1872 * Method: CALeGattCharacteristicWritjclasseCallback
1873 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
1875 JNIEXPORT void JNICALL
1876 Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicWriteCallback(JNIEnv *env, jobject obj,
1878 jobject characteristic,
1882 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
1884 jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
1885 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1888 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s",
1889 (char*)(*env)->GetByteArrayElements(env, data, &isCopy));
1892 CANativeSendFinish(env, gatt);
1895 if (0 != status) // error case
1897 CANativeSendFinish(env, gatt);
1902 * Class: com_iotivity_jar_caleinterface
1903 * Method: CALeGattCharacteristicChangedCallback
1904 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
1906 JNIEXPORT void JNICALL
1907 Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicChangedCallback(JNIEnv *env, jobject obj,
1909 jobject characteristic,
1912 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
1914 // get Byte Array and covert to char*
1915 jint length = (*env)->GetArrayLength(env, data);
1918 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
1920 char* recevicedData = (char*) OICMalloc(sizeof(char) * length);
1921 if (NULL == recevicedData)
1923 OIC_LOG(ERROR, TAG, "recevicedData is null");
1924 CANativeSendFinish(env, gatt);
1929 memcpy(recevicedData, (const char*) jni_byte_responseData, length);
1930 recevicedData[length] = '\0';
1931 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
1933 jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
1934 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1936 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %s, %d",
1937 recevicedData, length);
1940 g_packetReceiveCallback(address, recevicedData);
1941 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1943 // LE disconnect and finish BLE write routine
1944 CANativeSendFinish(env, gatt);
1948 * Class: com_iotivity_jar_caleinterface
1949 * Method: CALeGattDescriptorReadCallback
1950 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
1952 JNIEXPORT void JNICALL
1953 Java_com_iotivity_jar_caleinterface_CALeGattDescriptorReadCallback(JNIEnv *env, jobject obj,
1954 jobject gatt, jobject descriptor,
1957 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorReadCallback - status %d: ", status);
1961 * Class: com_iotivity_jar_caleinterface
1962 * Method: CALeGattDescriptorWriteCallback
1963 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
1965 JNIEXPORT void JNICALL
1966 Java_com_iotivity_jar_caleinterface_CALeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
1968 jobject descriptor, jint status)
1970 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
1974 * Class: com_iotivity_jar_caleinterface
1975 * Method: CALeGattReliableWriteCompletedCallback
1976 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
1978 JNIEXPORT void JNICALL
1979 Java_com_iotivity_jar_caleinterface_CALeGattReliableWriteCompletedCallback(JNIEnv *env, jobject obj,
1983 OIC_LOG_V(DEBUG, TAG, "CALeGattReliableWriteCompletedCallback - status %d: ", status);
1987 * Class: com_iotivity_jar_caleinterface
1988 * Method: CALeGattReadRemoteRssiCallback
1989 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
1991 JNIEXPORT void JNICALL
1992 Java_com_iotivity_jar_caleinterface_CALeGattReadRemoteRssiCallback(JNIEnv *env, jobject obj,
1993 jobject gatt, jint rssi,
1996 OIC_LOG_V(DEBUG, TAG, "CALeGattReadRemoteRssiCallback - rssi %d, status %d: ", rssi, status);