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