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