Fixed klockwork memory leaks and modified the logs
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / caleclient.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <jni.h>
4
5 #include "calecore.h"
6 #include "caleserver.h"
7 #include "caleutils.h"
8
9 #include "logger.h"
10 #include "oic_malloc.h"
11 #include "uthreadpool.h" /* for thread pool */
12 #include "umutex.h"
13 #include "uarraylist.h"
14 #include "com_iotivity_jar_CALeInterface.h"
15
16 //#define DEBUG_MODE
17 #define TAG PCF("CA_LE_CLIENT")
18
19 static const char *METHODID_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;";
20 static const char *METHODID_STRINGNONPARAM = "()Ljava/lang/String;";
21 static const char *CLASSPATH_BT_ADPATER = "android/bluetooth/BluetoothAdapter";
22 static const char *CLASSPATH_BT_UUID = "java/util/UUID";
23 static const char *CLASSPATH_BT_GATT = "android/bluetooth/BluetoothGatt";
24
25 static const char *IOTIVITY_GATT_SERVIE_UUID = "713d0000-503e-4c75-ba94-3148f18d941e";
26 static const char *IOTIVITY_GATT_TX_UUID = "713d0003-503e-4c75-ba94-3148f18d941e";
27 static const char *IOTIVITY_GATT_RX_UUID = "713d0002-503e-4c75-ba94-3148f18d941e";
28
29 static const uint32_t STATE_CONNECTED = 2;
30 static const uint32_t STATE_DISCONNECTED = 0;
31 static const uint32_t GATT_SUCCESS = 0;
32
33 static const uint32_t MAX_PDU_BUFFER = 1400;
34
35 JavaVM *g_jvm;
36 static u_arraylist_t *gdeviceList = NULL;
37 static u_arraylist_t *gGattObjectList = NULL;
38 static CAPacketReceiveCallback gPacketReceiveCallback = NULL;
39 static u_thread_pool_t gThreadPoolHandle = NULL;
40 static jobject gLeScanCallback;
41 static jobject gLeGattCallback;
42 static jobject gContext;
43 static jobjectArray gUUIDList;
44 static jboolean gIsStartServer;
45 static jboolean gIsFinishSendData;
46
47 static jbyteArray gSendBuffer;
48 static uint32_t gTargetCnt = 0;
49 static uint32_t gCurrentSentCnt = 0;
50
51 /** mutex for synchrnoization **/
52 static u_mutex gThreadMutex;
53 /** conditional mutex for synchrnoization **/
54 static u_cond gThreadCond;
55
56 ////////////////////////////////////////////////////////////////////////////////////////////////////
57 //FIXME getting context
58 void CALEClientJNISetContext(JNIEnv *env, jobject context)
59 {
60     OIC_LOG_V(DEBUG, TAG, "CALEClientJNISetContext");
61
62     if(context == NULL)
63     {
64         OIC_LOG_V(DEBUG, TAG, "context is null");
65         return;
66     }
67
68     gContext = (*env)->NewGlobalRef(env, context);
69 }
70
71 void CALeCreateJniInterfaceObject()
72 {
73     OIC_LOG_V(DEBUG, TAG, "CALeCreateJniInterfaceObject");
74
75     jboolean isAttached = FALSE;
76     JNIEnv* env;
77     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
78     if(res != JNI_OK)
79     {
80         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
81         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
82
83         if(res != JNI_OK)
84         {
85             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
86             return;
87         }
88         isAttached = TRUE;
89     }
90
91     jclass LeJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CALeInterface");
92     if (!LeJniInterface)
93     {
94         OIC_LOG_V(DEBUG, TAG, "Could not get CALeInterface class");
95         return;
96     }
97
98     jmethodID LeInterfaceConstructorMethod =
99             (*env)->GetMethodID(env, LeJniInterface, "<init>", "(Landroid/content/Context;)V");
100     if (!LeInterfaceConstructorMethod)
101     {
102         OIC_LOG_V(DEBUG, TAG, "Could not get CALeInterface constructor method");
103         return;
104     }
105
106     (*env)->NewObject(env, LeJniInterface, LeInterfaceConstructorMethod, gContext);
107     OIC_LOG_V(DEBUG, TAG, "Create CALeInterface instance");
108
109     if(isAttached)
110         (*g_jvm)->DetachCurrentThread(g_jvm);
111 }
112
113 JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
114 {
115     OIC_LOG_V(DEBUG, TAG, "JNI_OnLoad in calecore");
116
117     JNIEnv* env;
118     if((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6) != JNI_OK)
119     {
120         return -1;
121     }
122     g_jvm = jvm;  /* cache the JavaVM pointer */
123
124     //JVM required for WifiCore to work with JNI interface
125     CAWiFiJniInit(jvm);
126     CALeServerJniInit(env, jvm);
127     CAEDRCoreJniInit(env, jvm);
128
129     return JNI_VERSION_1_6;
130 }
131
132 void JNI_OnUnload(JavaVM *jvm, void *reserved)
133 {
134     OIC_LOG_V(DEBUG, TAG, "JNI_OnUnload in calecore");
135
136     JNIEnv* env;
137     if((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6) != JNI_OK)
138     {
139         return;
140     }
141     g_jvm = 0;
142     return;
143 }
144
145 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeScanCallback(JNIEnv *env,
146         jobject obj, jobject callback)
147 {
148     OIC_LOG_V(DEBUG, TAG, "CARegisterLeScanCallback");
149
150     gLeScanCallback = (*env)->NewGlobalRef(env, callback);
151 }
152
153 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeGattCallback(JNIEnv *env,
154         jobject obj, jobject callback)
155 {
156     OIC_LOG_V(DEBUG, TAG, "CARegisterLeGattCallback");
157
158     gLeGattCallback = (*env)->NewGlobalRef(env, callback);
159 }
160
161 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeScanCallback (JNIEnv *env,
162         jobject obj, jobject device, jint rssi, jbyteArray scanRecord)
163 {
164     CANativeAddScanDeviceToList(env, device);
165 }
166
167 /*
168  * Class:     com_iotivity_jar_CALeInterface
169  * Method:    CALeGattConnectionStateChangeCallback
170  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
171  */
172 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattConnectionStateChangeCallback
173   (JNIEnv *env, jobject obj, jobject gatt, jint status, jint newstate)
174 {
175     OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status, newstate);
176
177     if(GATT_SUCCESS == status && STATE_CONNECTED == newstate)  // le connected
178     {
179         if(gatt) {
180             CANativeAddGattobjToList(env, gatt);
181             CANativeLEDiscoverServices(env, gatt);
182         }
183     }
184     else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate)  // le disconnected
185     {
186 //        CANativeLEStartScan();
187
188         if(gatt) {
189             //CANativeGattClose(env, gatt);  // 20150105
190             //CANativeRemoveGattObj(env, gatt); // 20150105
191         }
192     }
193     else  // other error
194     {
195         CANativeSendFinsih(env, gatt);
196     }
197 }
198
199 /*
200  * Class:     com_iotivity_jar_CALeInterface
201  * Method:    CALeGattServicesDiscoveredCallback
202  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
203  */
204 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattServicesDiscoveredCallback
205   (JNIEnv *env, jobject obj, jobject gatt, jint status)
206 {
207     OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
208
209     if(0 != status) // discovery error
210     {
211         CANativeSendFinsih(env, gatt);
212         return;
213     }
214
215     // read Characteristic
216 //    CANativeReadCharacteristic(env, gatt);
217
218     jboolean ret_rx = CANativeSetCharacteristicNoti(env, gatt, IOTIVITY_GATT_RX_UUID);
219     if(!ret_rx) // SetCharacteristicNoti is failed
220     {
221         CANativeSendFinsih(env, gatt);
222         return;
223     }
224
225 //        jstring data = (*env)->NewStringUTF(env, "HelloWorld");
226     jobject jni_obj_character = CANativeCreateGattCharacteristic(env, gatt, gSendBuffer);
227     if(!jni_obj_character)
228     {
229         CANativeSendFinsih(env, gatt);
230         return;
231     }
232
233     sleep(1);
234     jboolean ret = CANativeLESendData(env, gatt, jni_obj_character);
235     if(!ret)
236     {
237         CANativeSendFinsih(env, gatt);
238         return;
239     }
240 }
241
242 /*
243  * Class:     com_iotivity_jar_CALeInterface
244  * Method:    CALeGattCharacteristicReadCallback
245  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
246  */
247 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicReadCallback
248   (JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data, jint status)
249 {
250     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicReadCallback - status : %d", status);
251 }
252
253 /*
254  * Class:     com_iotivity_jar_CALeInterface
255  * Method:    CALeGattCharacteristicWritjclasseCallback
256  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
257  */
258 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicWriteCallback
259   (JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data, jint status)
260 {
261     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
262
263     jboolean isCopy;
264     char* wroteData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
265
266     jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
267     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
268
269     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
270
271 #ifdef DEBUG_MODE
272     CANativeSendFinsih(env, gatt);
273 #endif
274
275     if(0 != status)  // error case
276     {
277         CANativeSendFinsih(env, gatt);
278     }
279 }
280
281 /*
282  * Class:     com_iotivity_jar_CALeInterface
283  * Method:    CALeGattCharacteristicChangedCallback
284  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
285  */
286 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicChangedCallback
287   (JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data)
288 {
289     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
290
291     // get Byte Array and covert to char*
292     jint length = (*env)->GetArrayLength(env, data);
293
294     jboolean isCopy;
295     jbyte *jni_byte_responseData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
296
297     char responseData[MAX_PDU_BUFFER];
298     memset(responseData, 0, MAX_PDU_BUFFER);
299     strncpy(responseData, (char*)jni_byte_responseData, length);
300     responseData[length] = '\0';
301     (*env)->ReleaseByteArrayElements(env, data, (jbyte*)jni_byte_responseData, JNI_ABORT);
302
303     jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
304     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
305
306     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %s, %d", responseData, length);
307
308     // callback
309     gPacketReceiveCallback(address, responseData);
310
311     // LE disconnect and finish BLE write routine
312     CANativeSendFinsih(env, gatt);
313 }
314
315 /*
316  * Class:     com_iotivity_jar_CALeInterface
317  * Method:    CALeGattDescriptorReadCallback
318  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
319  */
320 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorReadCallback
321   (JNIEnv *env, jobject obj, jobject gatt, jobject descriptor, jint status)
322 {
323     OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorReadCallback - status %d: ", status);
324 }
325
326 /*
327  * Class:     com_iotivity_jar_CALeInterface
328  * Method:    CALeGattDescriptorWriteCallback
329  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
330  */
331 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorWriteCallback
332   (JNIEnv *env, jobject obj, jobject gatt, jobject descriptor, jint status)
333 {
334     OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
335 }
336
337 /*
338  * Class:     com_iotivity_jar_CALeInterface
339  * Method:    CALeGattReliableWriteCompletedCallback
340  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
341  */
342 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReliableWriteCompletedCallback
343   (JNIEnv *env, jobject obj, jobject gatt, jint status)
344 {
345     OIC_LOG_V(DEBUG, TAG, "CALeGattReliableWriteCompletedCallback - status %d: ", status);
346 }
347
348 /*
349  * Class:     com_iotivity_jar_CALeInterface
350  * Method:    CALeGattReadRemoteRssiCallback
351  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
352  */
353 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReadRemoteRssiCallback
354   (JNIEnv *env, jobject obj, jobject gatt, jint rssi, jint status)
355 {
356     OIC_LOG_V(DEBUG, TAG, "CALeGattReadRemoteRssiCallback - rssi %d,  status %d: ", rssi, status);
357 }
358
359
360 void CALEInitialize(u_thread_pool_t handle)
361 {
362     OIC_LOG(DEBUG, TAG, "CALEInitialize");
363
364     gThreadPoolHandle = handle;
365
366     // init mutex for send logic
367     gThreadMutex = u_mutex_new();
368     gThreadCond = u_cond_new();
369
370     CANativeCreateUUIDList();
371
372     CALeCreateJniInterfaceObject(); /* create java CALeInterface instance*/
373 }
374
375 void CALETerminate()
376 {
377     OIC_LOG(DEBUG, TAG, "CALETerminate");
378
379     jboolean isAttached = FALSE;
380     JNIEnv* env;
381     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
382     if(res != JNI_OK)
383     {
384         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
385         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
386
387         if(res != JNI_OK)
388         {
389             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
390             return;
391         }
392         isAttached = TRUE;
393     }
394
395     CANativeLEDisconnectAll(env);
396
397     if(gLeScanCallback)
398     {
399         CANativeLEStopScanImpl(env, gLeScanCallback);
400         sleep(1);
401     }
402
403     if(gLeScanCallback)
404     {
405         (*env)->DeleteGlobalRef(env, gLeScanCallback);
406     }
407
408     if(gLeGattCallback)
409     {
410         (*env)->DeleteGlobalRef(env, gLeGattCallback);
411     }
412
413     if(gContext)
414     {
415         (*env)->DeleteGlobalRef(env, gContext);
416     }
417
418     if(gSendBuffer)
419     {
420         (*env)->DeleteGlobalRef(env, gSendBuffer);
421     }
422
423     if(gUUIDList)
424     {
425         (*env)->DeleteGlobalRef(env, gUUIDList);
426     }
427
428     CANativeRemoveAllDevices(env);
429     CANativeRemoveAllGattObjsList(env);
430     gIsStartServer = FALSE;
431     gIsFinishSendData = FALSE;
432
433     if(isAttached)
434         (*g_jvm)->DetachCurrentThread(g_jvm);
435
436     // delete mutex object
437     u_mutex_free(gThreadMutex);
438     gThreadMutex = NULL;
439     u_cond_signal(gThreadCond);
440     u_cond_free(gThreadCond);
441 }
442
443 void CANativeSendFinsih(JNIEnv *env, jobject gatt)
444 {
445     OIC_LOG_V(DEBUG, TAG, "CANativeSendFinsih");
446
447     if(gatt)
448     {
449         CANativeLEDisconnect(env, gatt);
450     }
451     CANativeupdateSendCnt(env);
452 }
453
454 int32_t CALESendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
455 {
456     OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessage(%s, %s)", address, data);
457
458     CALESendUnicastMessageImpl(address, data, dataLen);
459     return 0;
460 }
461
462 int32_t CALESendMulticastMessage(const char* data, uint32_t dataLen)
463 {
464     OIC_LOG_V(DEBUG, TAG, "CALESendMulticastMessage(%s)", data);
465
466     jboolean isAttached = FALSE;
467     JNIEnv* env;
468     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
469     if(res != JNI_OK)
470     {
471         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
472         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
473
474         if(res != JNI_OK)
475         {
476             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
477             return 0;
478         }
479         isAttached = TRUE;
480     }
481
482     CALESendMulticastMessageImpl(env, data, dataLen);
483
484     if(isAttached)
485         (*g_jvm)->DetachCurrentThread(g_jvm);
486
487     return 1;
488 }
489
490 int32_t CALEStartUnicastServer(const char* address)
491 {
492     OIC_LOG_V(DEBUG, TAG, "CALEStartUnicastServer(%s)", address);
493
494     return 0;
495 }
496
497 int32_t CALEStartMulticastServer()
498 {
499     OIC_LOG_V(DEBUG, TAG, "CALEStartMulticastServer");
500
501     if(gIsStartServer)
502     {
503         OIC_LOG_V(DEBUG, TAG, "server is already started..it will be skipped");
504         return 0;
505     }
506
507     jboolean isAttached = FALSE;
508     JNIEnv* env;
509     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
510     if(res != JNI_OK)
511     {
512         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
513         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
514
515         if(res != JNI_OK)
516         {
517             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
518             return 0;
519         }
520         isAttached = TRUE;
521     }
522
523     gIsStartServer = TRUE;
524
525     CANativeLEStartScan();
526
527     if(isAttached)
528         (*g_jvm)->DetachCurrentThread(g_jvm);
529
530     return 0;
531 }
532
533 int32_t CALEStopUnicastServer(int32_t serverID)
534 {
535     OIC_LOG(DEBUG, TAG, "CALEStopUnicastServer");
536
537     return 0;
538 }
539
540 int32_t CALEStopMulticastServer(int32_t serverID)
541 {
542     OIC_LOG(DEBUG, TAG, "CALEStopMulticastServer");
543     gIsStartServer = FALSE;
544     CANativeLEStopScan();
545     return 0;
546 }
547
548 void CALESetCallback(CAPacketReceiveCallback callback)
549 {
550     gPacketReceiveCallback = callback;
551 }
552
553 CAResult_t CALEGetInterfaceInfo(char **address)
554 {
555     CALEGetLocalAddress(address);
556     return CA_STATUS_OK;
557 }
558
559 void CALEGetLocalAddress(char** address)
560 {
561     jboolean isAttached = FALSE;
562     JNIEnv* env;
563     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
564     if(res != JNI_OK)
565     {
566         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
567         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
568         if(res != JNI_OK)
569         {
570             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
571             return;
572         }
573         isAttached = TRUE;
574     }
575
576     jstring jni_address = CALEGetLocalDeviceAddress(env);
577     if(jni_address)
578     {
579         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
580         *address = (char*)OICMalloc(strlen(localAddress) + 1);
581         if (*address == NULL)
582         {
583             return;
584         }
585         memcpy(*address, localAddress, strlen(localAddress));
586     }
587
588     OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
589     if(isAttached)
590         (*g_jvm)->DetachCurrentThread(g_jvm);
591 }
592
593 int32_t CALESendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen)
594 {
595     OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessageImpl, address: %s, data: %s", address, data);
596
597     jboolean isAttached = FALSE;
598     JNIEnv* env;
599     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
600     if(res != JNI_OK)
601     {
602         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
603         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
604         if(res != JNI_OK)
605         {
606             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
607             return 0;
608         }
609         isAttached = TRUE;
610     }
611
612     OIC_LOG(DEBUG, TAG, "[BLE][Native] set byteArray for data");
613     if(gSendBuffer)
614     {
615         (*env)->DeleteGlobalRef(env, gSendBuffer);
616     }
617     jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
618     (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data);
619     gSendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
620
621     // connect to gatt server
622     CANativeLEStopScanImpl(env, gLeScanCallback);
623     sleep(1);
624
625     jobject jni_obj_bluetoothDevice = NULL;
626     if(gContext && gdeviceList)
627     {
628         jint index;
629         for (index = 0; index < u_arraylist_length(gdeviceList); index++)
630         {
631             jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
632             if(!jarrayObj)
633             {
634                 OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
635                 return 0;
636             }
637
638             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
639             if(!jni_setAddress)
640             {
641                 OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
642                 return 0;
643             }
644             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
645
646             if(!strcmp(setAddress, address))
647             {
648                 jni_obj_bluetoothDevice = jarrayObj;
649                 break;
650             }
651         }
652
653         if(jni_obj_bluetoothDevice)
654         {
655             jboolean autoConnect = FALSE;
656             CANativeLEConnect(env, jni_obj_bluetoothDevice, gContext, autoConnect, gLeGattCallback);
657         }
658     }
659
660     if(isAttached)
661         (*g_jvm)->DetachCurrentThread(g_jvm);
662
663     return 1;
664 }
665
666 int32_t CALESendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
667 {
668     OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
669
670     if(!gdeviceList)
671     {
672         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
673         return 0;
674     }
675     OIC_LOG(DEBUG, TAG, "set wait");
676
677
678     gIsFinishSendData = FALSE;
679
680     OIC_LOG(DEBUG, TAG, "[BLE][Native] set byteArray for data");
681     if(gSendBuffer)
682     {
683         (*env)->DeleteGlobalRef(env, gSendBuffer);
684     }
685     jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
686     (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data);
687     gSendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
688
689     // connect to gatt server
690     CANativeLEStopScanImpl(env, gLeScanCallback);
691     sleep(1);
692
693     // reset gatt list
694     CANativeRemoveAllGattObjsList(env);
695     CANativeCreateGattObjList(env);
696
697     gTargetCnt = u_arraylist_length(gdeviceList);
698
699     jint index = 0;
700
701     while (index < u_arraylist_length(gdeviceList)) {
702         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
703         if(!jarrayObj)
704         {
705             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
706             continue;
707         }
708
709         if(0 <= CANativeLEConnect(env, jarrayObj, gContext, FALSE, gLeGattCallback))
710         {
711             // connection failure
712             index++;
713         }
714         sleep(1);
715     }
716
717     // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
718     if(!gIsFinishSendData)
719     {
720         u_mutex_lock(gThreadMutex);
721         u_cond_wait(gThreadCond, gThreadMutex);
722         OIC_LOG(DEBUG, TAG, "unset wait");
723         u_mutex_unlock(gThreadMutex);
724     }
725
726     // start LE Scan again
727 #ifdef DEBUG_MODE
728     CANativeLEStartScan();
729 #endif
730
731     return 1;
732 }
733
734 jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt)
735 {
736     if(!gatt)
737     {
738         OIC_LOG(DEBUG, TAG, "[BLE][Native] gatt is null");
739         return NULL;
740     }
741
742     jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
743     if(!jni_cid_gattdevice_list)
744     {
745         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_gattdevice_list is null");
746         return NULL;
747     }
748
749     jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
750             "()Landroid/bluetooth/BluetoothDevice;");
751     if(!jni_mid_getDevice)
752     {
753         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getDevice is null");
754         return NULL;
755     }
756
757     jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
758     if(!jni_obj_device)
759     {
760         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_device is null");
761         return NULL;
762     }
763
764     jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
765     if(!jni_address)
766     {
767         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
768         return NULL;
769     }
770
771     return jni_address;
772 }
773
774 /**
775  * BLE layer
776  */
777 void CANativeGattClose(JNIEnv *env, jobject bluetoothGatt)
778 {
779     // GATT CLOSE
780     OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT CLOSE");
781
782     // get BluetoothGatt class
783     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
784     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
785     if(!jni_cid_BluetoothGatt)
786     {
787         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
788         return;
789     }
790
791     jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close","()V");
792     if(!jni_mid_closeGatt)
793     {
794         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_closeGatt is null");
795         return;
796     }
797
798     // call disconnect gatt method
799     OIC_LOG(DEBUG, TAG, "[BLE][Native] request close Gatt");
800     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
801 }
802
803 void CANativeLEStartScan()
804 {
805     if(!gIsStartServer)
806     {
807         OIC_LOG_V(DEBUG, TAG, "server is not started yet..scan will be passed");
808         return;
809     }
810
811     jboolean isAttached = FALSE;
812     JNIEnv* env;
813     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
814     if(res != JNI_OK)
815     {
816         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
817
818         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
819         if(res != JNI_OK)
820         {
821             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
822             return;
823         }
824         isAttached = TRUE;
825     }
826
827     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStartScan");
828
829     // scan gatt server with UUID
830     if(gLeScanCallback && gUUIDList)
831     {
832         CANativeLEStartScanWithUUIDImpl(env, gUUIDList, gLeScanCallback);
833     }
834
835     if(isAttached)
836         (*g_jvm)->DetachCurrentThread(g_jvm);
837
838 }
839
840 void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
841 {
842     if(!CALEIsEnableBTAdapter(env))
843     {
844         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
845         return;
846     }
847
848     // get default bt adapter class
849     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
850     if(!jni_cid_BTAdapter)
851     {
852         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
853         return;
854     }
855
856     // get remote bt adapter method
857     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
858     if(!jni_mid_getDefaultAdapter)
859     {
860         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
861         return;
862     }
863
864     // get start le scan method
865     jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
866             "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
867     if(!jni_mid_startLeScan)
868     {
869         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
870         return;
871     }
872
873     // gat bt adapter object
874     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
875     if(!jni_obj_BTAdapter)
876     {
877         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
878         return;
879     }
880
881     // call start le scan method
882     jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_startLeScan, callback);
883     if(!jni_obj_startLeScan)
884     {
885         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan is failed");
886         return;
887     }
888     else
889     {
890         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan is started");
891     }
892 }
893
894 jobject CANativeGetUUIDObject(JNIEnv *env, const char* uuid)
895 {
896     // setting UUID
897     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
898     if(!jni_cid_uuid)
899     {
900         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_uuid is null");
901         return NULL;
902     }
903
904     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
905     if(!jni_mid_fromString)
906     {
907         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_fromString is null");
908         return NULL;
909     }
910
911     jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
912     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid);
913     if(!jni_obj_uuid)
914     {
915         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_uuid is null");
916         return NULL;
917     }
918
919     return jni_obj_uuid;
920 }
921
922 void CANativeLEStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
923 {
924     // get default bt adapter class
925     OIC_LOG(DEBUG, TAG, "[BLE][Native] get default bt adapter class");
926
927     if(!CALEIsEnableBTAdapter(env))
928     {
929         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
930         return;
931     }
932
933     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
934     if(!jni_cid_BTAdapter)
935     {
936         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
937         return;
938     }
939
940     // get remote bt adapter method
941     OIC_LOG(DEBUG, TAG, "[BLE][Native] get remote bt adapter method");
942     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
943     if(!jni_mid_getDefaultAdapter)
944     {
945         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
946         return;
947     }
948
949     // get start le scan method
950     OIC_LOG(DEBUG, TAG, "[BLE][Native] get start le scan method");
951     jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
952             "([Ljava/util/UUID;Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
953     if(!jni_mid_startLeScan)
954     {
955         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
956         return;
957     }
958
959     // get bt adapter object
960     OIC_LOG(DEBUG, TAG, "[BLE][Native] get bt adapter object");
961     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
962     if(!jni_obj_BTAdapter)
963     {
964         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
965         return;
966     }
967
968     // call start le scan method
969     OIC_LOG(DEBUG, TAG, "[BLE][Native] call start le scan service method");
970     jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_startLeScan, uuids, callback);
971     if(!jni_obj_startLeScan)
972     {
973         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan With UUID is failed");
974         return;
975     }
976     else
977     {
978         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan With UUID is started");
979     }
980 }
981
982 void CANativeLEStopScan()
983 {
984     jboolean isAttached = FALSE;
985     JNIEnv* env;
986     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
987     if(res != JNI_OK)
988     {
989         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
990         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
991         if(res != JNI_OK)
992         {
993             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
994             return;
995         }
996         isAttached = TRUE;
997     }
998
999     CANativeLEStopScanImpl(env, gLeScanCallback);
1000
1001     if(isAttached)
1002         (*g_jvm)->DetachCurrentThread(g_jvm);
1003
1004 }
1005
1006 void CANativeLEStopScanImpl(JNIEnv *env, jobject callback)
1007 {
1008     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStopScan");
1009
1010     if(!CALEIsEnableBTAdapter(env))
1011     {
1012         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1013         return;
1014     }
1015
1016     // get default bt adapter class
1017     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
1018     if(!jni_cid_BTAdapter)
1019     {
1020         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
1021         return;
1022     }
1023
1024     // get remote bt adapter method
1025     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
1026     if(!jni_mid_getDefaultAdapter)
1027     {
1028         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
1029         return;
1030     }
1031
1032     // get start le scan method
1033     jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1034             "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)V");
1035     if(!jni_mid_stopLeScan)
1036     {
1037         OIC_LOG(DEBUG, TAG, "[BLE][Native] stopLeScan: jni_mid_stopLeScan is null");
1038         return;
1039     }
1040
1041     // gat bt adapter object
1042     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
1043     if(!jni_obj_BTAdapter)
1044     {
1045         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
1046         return;
1047     }
1048
1049     OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to stop LE Scan");
1050     // call start le scan method
1051     (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1052 }
1053
1054 int32_t CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context,
1055         jboolean autoconnect, jobject callback)
1056 {
1057     if(!CALEIsEnableBTAdapter(env))
1058     {
1059         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1060         return 0;
1061     }
1062
1063     jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1064     const char * addr = (*env)->GetStringUTFChars(env, jni_address, NULL);
1065     OIC_LOG_V(DEBUG, TAG, "[BLE][Native] request connectGatt to %s", addr);
1066
1067     // GATT CONNECT
1068
1069     // get BluetoothDevice class
1070     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothDevice class");
1071     jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1072     if(!jni_cid_BluetoothDevice)
1073     {
1074         OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: jni_cid_BluetoothDevice is null");
1075         return 0;
1076     }
1077
1078     // get connectGatt method
1079     OIC_LOG(DEBUG, TAG, "[BLE][Native] get connectGatt method");
1080     jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice,
1081             "connectGatt",
1082             "(Landroid/content/Context;ZLandroid/bluetooth/BluetoothGattCallback;)Landroid/bluetooth/BluetoothGatt;");
1083     if(!jni_mid_connectGatt)
1084     {
1085         OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: jni_mid_connectGatt is null");
1086         return 0;
1087     }
1088
1089     OIC_LOG(DEBUG, TAG, "[BLE][Native] Call object method - connectGatt");
1090     jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1091             jni_mid_connectGatt, NULL, autoconnect, callback);
1092     if(!jni_obj_connectGatt)
1093     {
1094         OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - connectGatt was failed.obj will be removed");
1095         CANativeRemoveDevice(env, jni_address);
1096         CANativeupdateSendCnt(env);
1097         return -1;
1098     }
1099     else
1100     {
1101         OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - connecting..");
1102     }
1103     return 1;
1104 }
1105
1106 void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt)
1107 {
1108     if(!CALEIsEnableBTAdapter(env))
1109     {
1110         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1111         return;
1112     }
1113
1114     // GATT DISCONNECT
1115     OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT DISCONNECT");
1116
1117     // get BluetoothGatt class
1118     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt classjobject bluetoothGatt");
1119     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1120     if(!jni_cid_BluetoothGatt)
1121     {
1122         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1123         return;
1124     }
1125
1126     OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt disconnect method");
1127     jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1128             "disconnect","()V");
1129     if(!jni_mid_disconnectGatt)
1130     {
1131         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_disconnectGatt is null");
1132         return;
1133     }
1134
1135     // call disconnect gatt method
1136     OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request disconnectGatt");
1137     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1138
1139 }
1140
1141 void CANativeLEDisconnectAll(JNIEnv *env)
1142 {
1143     OIC_LOG_V(DEBUG, TAG, "CANativeLEDisconnectAll");
1144
1145     if(!gGattObjectList)
1146     {
1147         OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
1148         return;
1149     }
1150
1151     jint index;
1152     for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
1153     {
1154         jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
1155         if(!jarrayObj)
1156         {
1157             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1158             return;
1159         }
1160         CANativeLEDisconnect(env, jarrayObj);
1161     }
1162
1163     OICFree(gGattObjectList);
1164     gGattObjectList = NULL;
1165     return;
1166 }
1167
1168 void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1169 {
1170     if(!CALEIsEnableBTAdapter(env))
1171     {
1172         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1173         return;
1174     }
1175
1176     // GATT SERVICE DISCOVERY
1177     OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT SERVICE DISCOVERY");
1178
1179     // get BluetoothGatt class
1180     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
1181     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1182     if(!jni_cid_BluetoothGatt)
1183     {
1184         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1185         return;
1186     }
1187
1188     OIC_LOG(DEBUG, TAG, "[BLE][Native] discovery gatt services method");
1189     jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1190             "discoverServices","()Z");
1191     if(!jni_mid_discoverServices)
1192     {
1193         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_discoverServices is null");
1194         return;
1195     }
1196     // call disconnect gatt method
1197     OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request discovery gatt services");
1198     (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1199 }
1200
1201 jboolean CANativeLESendData(JNIEnv *env, jobject bluetoothGatt, jobject gattCharacteristic)
1202 {
1203     if(!CALEIsEnableBTAdapter(env))
1204     {
1205         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1206         return FALSE;
1207     }
1208
1209     // WRITE GATT CHARACTERISTIC
1210     OIC_LOG(DEBUG, TAG, "[BLE][Native] WRITE GATT CHARACTERISTIC");
1211
1212     // get BluetoothGatt class
1213     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
1214     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1215     if(!jni_cid_BluetoothGatt)
1216     {
1217         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1218         return FALSE;
1219     }
1220
1221     OIC_LOG(DEBUG, TAG, "[BLE][Native] write characteristic method");
1222     jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1223             "writeCharacteristic", "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
1224     if(!jni_mid_writeCharacteristic)
1225     {
1226         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_writeCharacteristic is null");
1227         return FALSE;
1228     }
1229
1230     // call disconnect gatt method
1231     OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to write gatt characteristic");
1232     jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeCharacteristic, gattCharacteristic);
1233     if(ret)
1234     {
1235         OIC_LOG(DEBUG, TAG, "[BLE][Native] writeCharacteristic is success");
1236     }
1237     else
1238     {
1239         OIC_LOG(DEBUG, TAG, "[BLE][Native] writeCharacteristic is failed");
1240         return FALSE;
1241     }
1242     return TRUE;
1243 }
1244
1245 void CANativeReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1246 {
1247
1248    if(!CALEIsEnableBTAdapter(env))
1249    {
1250        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1251        return;
1252    }
1253
1254    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1255    if(!jni_cid_BluetoothGatt)
1256    {
1257        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1258        return;
1259    }
1260
1261    jstring jni_uuid = (*env)->NewStringUTF(env, IOTIVITY_GATT_RX_UUID);
1262    jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1263    if(!jni_obj_GattCharacteristic)
1264    {
1265        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1266        return;
1267    }
1268
1269    OIC_LOG(DEBUG, TAG, "[BLE][Native] read characteristic method");
1270    jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "readCharacteristic", "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
1271    if(!jni_mid_readCharacteristic)
1272    {
1273        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_readCharacteristic is null");
1274        return;
1275    }
1276
1277    // call disconnect gatt method
1278    OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to read gatt characteristic");
1279    jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic, jni_obj_GattCharacteristic);
1280    if(ret)
1281    {
1282        OIC_LOG(DEBUG, TAG, "[BLE][Native] readCharacteristic is success");
1283    }
1284    else
1285    {
1286        OIC_LOG(DEBUG, TAG, "[BLE][Native] readCharacteristic is failed");
1287    }
1288 }
1289
1290 jboolean CANativeSetCharacteristicNoti(JNIEnv *env, jobject bluetoothGatt, const char* uuid)
1291 {
1292     if(!CALEIsEnableBTAdapter(env))
1293     {
1294         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1295         return FALSE;
1296     }
1297
1298     // get BluetoothGatt class
1299     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeSetCharacteristicNoti");
1300     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1301     if(!jni_cid_BluetoothGatt)
1302     {
1303         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1304         return FALSE;
1305     }
1306
1307     jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1308     jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1309     if(!jni_obj_GattCharacteristic)
1310     {
1311         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1312         return FALSE;
1313     }
1314
1315     // set Characteristic Notification
1316     jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "setCharacteristicNotification",
1317             "(Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
1318     if(!jni_mid_setNotification)
1319     {
1320         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getService is null");
1321         return FALSE;
1322     }
1323
1324     jboolean enable = TRUE;
1325     jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification, jni_obj_GattCharacteristic, enable);
1326     if(1 == ret)
1327     {
1328         OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - setCharacteristicNotification is success");
1329         return TRUE;
1330     }
1331     else
1332     {
1333         OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - setCharacteristicNotification is failed");
1334         return FALSE;
1335     }
1336 }
1337
1338 jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1339 {
1340     if(!CALEIsEnableBTAdapter(env))
1341     {
1342         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1343         return NULL;
1344     }
1345
1346     // get BluetoothGatt class
1347     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeGetGattService");
1348     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1349     if(!jni_cid_BluetoothGatt)
1350     {
1351         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1352         return NULL;
1353     }
1354
1355     jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "getService",
1356             "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1357     if(!jni_mid_getService)
1358     {
1359         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getService is null");
1360         return NULL;
1361     }
1362
1363     jobject jni_obj_service_uuid = CANativeGetUUIDObject(env, IOTIVITY_GATT_SERVIE_UUID);
1364     if(!jni_obj_service_uuid)
1365     {
1366         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_service_uuid is null");
1367         return NULL;
1368     }
1369
1370     // get bluetooth gatt service
1371     OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get service");
1372     jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService, jni_obj_service_uuid);
1373
1374     // get bluetooth gatt service class
1375     jclass jni_cid_BluetoothGattService = (*env)->FindClass(env, "android/bluetooth/BluetoothGattService");
1376     if(!jni_cid_BluetoothGattService)
1377     {
1378         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGattService is null");
1379         return NULL;
1380     }
1381
1382     OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt getCharacteristic method");
1383     jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService, "getCharacteristic",
1384             "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
1385     if(!jni_mid_getCharacteristic)
1386     {
1387         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getCharacteristic is null");
1388         return NULL;
1389     }
1390
1391     const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1392     jobject jni_obj_tx_uuid = CANativeGetUUIDObject(env, uuid);
1393     if(!jni_obj_tx_uuid)
1394     {
1395         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_tx_uuid is null");
1396         return NULL;
1397     }
1398
1399     OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get Characteristic");
1400     jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService, jni_mid_getCharacteristic, jni_obj_tx_uuid);
1401
1402     return jni_obj_GattCharacteristic;
1403 }
1404
1405 jobject CANativeCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1406 {
1407     if(!CALEIsEnableBTAdapter(env))
1408     {
1409         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1410         return NULL;
1411     }
1412
1413     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattCharacteristic");
1414     jstring jni_uuid = (*env)->NewStringUTF(env, IOTIVITY_GATT_TX_UUID);
1415     jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1416     if(!jni_obj_GattCharacteristic)
1417     {
1418         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1419         return NULL;
1420     }
1421
1422     jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/BluetoothGattCharacteristic");
1423     if(!jni_cid_BTGattCharacteristic)
1424     {
1425         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
1426         return NULL;
1427     }
1428
1429     OIC_LOG(DEBUG, TAG, "[BLE][Native] set value in Characteristic");
1430     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1431             "([B)Z");
1432     if(!jni_mid_setValue)
1433     {
1434         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_setValue is null");
1435         return NULL;
1436     }
1437
1438     jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue, data);
1439     if(1 == ret)
1440     {
1441         OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value has been set");
1442         return jni_obj_GattCharacteristic;
1443     }
1444     else
1445     {
1446         OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value hasn't been set");
1447         return NULL;
1448     }
1449 }
1450
1451 jbyteArray CANativeGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1452 {
1453     if(!CALEIsEnableBTAdapter(env))
1454     {
1455         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1456         return NULL;
1457     }
1458
1459     jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/BluetoothGattCharacteristic");
1460     if(!jni_cid_BTGattCharacteristic)
1461     {
1462         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
1463         return NULL;
1464     }
1465
1466     OIC_LOG(DEBUG, TAG, "[BLE][Native] get value in Characteristic");
1467     jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1468             "()[B");
1469     if(!jni_mid_getValue)
1470     {
1471         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getValue is null");
1472         return NULL;
1473     }
1474
1475     jbyteArray jni_obj_data_array =  (*env)->CallObjectMethod(env, characteristic, jni_mid_getValue);
1476     return jni_obj_data_array;
1477 }
1478
1479
1480 void CANativeCreateUUIDList()
1481 {
1482     jboolean isAttached = FALSE;
1483     JNIEnv* env;
1484     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
1485     if(res != JNI_OK)
1486     {
1487         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
1488         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1489
1490         if(res != JNI_OK)
1491         {
1492             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
1493             return;
1494         }
1495         isAttached = TRUE;
1496     }
1497
1498     // create new object array
1499     jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1500     if(!jni_cid_uuid_list)
1501     {
1502         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_uuid_list is null");
1503         return;
1504     }
1505
1506     jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1, jni_cid_uuid_list, NULL);
1507     if(!jni_obj_uuid_list)
1508     {
1509         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_uuid_list is null");
1510         return;
1511     }
1512
1513     // remove previous list and create list again
1514     CANativeRemoveAllDevices(env);
1515     CANativeCreateScanDeviceList(env);
1516
1517     // make uuid list
1518     jobject jni_obj_uuid = CANativeGetUUIDObject(env, IOTIVITY_GATT_SERVIE_UUID);
1519     (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1520
1521     gUUIDList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1522
1523     if(isAttached)
1524         (*g_jvm)->DetachCurrentThread(g_jvm);
1525 }
1526
1527 void CANativeCreateScanDeviceList(JNIEnv *env)
1528 {
1529     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateScanDeviceList");
1530
1531     // create new object array
1532     if (gdeviceList == NULL)
1533     {
1534         OIC_LOG_V(DEBUG, TAG, "Create device list");
1535
1536         gdeviceList = u_arraylist_create();
1537     }
1538 }
1539
1540 void CANativeAddScanDeviceToList(JNIEnv *env, jobject device)
1541 {
1542     if(!device)
1543     {
1544         OIC_LOG(DEBUG, TAG, "[BLE][Native] device is null");
1545         return;
1546     }
1547
1548     if(!gdeviceList)
1549     {
1550         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdevice_list is null");
1551         return;
1552     }
1553
1554     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1555     if(!jni_remoteAddress)
1556     {
1557         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
1558         return;
1559     }
1560
1561     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1562
1563     if(!CANativeIsDeviceInList(env, remoteAddress)) {
1564         jobject gdevice = (*env)->NewGlobalRef(env, device);
1565         u_arraylist_add(gdeviceList, gdevice);
1566         OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
1567     }
1568 }
1569
1570 jboolean CANativeIsDeviceInList(JNIEnv *env, const char* remoteAddress){
1571     // get address value from device list
1572
1573     jint index;
1574     for (index = 0; index < u_arraylist_length(gdeviceList); index++)
1575     {
1576         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
1577         if(!jarrayObj)
1578         {
1579             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1580             return TRUE;
1581         }
1582
1583         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1584         if(!jni_setAddress)
1585         {
1586             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1587             return TRUE;
1588         }
1589
1590         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1591
1592         if(!strcmp(remoteAddress, setAddress))
1593         {
1594             OIC_LOG_V(DEBUG, TAG, "the device is already set");
1595             return TRUE;
1596         }
1597         else
1598         {
1599             continue;
1600         }
1601     }
1602
1603     OIC_LOG_V(DEBUG, TAG, "there are no the device in list. we can add");
1604     return FALSE;
1605 }
1606
1607 void CANativeRemoveAllDevices(JNIEnv *env)
1608 {
1609     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveAllDevices");
1610
1611     if(!gdeviceList)
1612     {
1613         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
1614         return;
1615     }
1616
1617     jint index;
1618     for (index = 0; index < u_arraylist_length(gdeviceList); index++)
1619     {
1620         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
1621         if(!jarrayObj)
1622         {
1623             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1624             return;
1625         }
1626         (*env)->DeleteGlobalRef(env, jarrayObj);
1627     }
1628
1629     OICFree(gdeviceList);
1630     gdeviceList = NULL;
1631     return;
1632 }
1633
1634 void CANativeRemoveDevice(JNIEnv *env, jstring address)
1635 {
1636     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveDevice");
1637
1638     if(!gdeviceList)
1639     {
1640         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
1641         return;
1642     }
1643
1644     jint index;
1645     for (index = 0; index < u_arraylist_length(gdeviceList); index++)
1646     {
1647         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
1648         if(!jarrayObj)
1649         {
1650             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1651             return;
1652         }
1653
1654         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1655         if(!jni_setAddress)
1656         {
1657             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1658             return;
1659         }
1660         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1661         const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
1662
1663         if(!strcmp(setAddress, remoteAddress))
1664         {
1665             OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
1666             (*env)->DeleteGlobalRef(env, jarrayObj);
1667
1668             CAReorderingDeviceList(index);
1669             return;
1670         }
1671     }
1672     OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
1673     return;
1674 }
1675
1676 void CAReorderingDeviceList(uint32_t index)
1677 {
1678     if (index >= gdeviceList->length)
1679     {
1680         return;
1681     }
1682
1683     if (index < gdeviceList->length - 1)
1684     {
1685         memmove(&gdeviceList->data[index], &gdeviceList->data[index + 1],
1686                 (gdeviceList->length - index - 1) * sizeof(void *));
1687     }
1688
1689     gdeviceList->size--;
1690     gdeviceList->length--;
1691 }
1692
1693 /**
1694  * Gatt Object List
1695  */
1696 void CANativeCreateGattObjList(JNIEnv *env)
1697 {
1698     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattObjList");
1699
1700     // create new object array
1701     if (gGattObjectList == NULL)
1702     {
1703         OIC_LOG_V(DEBUG, TAG, "Create Gatt object list");
1704
1705         gGattObjectList = u_arraylist_create();
1706     }
1707 }
1708
1709 void CANativeAddGattobjToList(JNIEnv *env, jobject gatt)
1710 {
1711     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeAddGattobjToList");
1712
1713     if(!gatt)
1714     {
1715         OIC_LOG(DEBUG, TAG, "[BLE][Native] gatt is null");
1716         return;
1717     }
1718
1719     if(!gGattObjectList)
1720     {
1721         OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
1722         return;
1723     }
1724
1725     jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
1726     if(!jni_remoteAddress)
1727     {
1728         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
1729         return;
1730     }
1731
1732     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1733
1734     if(!CANativeIsGattObjInList(env, remoteAddress))
1735     {
1736         jobject gGatt = (*env)->NewGlobalRef(env, gatt);
1737         u_arraylist_add(gGattObjectList, gGatt);
1738         OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
1739     }
1740 }
1741
1742 jboolean CANativeIsGattObjInList(JNIEnv *env, const char* remoteAddress)
1743 {
1744     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsGattObjInList");
1745
1746     jint index;
1747     for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
1748     {
1749
1750         jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
1751         if(!jarrayObj)
1752         {
1753             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1754             return TRUE;
1755         }
1756
1757         jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
1758         if(!jni_setAddress)
1759         {
1760             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1761             return TRUE;
1762         }
1763
1764         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1765
1766         if(!strcmp(remoteAddress, setAddress))
1767         {
1768             OIC_LOG_V(DEBUG, TAG, "the device is already set");
1769             return TRUE;
1770         }
1771         else
1772         {
1773             continue;
1774         }
1775     }
1776
1777     OIC_LOG_V(DEBUG, TAG, "there are no the gatt obejct in list. we can add");
1778     return FALSE;
1779 }
1780
1781 void CANativeRemoveAllGattObjsList(JNIEnv *env)
1782 {
1783     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveAllGattObjsList");
1784
1785     if(!gGattObjectList)
1786     {
1787         OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
1788         return;
1789     }
1790
1791     jint index;
1792     for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
1793     {
1794         jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
1795         if(!jarrayObj)
1796         {
1797             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1798             return;
1799         }
1800         (*env)->DeleteGlobalRef(env, jarrayObj);
1801     }
1802
1803     OICFree(gGattObjectList);
1804     gGattObjectList = NULL;
1805     return;
1806 }
1807
1808 void CANativeRemoveGattObj(JNIEnv *env, jobject gatt)
1809 {
1810     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveGattObj");
1811
1812     if(!gGattObjectList)
1813     {
1814         OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
1815         return;
1816     }
1817
1818     jint index;
1819     for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
1820     {
1821         jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
1822         if(!jarrayObj)
1823         {
1824             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1825             return;
1826         }
1827
1828         jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
1829         if(!jni_setAddress)
1830         {
1831             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1832             return;
1833         }
1834         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1835
1836         jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
1837         if(!jni_remoteAddress)
1838         {
1839             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
1840             return;
1841         }
1842         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1843
1844         if(!strcmp(setAddress, remoteAddress))
1845         {
1846             OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
1847             (*env)->DeleteGlobalRef(env, jarrayObj);
1848
1849             CAReorderingGattList(index);
1850             return;
1851         }
1852     }
1853     OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
1854     return;
1855 }
1856
1857 void CAReorderingGattList(uint32_t index)
1858 {
1859     if (index >= gGattObjectList->length)
1860     {
1861         return;
1862     }
1863
1864     if (index < gGattObjectList->length - 1)
1865     {
1866         memmove(&gGattObjectList->data[index], &gGattObjectList->data[index + 1],
1867                 (gGattObjectList->length - index - 1) * sizeof(void *));
1868     }
1869
1870     gGattObjectList->size--;
1871     gGattObjectList->length--;
1872 }
1873
1874 /**
1875  * Check Sent Count for remove gSendBuffer
1876  */
1877 void CANativeupdateSendCnt(JNIEnv *env)
1878 {
1879     // mutex lock
1880     u_mutex_lock(gThreadMutex);
1881
1882     gCurrentSentCnt++;
1883
1884     if(gTargetCnt <= gCurrentSentCnt)
1885     {
1886         gTargetCnt = 0;
1887         gCurrentSentCnt = 0;
1888
1889         if(gSendBuffer)
1890         {
1891             (*env)->DeleteGlobalRef(env, gSendBuffer);
1892             gSendBuffer = NULL;
1893         }
1894         // notity the thread
1895         u_cond_signal(gThreadCond);
1896         gIsFinishSendData = TRUE;
1897         OIC_LOG(DEBUG, TAG, "set signal for send data");
1898     }
1899     // mutex unlock
1900     u_mutex_unlock(gThreadMutex);
1901 }