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