[CA] [All] Klockwork , Prevent , Memory leaks fixed
[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         memcpy(*address, localAddress, strlen(localAddress));
573     }
574
575     OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
576     if(isAttached)
577         (*g_jvm)->DetachCurrentThread(g_jvm);
578 }
579
580 int32_t CALESendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen)
581 {
582     OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessageImpl, address: %s, data: %s", address, data);
583
584     jboolean isAttached = FALSE;
585     JNIEnv* env;
586     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
587     if(res != JNI_OK)
588     {
589         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
590         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
591         if(res != JNI_OK)
592         {
593             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
594             return 0;
595         }
596         isAttached = TRUE;
597     }
598
599     OIC_LOG(DEBUG, TAG, "[BLE][Native] set byteArray for data");
600     if(gSendBuffer)
601     {
602         (*env)->DeleteGlobalRef(env, gSendBuffer);
603     }
604     jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
605     (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data);
606     gSendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
607
608     // connect to gatt server
609     CANativeLEStopScanImpl(env, gLeScanCallback);
610     sleep(1);
611
612     jobject jni_obj_bluetoothDevice = NULL;
613     if(gContext && gdeviceList)
614     {
615         jint index;
616         for (index = 0; index < u_arraylist_length(gdeviceList); index++)
617         {
618             jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
619             if(!jarrayObj)
620             {
621                 OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
622                 return 0;
623             }
624
625             jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
626             if(!jni_setAddress)
627             {
628                 OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
629                 return 0;
630             }
631             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
632
633             if(!strcmp(setAddress, address))
634             {
635                 jni_obj_bluetoothDevice = jarrayObj;
636                 break;
637             }
638         }
639
640         if(jni_obj_bluetoothDevice)
641         {
642             jboolean autoConnect = FALSE;
643             CANativeLEConnect(env, jni_obj_bluetoothDevice, gContext, autoConnect, gLeGattCallback);
644         }
645     }
646
647     if(isAttached)
648         (*g_jvm)->DetachCurrentThread(g_jvm);
649
650     return 1;
651 }
652
653 int32_t CALESendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
654 {
655     OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
656
657     if(!gdeviceList)
658     {
659         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
660         return 0;
661     }
662     OIC_LOG(DEBUG, TAG, "set wait");
663
664
665     gIsFinishSendData = FALSE;
666
667     OIC_LOG(DEBUG, TAG, "[BLE][Native] set byteArray for data");
668     if(gSendBuffer)
669     {
670         (*env)->DeleteGlobalRef(env, gSendBuffer);
671     }
672     jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
673     (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data);
674     gSendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
675
676     // connect to gatt server
677     CANativeLEStopScanImpl(env, gLeScanCallback);
678     sleep(1);
679
680     // reset gatt list
681     CANativeRemoveAllGattObjsList(env);
682     CANativeCreateGattObjList(env);
683
684     gTargetCnt = u_arraylist_length(gdeviceList);
685
686     jint index = 0;
687
688     while (index < u_arraylist_length(gdeviceList)) {
689         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
690         if(!jarrayObj)
691         {
692             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
693             continue;
694         }
695
696         if(0 <= CANativeLEConnect(env, jarrayObj, gContext, FALSE, gLeGattCallback))
697         {
698             // connection failure
699             index++;
700         }
701         sleep(1);
702     }
703
704     // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
705     if(!gIsFinishSendData)
706     {
707         u_mutex_lock(gThreadMutex);
708         u_cond_wait(gThreadCond, gThreadMutex);
709         OIC_LOG(DEBUG, TAG, "unset wait");
710         u_mutex_unlock(gThreadMutex);
711     }
712
713     // start LE Scan again
714 #ifdef DEBUG_MODE
715     CANativeLEStartScan();
716 #endif
717
718     return 1;
719 }
720
721 /**
722  * BT common
723  */
724 jstring CANativeGetLocalDeviceAddress(JNIEnv* env)
725 {
726     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
727     if(!jni_cid_BTAdapter)
728     {
729         OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_cid_BTAdapter is null");
730         return NULL;
731     }
732
733     jmethodID jni_mid_getDefaultAdapter =
734             (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
735     if(!jni_mid_getDefaultAdapter)
736     {
737         OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_mid_getDefaultAdapter is null");
738         return NULL;
739     }
740
741     jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTAdapter, "getAddress", METHODID_STRINGNONPARAM);
742     if(!jni_mid_getAddress)
743     {
744         OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_mid_getAddress is null");
745         return NULL;
746     }
747
748     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
749     if(!jni_obj_BTAdapter)
750     {
751         OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_obj_BTAdapter is null");
752         return NULL;
753     }
754
755     jstring jni_str_address = (jstring)(*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_getAddress);
756     if(!jni_str_address)
757     {
758         OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_str_address is null");
759         return NULL;
760     }
761
762     return jni_str_address;
763 }
764
765 jobjectArray CANativeBondedDevices(JNIEnv *env)
766 {
767     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
768     if(!jni_cid_BTAdapter)
769     {
770         OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_cid_BTAdapter is null");
771         return NULL;
772     }
773
774     jmethodID jni_mid_getDefaultAdapter =
775             (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
776
777     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
778     if(!jni_obj_BTAdapter)
779     {
780         OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: bluetooth adapter is null");
781         return NULL;
782     }
783
784     // Get a list of currently paired devices
785     jmethodID jni_mid_getBondedDevices = (*env)->GetMethodID(env, jni_cid_BTAdapter,
786             "getBondedDevices", "()Ljava/util/Set;");
787     if(!jni_mid_getBondedDevices)
788     {
789         OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_mid_getBondedDevicesr is null");
790         return NULL;
791     }
792
793     jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_getBondedDevices);
794     if(!jni_obj_setPairedDevices)
795     {
796         OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_obj_setPairedDevices is null");
797         return NULL;
798     }
799
800     // Convert the set to an object array
801     // object[] array = Set<BluetoothDevice>.toArray();
802     jclass jni_cid_Set = (*env)->FindClass(env,  "java/util/Set");
803     jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray", "()[Ljava/lang/Object;");
804
805     if(!jni_mid_toArray)
806     {
807         OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_mid_toArray is null");
808         return NULL;
809     }
810
811     jobjectArray jni_arrayPairedDevices = (jobjectArray)((*env)->CallObjectMethod(env,
812             jni_obj_setPairedDevices, jni_mid_toArray));
813     if(!jni_arrayPairedDevices)
814     {
815         OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_arrayPairedDevices is null");
816         return NULL;
817     }
818
819     return jni_arrayPairedDevices;
820 }
821
822 jint CANativeGetBTStateOnInfo(JNIEnv *env)
823 {
824     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
825     if(!jni_cid_BTAdapter)
826     {
827         OIC_LOG(DEBUG, TAG, "[BLE][Native] getBTStateOnInfo: jni_cid_BTAdapter is null");
828         return -1;
829     }
830
831     jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
832     if (jni_fid_stateon == 0)
833     {
834         OIC_LOG(DEBUG, TAG, "[BLE][Native] get_field_state is 0");
835         return -1;
836     }
837     jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
838
839     OIC_LOG_V(DEBUG, TAG, "[BLE][Native] bluetooth STATE_ON state integer value : %d", jni_int_val);
840
841     return jni_int_val;
842 }
843
844 jboolean CANativeIsEnableBTAdapter(JNIEnv *env)
845 {
846     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
847     if(!jni_cid_BTAdapter)
848     {
849         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTAdapter: jni_cid_BTAdapter is null");
850         return FALSE;
851     }
852
853     jmethodID jni_mid_getDefaultAdapter =
854             (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
855     if(!jni_mid_getDefaultAdapter)
856     {
857         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getDefaultAdapter is null");
858         return FALSE;
859     }
860
861     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
862     if(!jni_obj_BTAdapter)
863     {
864         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
865         return FALSE;
866     }
867
868     // isEnable()
869     jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled",
870             "()Z");
871     if(!jni_mid_isEnable)
872     {
873         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_isEnable is null");
874         return FALSE;
875     }
876
877     jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
878     OIC_LOG_V(DEBUG, TAG, "[BLE][Native] adapter state is %d", jni_isEnable);
879
880     return jni_isEnable;
881 }
882
883 jstring CANativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
884 {
885     jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
886     if(!jni_cid_device_list)
887     {
888         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_device_list is null");
889         return NULL;
890     }
891
892     jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_device_list, "getAddress",
893             "()Ljava/lang/String;");
894     if(!jni_mid_getAddress)
895     {
896         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getAddress is null");
897         return NULL;
898     }
899
900     jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice, jni_mid_getAddress);
901     if(!jni_address)
902     {
903         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
904         return NULL;
905     }
906     return jni_address;
907 }
908
909 jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt)
910 {
911     if(!gatt)
912     {
913         OIC_LOG(DEBUG, TAG, "[BLE][Native] gatt is null");
914         return NULL;
915     }
916
917     jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
918     if(!jni_cid_gattdevice_list)
919     {
920         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_gattdevice_list is null");
921         return NULL;
922     }
923
924     jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
925             "()Landroid/bluetooth/BluetoothDevice;");
926     if(!jni_mid_getDevice)
927     {
928         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getDevice is null");
929         return NULL;
930     }
931
932     jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
933     if(!jni_obj_device)
934     {
935         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_device is null");
936         return NULL;
937     }
938
939     jstring jni_address = CANativeGetAddressFromBTDevice(env, jni_obj_device);
940     if(!jni_address)
941     {
942         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
943         return NULL;
944     }
945
946     return jni_address;
947 }
948
949 /**
950  * BLE layer
951  */
952 void CANativeGattClose(JNIEnv *env, jobject bluetoothGatt)
953 {
954     // GATT CLOSE
955     OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT CLOSE");
956
957     // get BluetoothGatt class
958     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
959     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
960     if(!jni_cid_BluetoothGatt)
961     {
962         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
963         return;
964     }
965
966     jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close","()V");
967     if(!jni_mid_closeGatt)
968     {
969         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_closeGatt is null");
970         return;
971     }
972
973     // call disconnect gatt method
974     OIC_LOG(DEBUG, TAG, "[BLE][Native] request close Gatt");
975     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
976 }
977
978 void CANativeLEStartScan()
979 {
980     if(!gIsStartServer)
981     {
982         OIC_LOG_V(DEBUG, TAG, "server is not started yet..scan will be passed");
983         return;
984     }
985
986     jboolean isAttached = FALSE;
987     JNIEnv* env;
988     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
989     if(res != JNI_OK)
990     {
991         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
992
993         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
994         if(res != JNI_OK)
995         {
996             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
997             return;
998         }
999         isAttached = TRUE;
1000     }
1001
1002     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStartScan");
1003
1004     // scan gatt server with UUID
1005     if(gLeScanCallback && gUUIDList)
1006     {
1007         CANativeLEStartScanWithUUIDImpl(env, gUUIDList, gLeScanCallback);
1008     }
1009
1010     if(isAttached)
1011         (*g_jvm)->DetachCurrentThread(g_jvm);
1012
1013 }
1014
1015 void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
1016 {
1017     if(!CANativeIsEnableBTAdapter(env))
1018     {
1019         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1020         return;
1021     }
1022
1023     // get default bt adapter class
1024     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
1025     if(!jni_cid_BTAdapter)
1026     {
1027         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
1028         return;
1029     }
1030
1031     // get remote bt adapter method
1032     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
1033     if(!jni_mid_getDefaultAdapter)
1034     {
1035         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
1036         return;
1037     }
1038
1039     // get start le scan method
1040     jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1041             "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
1042     if(!jni_mid_startLeScan)
1043     {
1044         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
1045         return;
1046     }
1047
1048     // gat bt adapter object
1049     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
1050     if(!jni_obj_BTAdapter)
1051     {
1052         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
1053         return;
1054     }
1055
1056     // call start le scan method
1057     jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_startLeScan, callback);
1058     if(!jni_obj_startLeScan)
1059     {
1060         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan is failed");
1061         return;
1062     }
1063     else
1064     {
1065         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan is started");
1066     }
1067 }
1068
1069 jobject CANativeGetUUIDObject(JNIEnv *env, const char* uuid)
1070 {
1071     // setting UUID
1072     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1073     if(!jni_cid_uuid)
1074     {
1075         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_uuid is null");
1076         return NULL;
1077     }
1078
1079     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
1080     if(!jni_mid_fromString)
1081     {
1082         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_fromString is null");
1083         return NULL;
1084     }
1085
1086     jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1087     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid);
1088     if(!jni_obj_uuid)
1089     {
1090         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_uuid is null");
1091         return NULL;
1092     }
1093
1094     return jni_obj_uuid;
1095 }
1096
1097 void CANativeLEStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1098 {
1099     // get default bt adapter class
1100     OIC_LOG(DEBUG, TAG, "[BLE][Native] get default bt adapter class");
1101
1102     if(!CANativeIsEnableBTAdapter(env))
1103     {
1104         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1105         return;
1106     }
1107
1108     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
1109     if(!jni_cid_BTAdapter)
1110     {
1111         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
1112         return;
1113     }
1114
1115     // get remote bt adapter method
1116     OIC_LOG(DEBUG, TAG, "[BLE][Native] get remote bt adapter method");
1117     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
1118     if(!jni_mid_getDefaultAdapter)
1119     {
1120         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
1121         return;
1122     }
1123
1124     // get start le scan method
1125     OIC_LOG(DEBUG, TAG, "[BLE][Native] get start le scan method");
1126     jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1127             "([Ljava/util/UUID;Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
1128     if(!jni_mid_startLeScan)
1129     {
1130         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
1131         return;
1132     }
1133
1134     // get bt adapter object
1135     OIC_LOG(DEBUG, TAG, "[BLE][Native] get bt adapter object");
1136     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
1137     if(!jni_obj_BTAdapter)
1138     {
1139         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
1140         return;
1141     }
1142
1143     // call start le scan method
1144     OIC_LOG(DEBUG, TAG, "[BLE][Native] call start le scan service method");
1145     jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_startLeScan, uuids, callback);
1146     if(!jni_obj_startLeScan)
1147     {
1148         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan With UUID is failed");
1149         return;
1150     }
1151     else
1152     {
1153         OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan With UUID is started");
1154     }
1155 }
1156
1157 void CANativeLEStopScan()
1158 {
1159     jboolean isAttached = FALSE;
1160     JNIEnv* env;
1161     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
1162     if(res != JNI_OK)
1163     {
1164         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
1165         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1166         if(res != JNI_OK)
1167         {
1168             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
1169             return;
1170         }
1171         isAttached = TRUE;
1172     }
1173
1174     CANativeLEStopScanImpl(env, gLeScanCallback);
1175
1176     if(isAttached)
1177         (*g_jvm)->DetachCurrentThread(g_jvm);
1178
1179 }
1180
1181 void CANativeLEStopScanImpl(JNIEnv *env, jobject callback)
1182 {
1183     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStopScan");
1184
1185     if(!CANativeIsEnableBTAdapter(env))
1186     {
1187         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1188         return;
1189     }
1190
1191     // get default bt adapter class
1192     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
1193     if(!jni_cid_BTAdapter)
1194     {
1195         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
1196         return;
1197     }
1198
1199     // get remote bt adapter method
1200     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
1201     if(!jni_mid_getDefaultAdapter)
1202     {
1203         OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
1204         return;
1205     }
1206
1207     // get start le scan method
1208     jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1209             "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)V");
1210     if(!jni_mid_stopLeScan)
1211     {
1212         OIC_LOG(DEBUG, TAG, "[BLE][Native] stopLeScan: jni_mid_stopLeScan is null");
1213         return;
1214     }
1215
1216     // gat bt adapter object
1217     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
1218     if(!jni_obj_BTAdapter)
1219     {
1220         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
1221         return;
1222     }
1223
1224     OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to stop LE Scan");
1225     // call start le scan method
1226     (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1227 }
1228
1229 int32_t CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context,
1230         jboolean autoconnect, jobject callback)
1231 {
1232     if(!CANativeIsEnableBTAdapter(env))
1233     {
1234         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1235         return 0;
1236     }
1237
1238     jstring jni_address = CANativeGetAddressFromBTDevice(env, bluetoothDevice);
1239     const char * addr = (*env)->GetStringUTFChars(env, jni_address, NULL);
1240     OIC_LOG_V(DEBUG, TAG, "[BLE][Native] request connectGatt to %s", addr);
1241
1242     // GATT CONNECT
1243
1244     // get BluetoothDevice class
1245     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothDevice class");
1246     jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1247     if(!jni_cid_BluetoothDevice)
1248     {
1249         OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: jni_cid_BluetoothDevice is null");
1250         return 0;
1251     }
1252
1253     // get connectGatt method
1254     OIC_LOG(DEBUG, TAG, "[BLE][Native] get connectGatt method");
1255     jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice,
1256             "connectGatt",
1257             "(Landroid/content/Context;ZLandroid/bluetooth/BluetoothGattCallback;)Landroid/bluetooth/BluetoothGatt;");
1258     if(!jni_mid_connectGatt)
1259     {
1260         OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: jni_mid_connectGatt is null");
1261         return 0;
1262     }
1263
1264     OIC_LOG(DEBUG, TAG, "[BLE][Native] Call object method - connectGatt");
1265     jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1266             jni_mid_connectGatt, NULL, autoconnect, callback);
1267     if(!jni_obj_connectGatt)
1268     {
1269         OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - connectGatt was failed.obj will be removed");
1270         CANativeRemoveDevice(env, jni_address);
1271         CANativeupdateSendCnt(env);
1272         return -1;
1273     }
1274     else
1275     {
1276         OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - connecting..");
1277     }
1278     return 1;
1279 }
1280
1281 void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt)
1282 {
1283     if(!CANativeIsEnableBTAdapter(env))
1284     {
1285         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1286         return;
1287     }
1288
1289     // GATT DISCONNECT
1290     OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT DISCONNECT");
1291
1292     // get BluetoothGatt class
1293     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt classjobject bluetoothGatt");
1294     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1295     if(!jni_cid_BluetoothGatt)
1296     {
1297         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1298         return;
1299     }
1300
1301     OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt disconnect method");
1302     jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1303             "disconnect","()V");
1304     if(!jni_mid_disconnectGatt)
1305     {
1306         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_disconnectGatt is null");
1307         return;
1308     }
1309
1310     // call disconnect gatt method
1311     OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request disconnectGatt");
1312     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1313
1314 }
1315
1316 void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1317 {
1318     if(!CANativeIsEnableBTAdapter(env))
1319     {
1320         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1321         return;
1322     }
1323
1324     // GATT SERVICE DISCOVERY
1325     OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT SERVICE DISCOVERY");
1326
1327     // get BluetoothGatt class
1328     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
1329     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1330     if(!jni_cid_BluetoothGatt)
1331     {
1332         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1333         return;
1334     }
1335
1336     OIC_LOG(DEBUG, TAG, "[BLE][Native] discovery gatt services method");
1337     jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1338             "discoverServices","()Z");
1339     if(!jni_mid_discoverServices)
1340     {
1341         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_discoverServices is null");
1342         return;
1343     }
1344     // call disconnect gatt method
1345     OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request discovery gatt services");
1346     (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1347 }
1348
1349 jboolean CANativeLESendData(JNIEnv *env, jobject bluetoothGatt, jobject gattCharacteristic)
1350 {
1351     if(!CANativeIsEnableBTAdapter(env))
1352     {
1353         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1354         return FALSE;
1355     }
1356
1357     // WRITE GATT CHARACTERISTIC
1358     OIC_LOG(DEBUG, TAG, "[BLE][Native] WRITE GATT CHARACTERISTIC");
1359
1360     // get BluetoothGatt class
1361     OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
1362     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1363     if(!jni_cid_BluetoothGatt)
1364     {
1365         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1366         return FALSE;
1367     }
1368
1369     OIC_LOG(DEBUG, TAG, "[BLE][Native] write characteristic method");
1370     jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1371             "writeCharacteristic", "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
1372     if(!jni_mid_writeCharacteristic)
1373     {
1374         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_writeCharacteristic is null");
1375         return FALSE;
1376     }
1377
1378     // call disconnect gatt method
1379     OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to write gatt characteristic");
1380     jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeCharacteristic, gattCharacteristic);
1381     if(ret)
1382     {
1383         OIC_LOG(DEBUG, TAG, "[BLE][Native] writeCharacteristic is success");
1384     }
1385     else
1386     {
1387         OIC_LOG(DEBUG, TAG, "[BLE][Native] writeCharacteristic is failed");
1388         return FALSE;
1389     }
1390     return TRUE;
1391 }
1392
1393 void CANativeReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1394 {
1395
1396    if(!CANativeIsEnableBTAdapter(env))
1397    {
1398        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1399        return;
1400    }
1401
1402    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1403    if(!jni_cid_BluetoothGatt)
1404    {
1405        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1406        return;
1407    }
1408
1409    jstring jni_uuid = (*env)->NewStringUTF(env, IOTIVITY_GATT_RX_UUID);
1410    jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1411    if(!jni_obj_GattCharacteristic)
1412    {
1413        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1414        return;
1415    }
1416
1417    OIC_LOG(DEBUG, TAG, "[BLE][Native] read characteristic method");
1418    jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "readCharacteristic", "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
1419    if(!jni_mid_readCharacteristic)
1420    {
1421        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_readCharacteristic is null");
1422        return;
1423    }
1424
1425    // call disconnect gatt method
1426    OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to read gatt characteristic");
1427    jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic, jni_obj_GattCharacteristic);
1428    if(ret)
1429    {
1430        OIC_LOG(DEBUG, TAG, "[BLE][Native] readCharacteristic is success");
1431    }
1432    else
1433    {
1434        OIC_LOG(DEBUG, TAG, "[BLE][Native] readCharacteristic is failed");
1435    }
1436 }
1437
1438 jboolean CANativeSetCharacteristicNoti(JNIEnv *env, jobject bluetoothGatt, const char* uuid)
1439 {
1440     if(!CANativeIsEnableBTAdapter(env))
1441     {
1442         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1443         return FALSE;
1444     }
1445
1446     // get BluetoothGatt class
1447     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeSetCharacteristicNoti");
1448     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1449     if(!jni_cid_BluetoothGatt)
1450     {
1451         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1452         return FALSE;
1453     }
1454
1455     jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1456     jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1457     if(!jni_obj_GattCharacteristic)
1458     {
1459         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1460         return FALSE;
1461     }
1462
1463     // set Characteristic Notification
1464     jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "setCharacteristicNotification",
1465             "(Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
1466     if(!jni_mid_setNotification)
1467     {
1468         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getService is null");
1469         return FALSE;
1470     }
1471
1472     jboolean enable = TRUE;
1473     jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification, jni_obj_GattCharacteristic, enable);
1474     if(1 == ret)
1475     {
1476         OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - setCharacteristicNotification is success");
1477         return TRUE;
1478     }
1479     else
1480     {
1481         OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - setCharacteristicNotification is failed");
1482         return FALSE;
1483     }
1484 }
1485
1486 jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1487 {
1488     if(!CANativeIsEnableBTAdapter(env))
1489     {
1490         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1491         return NULL;
1492     }
1493
1494     // get BluetoothGatt class
1495     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeGetGattService");
1496     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1497     if(!jni_cid_BluetoothGatt)
1498     {
1499         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
1500         return NULL;
1501     }
1502
1503     jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "getService",
1504             "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1505     if(!jni_mid_getService)
1506     {
1507         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getService is null");
1508         return NULL;
1509     }
1510
1511     jobject jni_obj_service_uuid = CANativeGetUUIDObject(env, IOTIVITY_GATT_SERVIE_UUID);
1512     if(!jni_obj_service_uuid)
1513     {
1514         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_service_uuid is null");
1515         return NULL;
1516     }
1517
1518     // get bluetooth gatt service
1519     OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get service");
1520     jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService, jni_obj_service_uuid);
1521
1522     // get bluetooth gatt service class
1523     jclass jni_cid_BluetoothGattService = (*env)->FindClass(env, "android/bluetooth/BluetoothGattService");
1524     if(!jni_cid_BluetoothGattService)
1525     {
1526         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGattService is null");
1527         return NULL;
1528     }
1529
1530     OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt getCharacteristic method");
1531     jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService, "getCharacteristic",
1532             "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
1533     if(!jni_mid_getCharacteristic)
1534     {
1535         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getCharacteristic is null");
1536         return NULL;
1537     }
1538
1539     const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1540     jobject jni_obj_tx_uuid = CANativeGetUUIDObject(env, uuid);
1541     if(!jni_obj_tx_uuid)
1542     {
1543         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_tx_uuid is null");
1544         return NULL;
1545     }
1546
1547     OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get Characteristic");
1548     jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService, jni_mid_getCharacteristic, jni_obj_tx_uuid);
1549
1550     return jni_obj_GattCharacteristic;
1551 }
1552
1553 jobject CANativeCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1554 {
1555     if(!CANativeIsEnableBTAdapter(env))
1556     {
1557         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1558         return NULL;
1559     }
1560
1561     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattCharacteristic");
1562     jstring jni_uuid = (*env)->NewStringUTF(env, IOTIVITY_GATT_TX_UUID);
1563     jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
1564     if(!jni_obj_GattCharacteristic)
1565     {
1566         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
1567         return NULL;
1568     }
1569
1570     jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/BluetoothGattCharacteristic");
1571     if(!jni_cid_BTGattCharacteristic)
1572     {
1573         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
1574         return NULL;
1575     }
1576
1577     OIC_LOG(DEBUG, TAG, "[BLE][Native] set value in Characteristic");
1578     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1579             "([B)Z");
1580     if(!jni_mid_setValue)
1581     {
1582         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_setValue is null");
1583         return NULL;
1584     }
1585
1586     jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue, data);
1587     if(1 == ret)
1588     {
1589         OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value has been set");
1590         return jni_obj_GattCharacteristic;
1591     }
1592     else
1593     {
1594         OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value hasn't been set");
1595         return NULL;
1596     }
1597 }
1598
1599 jbyteArray CANativeGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1600 {
1601     if(!CANativeIsEnableBTAdapter(env))
1602     {
1603         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
1604         return NULL;
1605     }
1606
1607     jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/BluetoothGattCharacteristic");
1608     if(!jni_cid_BTGattCharacteristic)
1609     {
1610         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
1611         return NULL;
1612     }
1613
1614     OIC_LOG(DEBUG, TAG, "[BLE][Native] get value in Characteristic");
1615     jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1616             "()[B");
1617     if(!jni_mid_getValue)
1618     {
1619         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getValue is null");
1620         return NULL;
1621     }
1622
1623     jbyteArray jni_obj_data_array =  (*env)->CallObjectMethod(env, characteristic, jni_mid_getValue);
1624     return jni_obj_data_array;
1625 }
1626
1627
1628 void CANativeCreateUUIDList()
1629 {
1630     jboolean isAttached = FALSE;
1631     JNIEnv* env;
1632     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
1633     if(res != JNI_OK)
1634     {
1635         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
1636         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1637
1638         if(res != JNI_OK)
1639         {
1640             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
1641             return;
1642         }
1643         isAttached = TRUE;
1644     }
1645
1646     // create new object array
1647     jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1648     if(!jni_cid_uuid_list)
1649     {
1650         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_uuid_list is null");
1651         return;
1652     }
1653
1654     jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1, jni_cid_uuid_list, NULL);
1655     if(!jni_obj_uuid_list)
1656     {
1657         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_uuid_list is null");
1658         return;
1659     }
1660
1661     // remove previous list and create list again
1662     CANativeRemoveAllDevices(env);
1663     CANativeCreateScanDeviceList(env);
1664
1665     // make uuid list
1666     jobject jni_obj_uuid = CANativeGetUUIDObject(env, IOTIVITY_GATT_SERVIE_UUID);
1667     (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1668
1669     gUUIDList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1670
1671     if(isAttached)
1672         (*g_jvm)->DetachCurrentThread(g_jvm);
1673 }
1674
1675 void CANativeCreateScanDeviceList(JNIEnv *env)
1676 {
1677     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateScanDeviceList");
1678
1679     // create new object array
1680     if (gdeviceList == NULL)
1681     {
1682         OIC_LOG_V(DEBUG, TAG, "Create device list");
1683
1684         gdeviceList = u_arraylist_create();
1685     }
1686 }
1687
1688 void CANativeAddScanDeviceToList(JNIEnv *env, jobject device)
1689 {
1690     if(!device)
1691     {
1692         OIC_LOG(DEBUG, TAG, "[BLE][Native] device is null");
1693         return;
1694     }
1695
1696     if(!gdeviceList)
1697     {
1698         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdevice_list is null");
1699         return;
1700     }
1701
1702     jstring jni_remoteAddress = CANativeGetAddressFromBTDevice(env, device);
1703     if(!jni_remoteAddress)
1704     {
1705         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
1706         return;
1707     }
1708
1709     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1710
1711     if(!CANativeIsDeviceInList(env, remoteAddress)) {
1712         jobject gdevice = (*env)->NewGlobalRef(env, device);
1713         u_arraylist_add(gdeviceList, gdevice);
1714         OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
1715     }
1716 }
1717
1718 jboolean CANativeIsDeviceInList(JNIEnv *env, const char* remoteAddress){
1719     // get address value from device list
1720
1721     jint index;
1722     for (index = 0; index < u_arraylist_length(gdeviceList); index++)
1723     {
1724         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
1725         if(!jarrayObj)
1726         {
1727             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1728             return TRUE;
1729         }
1730
1731         jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
1732         if(!jni_setAddress)
1733         {
1734             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1735             return TRUE;
1736         }
1737
1738         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1739
1740         if(!strcmp(remoteAddress, setAddress))
1741         {
1742             OIC_LOG_V(DEBUG, TAG, "the device is already set");
1743             return TRUE;
1744         }
1745         else
1746         {
1747             continue;
1748         }
1749     }
1750
1751     OIC_LOG_V(DEBUG, TAG, "there are no the device in list. we can add");
1752     return FALSE;
1753 }
1754
1755 void CANativeRemoveAllDevices(JNIEnv *env)
1756 {
1757     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveAllDevices");
1758
1759     if(!gdeviceList)
1760     {
1761         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
1762         return;
1763     }
1764
1765     jint index;
1766     for (index = 0; index < u_arraylist_length(gdeviceList); index++)
1767     {
1768         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
1769         if(!jarrayObj)
1770         {
1771             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1772             return;
1773         }
1774         (*env)->DeleteGlobalRef(env, jarrayObj);
1775     }
1776
1777     OICFree(gdeviceList);
1778     gdeviceList = NULL;
1779     return;
1780 }
1781
1782 void CANativeRemoveDevice(JNIEnv *env, jstring address)
1783 {
1784     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveDevice");
1785
1786     if(!gdeviceList)
1787     {
1788         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
1789         return;
1790     }
1791
1792     jint index;
1793     for (index = 0; index < u_arraylist_length(gdeviceList); index++)
1794     {
1795         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
1796         if(!jarrayObj)
1797         {
1798             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1799             return;
1800         }
1801
1802         jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
1803         if(!jni_setAddress)
1804         {
1805             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1806             return;
1807         }
1808         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1809         const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
1810
1811         if(!strcmp(setAddress, remoteAddress))
1812         {
1813             OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
1814             (*env)->DeleteGlobalRef(env, jarrayObj);
1815
1816             CAReorderingDeviceList(index);
1817             return;
1818         }
1819     }
1820     OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
1821     return;
1822 }
1823
1824 void CAReorderingDeviceList(uint32_t index)
1825 {
1826     if (index >= gdeviceList->length)
1827     {
1828         return;
1829     }
1830
1831     if (index < gdeviceList->length - 1)
1832     {
1833         memmove(&gdeviceList->data[index], &gdeviceList->data[index + 1],
1834                 (gdeviceList->length - index - 1) * sizeof(void *));
1835     }
1836
1837     gdeviceList->size--;
1838     gdeviceList->length--;
1839 }
1840
1841 /**
1842  * Gatt Object List
1843  */
1844 void CANativeCreateGattObjList(JNIEnv *env)
1845 {
1846     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattObjList");
1847
1848     // create new object array
1849     if (gGattObjectList == NULL)
1850     {
1851         OIC_LOG_V(DEBUG, TAG, "Create Gatt object list");
1852
1853         gGattObjectList = u_arraylist_create();
1854     }
1855 }
1856
1857 void CANativeAddGattobjToList(JNIEnv *env, jobject gatt)
1858 {
1859     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeAddGattobjToList");
1860
1861     if(!gatt)
1862     {
1863         OIC_LOG(DEBUG, TAG, "[BLE][Native] gatt is null");
1864         return;
1865     }
1866
1867     if(!gGattObjectList)
1868     {
1869         OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
1870         return;
1871     }
1872
1873     jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
1874     if(!jni_remoteAddress)
1875     {
1876         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
1877         return;
1878     }
1879
1880     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1881
1882     if(!CANativeIsGattObjInList(env, remoteAddress))
1883     {
1884         jobject gGatt = (*env)->NewGlobalRef(env, gatt);
1885         u_arraylist_add(gGattObjectList, gGatt);
1886         OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
1887     }
1888 }
1889
1890 jboolean CANativeIsGattObjInList(JNIEnv *env, const char* remoteAddress)
1891 {
1892     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsGattObjInList");
1893
1894     jint index;
1895     for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
1896     {
1897
1898         jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
1899         if(!jarrayObj)
1900         {
1901             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1902             return TRUE;
1903         }
1904
1905         jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
1906         if(!jni_setAddress)
1907         {
1908             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1909             return TRUE;
1910         }
1911
1912         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1913
1914         if(!strcmp(remoteAddress, setAddress))
1915         {
1916             OIC_LOG_V(DEBUG, TAG, "the device is already set");
1917             return TRUE;
1918         }
1919         else
1920         {
1921             continue;
1922         }
1923     }
1924
1925     OIC_LOG_V(DEBUG, TAG, "there are no the gatt obejct in list. we can add");
1926     return FALSE;
1927 }
1928
1929 void CANativeRemoveAllGattObjsList(JNIEnv *env)
1930 {
1931     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveAllGattObjsList");
1932
1933     if(!gGattObjectList)
1934     {
1935         OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
1936         return;
1937     }
1938
1939     jint index;
1940     for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
1941     {
1942         jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
1943         if(!jarrayObj)
1944         {
1945             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1946             return;
1947         }
1948         (*env)->DeleteGlobalRef(env, jarrayObj);
1949     }
1950
1951     OICFree(gGattObjectList);
1952     gGattObjectList = NULL;
1953     return;
1954 }
1955
1956 void CANativeLEDisconnectAll(JNIEnv *env)
1957 {
1958     OIC_LOG_V(DEBUG, TAG, "CANativeLEDisconnectAll");
1959
1960     if(!gGattObjectList)
1961     {
1962         OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
1963         return;
1964     }
1965
1966     jint index;
1967     for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
1968     {
1969         jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
1970         if(!jarrayObj)
1971         {
1972             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1973             return;
1974         }
1975         CANativeLEDisconnect(env, jarrayObj);
1976     }
1977
1978     OICFree(gGattObjectList);
1979     gGattObjectList = NULL;
1980     return;
1981 }
1982
1983 void CANativeRemoveGattObj(JNIEnv *env, jobject gatt)
1984 {
1985     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveGattObj");
1986
1987     if(!gGattObjectList)
1988     {
1989         OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
1990         return;
1991     }
1992
1993     jint index;
1994     for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
1995     {
1996         jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
1997         if(!jarrayObj)
1998         {
1999             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
2000             return;
2001         }
2002
2003         jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
2004         if(!jni_setAddress)
2005         {
2006             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
2007             return;
2008         }
2009         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2010
2011         jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
2012         if(!jni_remoteAddress)
2013         {
2014             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
2015             return;
2016         }
2017         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2018
2019         if(!strcmp(setAddress, remoteAddress))
2020         {
2021             OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
2022             (*env)->DeleteGlobalRef(env, jarrayObj);
2023
2024             CAReorderingGattList(index);
2025             return;
2026         }
2027     }
2028     OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
2029     return;
2030 }
2031
2032 void CAReorderingGattList(uint32_t index)
2033 {
2034     if (index >= gGattObjectList->length)
2035     {
2036         return;
2037     }
2038
2039     if (index < gGattObjectList->length - 1)
2040     {
2041         memmove(&gGattObjectList->data[index], &gGattObjectList->data[index + 1],
2042                 (gGattObjectList->length - index - 1) * sizeof(void *));
2043     }
2044
2045     gGattObjectList->size--;
2046     gGattObjectList->length--;
2047 }
2048
2049 void CANativeupdateSendCnt(JNIEnv *env)
2050 {
2051     // mutex lock
2052     u_mutex_lock(gThreadMutex);
2053
2054     gCurrentSentCnt++;
2055
2056     if(gTargetCnt <= gCurrentSentCnt)
2057     {
2058         gTargetCnt = 0;
2059         gCurrentSentCnt = 0;
2060
2061         if(gSendBuffer)
2062         {
2063             (*env)->DeleteGlobalRef(env, gSendBuffer);
2064             gSendBuffer = NULL;
2065         }
2066         // notity the thread
2067         u_cond_signal(gThreadCond);
2068         gIsFinishSendData = TRUE;
2069         OIC_LOG(DEBUG, TAG, "set signal for send data");
2070     }
2071     // mutex unlock
2072     u_mutex_unlock(gThreadMutex);
2073 }