Merge branch 'master' into 'security-basecamp'
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / caleclient.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <jni.h>
24 #include <unistd.h>
25
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
31
32 #include "logger.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
36 #include "camutex.h"
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
39
40 #define TAG PCF("CA_LE_CLIENT")
41
42 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
43 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
44 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
45 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
46
47 JavaVM *g_jvm;
48 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
49 static u_arraylist_t *g_gattObjectList = NULL;
50 static u_arraylist_t *g_deviceStateList = NULL;
51
52 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
53 static CABLEErrorHandleCallback g_clientErrorCallback;
54 static ca_thread_pool_t g_threadPoolHandle = NULL;
55 static jobject g_leScanCallback = NULL;
56 static jobject g_leGattCallback = NULL;
57 static jobject g_context = NULL;
58 static jobjectArray g_uuidList = NULL;
59
60 // it will be prevent to start send logic when adapter has stopped.
61 static bool g_isStartedLEClient = false;
62 static bool g_isStartedMulticastServer = false;
63 static bool g_isStartedScan = false;
64
65 static jbyteArray g_sendBuffer = NULL;
66 static uint32_t g_targetCnt = 0;
67 static uint32_t g_currentSentCnt = 0;
68 static bool g_isFinishedSendData = false;
69 static ca_mutex g_SendFinishMutex = NULL;
70 static ca_mutex g_threadMutex = NULL;
71 static ca_cond g_threadCond = NULL;
72
73 static ca_mutex g_threadSendMutex = NULL;
74
75 static ca_mutex g_bleReqRespClientCbMutex = NULL;
76 static ca_mutex g_bleServerBDAddressMutex = NULL;
77
78 static ca_mutex g_deviceListMutex = NULL;
79 static ca_mutex g_gattObjectMutex = NULL;
80 static ca_mutex g_deviceStateListMutex = NULL;
81
82 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
83
84 //getting jvm
85 void CALEClientJniInit()
86 {
87     OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
88     g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
89 }
90
91 void CALEClientJNISetContext()
92 {
93     OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
94     g_context = (jobject) CANativeJNIGetContext();
95 }
96
97 CAResult_t CALECreateJniInterfaceObject()
98 {
99     OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
100
101     if (!g_context)
102     {
103         OIC_LOG(ERROR, TAG, "g_context is null");
104         return CA_STATUS_FAILED;
105     }
106
107     if (!g_jvm)
108     {
109         OIC_LOG(ERROR, TAG, "g_jvm is null");
110         return CA_STATUS_FAILED;
111     }
112
113     bool isAttached = false;
114     JNIEnv* env;
115     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
116     if (JNI_OK != res)
117     {
118         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
119         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
120
121         if (JNI_OK != res)
122         {
123             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
124             return CA_STATUS_FAILED;
125         }
126         isAttached = true;
127     }
128
129     jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
130     if (!jni_LEInterface)
131     {
132         OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
133         goto error_exit;
134     }
135
136     jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
137                                                                  "(Landroid/content/Context;)V");
138     if (!LeInterfaceConstructorMethod)
139     {
140         OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
141         goto error_exit;
142     }
143
144     (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
145     OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
146
147     if (isAttached)
148     {
149         (*g_jvm)->DetachCurrentThread(g_jvm);
150     }
151
152     return CA_STATUS_OK;
153
154 error_exit:
155
156     if (isAttached)
157     {
158         (*g_jvm)->DetachCurrentThread(g_jvm);
159     }
160
161     return CA_STATUS_FAILED;
162 }
163
164 CAResult_t CALEClientInitialize(ca_thread_pool_t handle)
165 {
166     OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
167
168     CALEClientJniInit();
169
170     if (!g_jvm)
171     {
172         OIC_LOG(ERROR, TAG, "g_jvm is null");
173         return CA_STATUS_FAILED;
174     }
175
176     bool isAttached = false;
177     JNIEnv* env;
178     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
179     if (JNI_OK != res)
180     {
181         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
182         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
183
184         if (JNI_OK != res)
185         {
186             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
187             return CA_STATUS_FAILED;
188         }
189         isAttached = true;
190     }
191
192     CAResult_t ret = CALECheckPlatformVersion(env, 18);
193     if (CA_STATUS_OK != ret)
194     {
195         OIC_LOG(ERROR, TAG, "it is not supported");
196
197         if (isAttached)
198         {
199             (*g_jvm)->DetachCurrentThread(g_jvm);
200         }
201
202         return ret;
203     }
204
205     g_threadPoolHandle = handle;
206
207     ret = CALEClientInitGattMutexVaraibles();
208     if (CA_STATUS_OK != ret)
209     {
210         OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
211         CALEClientTerminateGattMutexVariables();
212
213         if (isAttached)
214         {
215             (*g_jvm)->DetachCurrentThread(g_jvm);
216         }
217
218         return ret;
219     }
220
221     // init mutex for send logic
222     g_threadCond = ca_cond_new();
223
224     CALEClientCreateDeviceList();
225     CALEClientJNISetContext();
226
227     ret = CALEClientCreateUUIDList();
228     if (CA_STATUS_OK != ret)
229     {
230         OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
231
232         if (isAttached)
233         {
234             (*g_jvm)->DetachCurrentThread(g_jvm);
235         }
236
237         return ret;
238     }
239
240     ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
241     if (CA_STATUS_OK != ret)
242     {
243         OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
244
245         if (isAttached)
246         {
247             (*g_jvm)->DetachCurrentThread(g_jvm);
248         }
249
250         return ret;
251     }
252     g_isStartedLEClient = true;
253
254     return CA_STATUS_OK;
255 }
256
257 void CALEClientTerminate()
258 {
259     OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
260
261     if (!g_jvm)
262     {
263         OIC_LOG(ERROR, TAG, "g_jvm is null");
264         return;
265     }
266
267     bool isAttached = false;
268     JNIEnv* env;
269     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
270     if (JNI_OK != res)
271     {
272         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
273         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
274
275         if (JNI_OK != res)
276         {
277             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
278             return;
279         }
280         isAttached = true;
281     }
282
283     if (g_leScanCallback)
284     {
285         (*env)->DeleteGlobalRef(env, g_leScanCallback);
286     }
287
288     if (g_leGattCallback)
289     {
290         (*env)->DeleteGlobalRef(env, g_leGattCallback);
291     }
292
293     if (g_sendBuffer)
294     {
295         (*env)->DeleteGlobalRef(env, g_sendBuffer);
296     }
297
298     if (g_uuidList)
299     {
300         (*env)->DeleteGlobalRef(env, g_uuidList);
301     }
302
303     CAResult_t ret = CALEClientRemoveAllDeviceState();
304     if (CA_STATUS_OK != ret)
305     {
306         OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
307     }
308
309     ret = CALEClientRemoveAllScanDevices(env);
310     if (CA_STATUS_OK != ret)
311     {
312         OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
313     }
314
315     ret = CALEClientRemoveAllGattObjs(env);
316     if (CA_STATUS_OK != ret)
317     {
318         OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
319     }
320
321     g_isStartedMulticastServer = false;
322     g_isStartedScan = false;
323     CALEClientSetSendFinishFlag(false);
324
325     CALEClientTerminateGattMutexVariables();
326
327     ca_cond_free(g_threadCond);
328
329     if (isAttached)
330     {
331         (*g_jvm)->DetachCurrentThread(g_jvm);
332     }
333 }
334
335 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
336 {
337     OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
338     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
339
340     if (gatt)
341     {
342         CAResult_t res = CALEClientDisconnect(env, gatt);
343         if (CA_STATUS_OK != res)
344         {
345             OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
346         }
347     }
348     CALEClientUpdateSendCnt(env);
349 }
350
351 CAResult_t CALEClientSendUnicastMessage(const char* address, const char* data,
352                                         const uint32_t dataLen)
353 {
354     OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %s)", address, data);
355     VERIFY_NON_NULL(address, TAG, "address is null");
356     VERIFY_NON_NULL(data, TAG, "data is null");
357
358     return CALEClientSendUnicastMessageImpl(address, data, dataLen);
359 }
360
361 CAResult_t CALEClientSendMulticastMessage(const char* data, const uint32_t dataLen)
362 {
363     OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%s)", data);
364     VERIFY_NON_NULL(data, TAG, "data is null");
365
366     if (!g_jvm)
367     {
368         OIC_LOG(ERROR, TAG, "g_jvm is null");
369         return CA_STATUS_FAILED;
370     }
371
372     bool isAttached = false;
373     JNIEnv* env;
374     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
375     if (JNI_OK != res)
376     {
377         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
378         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
379
380         if (JNI_OK != res)
381         {
382             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
383             return CA_STATUS_FAILED;
384         }
385         isAttached = true;
386     }
387
388     CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
389     if (CA_STATUS_OK != ret)
390     {
391         OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
392     }
393
394     if (isAttached)
395     {
396         (*g_jvm)->DetachCurrentThread(g_jvm);
397     }
398
399     return ret;
400 }
401
402 CAResult_t CALEClientStartUnicastServer(const char* address)
403 {
404     OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
405
406     return CA_NOT_SUPPORTED;
407 }
408
409 CAResult_t CALEClientStartMulticastServer()
410 {
411     OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
412
413     if (g_isStartedMulticastServer)
414     {
415         OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
416         return CA_STATUS_FAILED;
417     }
418
419     if (!g_jvm)
420     {
421         OIC_LOG(ERROR, TAG, "g_jvm is null");
422         return CA_STATUS_FAILED;
423     }
424
425     bool isAttached = false;
426     JNIEnv* env;
427     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
428     if (JNI_OK != res)
429     {
430         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
431         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
432
433         if (JNI_OK != res)
434         {
435             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
436             return CA_STATUS_FAILED;
437         }
438         isAttached = true;
439     }
440
441     g_isStartedMulticastServer = true;
442     CAResult_t ret = CALEClientStartScan();
443     if (CA_STATUS_OK != ret)
444     {
445         OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
446     }
447
448     if (isAttached)
449     {
450         (*g_jvm)->DetachCurrentThread(g_jvm);
451     }
452
453     return ret;
454 }
455
456 void CALEClientStopUnicastServer()
457 {
458     OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
459 }
460
461 void CALEClientStopMulticastServer()
462 {
463     OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
464     g_isStartedMulticastServer = false;
465     CAResult_t res = CALEClientStopScan();
466     if (CA_STATUS_OK != res)
467     {
468         OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
469         return;
470     }
471 }
472
473 void CALEClientSetCallback(CAPacketReceiveCallback callback)
474 {
475     g_packetReceiveCallback = callback;
476 }
477
478 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
479 {
480     g_clientErrorCallback = callback;
481 }
482
483 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const char* data,
484                                       const uint32_t dataLen)
485 {
486     OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %s", address,
487               data);
488     VERIFY_NON_NULL(address, TAG, "address is null");
489     VERIFY_NON_NULL(data, TAG, "data is null");
490
491     if (!g_jvm)
492     {
493         OIC_LOG(ERROR, TAG, "g_jvm is null");
494         return CA_STATUS_FAILED;
495     }
496
497     bool isAttached = false;
498     JNIEnv* env;
499     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
500     if (JNI_OK != res)
501     {
502         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
503         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
504         if (JNI_OK != res)
505         {
506             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
507             return CA_STATUS_FAILED;
508         }
509         isAttached = true;
510     }
511
512     ca_mutex_lock(g_threadSendMutex);
513
514     CAResult_t ret = CA_STATUS_OK;
515     if (g_context && g_deviceList)
516     {
517         uint32_t length = u_arraylist_length(g_deviceList);
518         for (uint32_t index = 0; index < length; index++)
519         {
520             jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
521             if (!jarrayObj)
522             {
523                 OIC_LOG(ERROR, TAG, "jarrayObj is null");
524                 goto error_exit;
525             }
526
527             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
528             if (!jni_setAddress)
529             {
530                 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
531                 goto error_exit;
532             }
533
534             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
535             if (!setAddress)
536             {
537                 OIC_LOG(ERROR, TAG, "setAddress is null");
538                 goto error_exit;
539             }
540
541             OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
542
543             if (!strcmp(setAddress, address))
544             {
545                 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
546
547                 // connect to gatt server
548                 ret = CALEClientStopScan();
549                 if (CA_STATUS_OK != ret)
550                 {
551                     OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
552                     goto error_exit;
553                 }
554
555                 if (g_sendBuffer)
556                 {
557                     (*env)->DeleteGlobalRef(env, g_sendBuffer);
558                 }
559                 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
560                 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
561                 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
562
563                 ret = CALEClientSendData(env, jarrayObj);
564                 if (CA_STATUS_OK != ret)
565                 {
566                     OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
567                     goto error_exit;
568                 }
569
570                 OIC_LOG(INFO, TAG, "wake up");
571                 break;
572             }
573             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
574         }
575     }
576
577     if (isAttached)
578     {
579         (*g_jvm)->DetachCurrentThread(g_jvm);
580     }
581
582     ret = CALECheckSendState(address);
583     if(CA_STATUS_OK != ret)
584     {
585         OIC_LOG(ERROR, TAG, "send has failed");
586         goto error_exit;
587     }
588
589     // start LE Scan again
590     ret = CALEClientStartScan();
591     if (CA_STATUS_OK != ret)
592     {
593         OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
594         ca_mutex_unlock(g_threadSendMutex);
595         return res;
596     }
597
598     ca_mutex_unlock(g_threadSendMutex);
599     OIC_LOG(INFO, TAG, "unicast - send success");
600     return CA_STATUS_OK;
601
602     // error label.
603 error_exit:
604
605     // start LE Scan again
606     ret = CALEClientStartScan();
607     if (CA_STATUS_OK != ret)
608     {
609         OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
610         ca_mutex_unlock(g_threadSendMutex);
611         return res;
612     }
613
614     if (isAttached)
615     {
616         (*g_jvm)->DetachCurrentThread(g_jvm);
617     }
618     ca_mutex_unlock(g_threadSendMutex);
619     return CA_SEND_FAILED;
620 }
621
622 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const char* data,
623                                               const uint32_t dataLen)
624 {
625     OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
626     VERIFY_NON_NULL(data, TAG, "data is null");
627     VERIFY_NON_NULL(env, TAG, "env is null");
628
629     if (!g_deviceList)
630     {
631         OIC_LOG(ERROR, TAG, "g_deviceList is null");
632         return CA_STATUS_FAILED;
633     }
634
635     ca_mutex_lock(g_threadSendMutex);
636
637     CALEClientSetSendFinishFlag(false);
638
639     OIC_LOG(DEBUG, TAG, "set byteArray for data");
640     if (g_sendBuffer)
641     {
642         (*env)->DeleteGlobalRef(env, g_sendBuffer);
643     }
644     jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
645     (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
646     g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
647
648     // connect to gatt server
649     CAResult_t res = CALEClientStopScan();
650     if (CA_STATUS_OK != res)
651     {
652         OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
653         ca_mutex_unlock(g_threadSendMutex);
654         return res;
655     }
656
657     uint32_t length = u_arraylist_length(g_deviceList);
658     g_targetCnt = length;
659     if (0 == length)
660     {
661         goto error_exit;
662     }
663
664     for (uint32_t index = 0; index < length; index++)
665     {
666         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
667         if (!jarrayObj)
668         {
669             OIC_LOG(ERROR, TAG, "jarrayObj is not available");
670             continue;
671         }
672
673         res = CALEClientSendData(env, jarrayObj);
674         if (res != CA_STATUS_OK)
675         {
676             OIC_LOG(ERROR, TAG, "BT device[%d] - send has failed");
677         }
678
679         jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
680         if (!jni_address)
681         {
682             OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
683             continue;
684         }
685
686         const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
687         if (!address)
688         {
689             OIC_LOG(ERROR, TAG, "address is not available");
690             continue;
691         }
692
693         res = CALECheckSendState(address);
694         if (CA_STATUS_OK != res)
695         {
696             OIC_LOG_V(INFO, TAG, "multicast : send has failed for this device[%s]", address);
697             g_clientErrorCallback(address, data, dataLen, res);
698             (*env)->ReleaseStringUTFChars(env, jni_address, address);
699             continue;
700         }
701
702         (*env)->ReleaseStringUTFChars(env, jni_address, address);
703     }
704
705     OIC_LOG(DEBUG, TAG, "connection routine is finished");
706
707     // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
708     if (!g_isFinishedSendData)
709     {
710         ca_mutex_lock(g_threadMutex);
711         ca_cond_wait(g_threadCond, g_threadMutex);
712         OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
713         ca_mutex_unlock(g_threadMutex);
714     }
715
716     // start LE Scan again
717     res = CALEClientStartScan();
718     if (CA_STATUS_OK != res)
719     {
720         OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
721         ca_mutex_unlock(g_threadSendMutex);
722         return res;
723     }
724
725     ca_mutex_unlock(g_threadSendMutex);
726     OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
727     return CA_STATUS_OK;
728
729 error_exit:
730     res = CALEClientStartScan();
731     if (CA_STATUS_OK != res)
732     {
733         OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
734         ca_mutex_unlock(g_threadSendMutex);
735         return res;
736     }
737
738     ca_mutex_unlock(g_threadSendMutex);
739     OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
740     return CA_SEND_FAILED;
741 }
742
743 CAResult_t CALECheckSendState(const char* address)
744 {
745     VERIFY_NON_NULL(address, TAG, "address is null");
746
747     ca_mutex_lock(g_deviceStateListMutex);
748     CALEState_t* state = CALEClientGetStateInfo(address);
749     if (NULL == state)
750     {
751         OIC_LOG(ERROR, TAG, "state is null");
752         ca_mutex_unlock(g_deviceStateListMutex);
753         return CA_SEND_FAILED;
754     }
755
756     if (STATE_SEND_SUCCESS != state->sendState)
757     {
758         OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
759         ca_mutex_unlock(g_deviceStateListMutex);
760         return CA_SEND_FAILED;
761     }
762     ca_mutex_unlock(g_deviceStateListMutex);
763     return CA_STATUS_OK;
764 }
765
766 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
767 {
768     OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
769     VERIFY_NON_NULL(device, TAG, "device is null");
770     VERIFY_NON_NULL(env, TAG, "env is null");
771
772     jstring jni_address = CALEGetAddressFromBTDevice(env, device);
773     if (!jni_address)
774     {
775         OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
776         return CA_STATUS_FAILED;
777     }
778
779     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
780     if (!address)
781     {
782         OIC_LOG(ERROR, TAG, "address is not available");
783         return CA_STATUS_FAILED;
784     }
785
786     ca_mutex_lock(g_deviceStateListMutex);
787     CALEState_t* state = CALEClientGetStateInfo(address);
788     ca_mutex_unlock(g_deviceStateListMutex);
789     if (!state)
790     {
791         OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
792         CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
793         if (CA_STATUS_OK != ret)
794         {
795             OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
796             (*env)->ReleaseStringUTFChars(env, jni_address, address);
797             return ret;
798         }
799     }
800     else
801     {
802         if (STATE_CONNECTED == state->connectedState)
803         {
804             OIC_LOG(INFO, TAG, "GATT has already connected");
805             jobject gatt = CALEClientGetGattObjInList(env, address);
806             if (!gatt)
807             {
808                 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
809                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
810                 return CA_STATUS_FAILED;
811             }
812
813             CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
814             if (CA_STATUS_OK != ret)
815             {
816                 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
817                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
818                 return ret;
819             }
820         }
821         else
822         {
823             OIC_LOG(DEBUG, TAG, "start to connect LE");
824             CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
825             if (CA_STATUS_OK != ret)
826             {
827                 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
828                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
829                 return ret;
830             }
831         }
832     }
833
834     (*env)->ReleaseStringUTFChars(env, jni_address, address);
835     return CA_STATUS_OK;
836 }
837
838 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
839 {
840     VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
841     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
842
843     jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
844     if (!jni_cid_gattdevice_list)
845     {
846         OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
847         return NULL;
848     }
849
850     jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
851                                                       "()Landroid/bluetooth/BluetoothDevice;");
852     if (!jni_mid_getDevice)
853     {
854         OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
855         return NULL;
856     }
857
858     jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
859     if (!jni_obj_device)
860     {
861         OIC_LOG(ERROR, TAG, "jni_obj_device is null");
862         return NULL;
863     }
864
865     jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
866     if (!jni_address)
867     {
868         OIC_LOG(ERROR, TAG, "jni_address is null");
869         return NULL;
870     }
871
872     return jni_address;
873 }
874
875 /**
876  * BLE layer
877  */
878 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
879 {
880     // GATT CLOSE
881     OIC_LOG(DEBUG, TAG, "Gatt Close");
882     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
883     VERIFY_NON_NULL(env, TAG, "env is null");
884
885     // get BluetoothGatt class
886     OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
887     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
888     if (!jni_cid_BluetoothGatt)
889     {
890         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
891         return CA_STATUS_FAILED;
892     }
893
894     jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
895     if (!jni_mid_closeGatt)
896     {
897         OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
898         return CA_STATUS_OK;
899     }
900
901     // call disconnect gatt method
902     OIC_LOG(DEBUG, TAG, "request to close GATT");
903     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
904
905     if ((*env)->ExceptionCheck(env))
906     {
907         OIC_LOG(ERROR, TAG, "closeGATT has failed");
908         (*env)->ExceptionDescribe(env);
909         (*env)->ExceptionClear(env);
910         return CA_STATUS_FAILED;
911     }
912
913     return CA_STATUS_OK;
914 }
915
916 CAResult_t CALEClientStartScan()
917 {
918     if (!g_isStartedMulticastServer)
919     {
920         OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
921         return CA_STATUS_FAILED;
922     }
923
924     if (!g_isStartedLEClient)
925     {
926         OIC_LOG(ERROR, TAG, "LE client is not started");
927         return CA_STATUS_FAILED;
928     }
929
930     if (!g_jvm)
931     {
932         OIC_LOG(ERROR, TAG, "g_jvm is null");
933         return CA_STATUS_FAILED;
934     }
935
936     if (g_isStartedScan)
937     {
938         OIC_LOG(INFO, TAG, "scanning is already started");
939         return CA_STATUS_OK;
940     }
941
942     bool isAttached = false;
943     JNIEnv* env;
944     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
945     if (JNI_OK != res)
946     {
947         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
948
949         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
950         if (JNI_OK != res)
951         {
952             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
953             return CA_STATUS_FAILED;
954         }
955         isAttached = true;
956     }
957
958     OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
959
960     CAResult_t ret = CA_STATUS_OK;
961     // scan gatt server with UUID
962     if (g_leScanCallback && g_uuidList)
963     {
964 #ifdef UUID_SCAN
965         ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
966         if(CA_STATUS_OK != ret)
967         {
968             OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
969         }
970 #else
971         ret = CALEClientStartScanImpl(env, g_leScanCallback);
972         if (CA_STATUS_OK != ret)
973         {
974             OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
975         }
976 #endif
977     }
978
979     if (isAttached)
980     {
981         (*g_jvm)->DetachCurrentThread(g_jvm);
982     }
983
984     return ret;
985 }
986
987 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
988 {
989     VERIFY_NON_NULL(callback, TAG, "callback is null");
990     VERIFY_NON_NULL(env, TAG, "env is null");
991
992     if (!CALEIsEnableBTAdapter(env))
993     {
994         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
995         return CA_ADAPTER_NOT_ENABLED;
996     }
997
998     // get default bt adapter class
999     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1000     if (!jni_cid_BTAdapter)
1001     {
1002         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1003         return CA_STATUS_FAILED;
1004     }
1005
1006     // get remote bt adapter method
1007     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1008                                                                     "getDefaultAdapter",
1009                                                                     METHODID_OBJECTNONPARAM);
1010     if (!jni_mid_getDefaultAdapter)
1011     {
1012         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1013         return CA_STATUS_FAILED;
1014     }
1015
1016     // get start le scan method
1017     jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1018                                                         "(Landroid/bluetooth/BluetoothAdapter$"
1019                                                         "LeScanCallback;)Z");
1020     if (!jni_mid_startLeScan)
1021     {
1022         OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1023         return CA_STATUS_FAILED;
1024     }
1025
1026     // gat bt adapter object
1027     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1028                                                                jni_mid_getDefaultAdapter);
1029     if (!jni_obj_BTAdapter)
1030     {
1031         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1032         return CA_STATUS_FAILED;
1033     }
1034
1035     // call start le scan method
1036     jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1037                                                              jni_mid_startLeScan, callback);
1038     if (!jni_obj_startLeScan)
1039     {
1040         OIC_LOG(ERROR, TAG, "startLeScan is failed");
1041         return CA_STATUS_FAILED;
1042     }
1043     else
1044     {
1045         OIC_LOG(DEBUG, TAG, "startLeScan is started");
1046         g_isStartedScan = true;
1047     }
1048
1049     return CA_STATUS_OK;
1050 }
1051
1052 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1053 {
1054     VERIFY_NON_NULL(callback, TAG, "callback is null");
1055     VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1056     VERIFY_NON_NULL(env, TAG, "env is null");
1057
1058     if (!CALEIsEnableBTAdapter(env))
1059     {
1060         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1061         return CA_ADAPTER_NOT_ENABLED;
1062     }
1063
1064     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1065     if (!jni_cid_BTAdapter)
1066     {
1067         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1068         return CA_STATUS_FAILED;
1069     }
1070
1071     // get remote bt adapter method
1072     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1073                                                                     "getDefaultAdapter",
1074                                                                     METHODID_OBJECTNONPARAM);
1075     if (!jni_mid_getDefaultAdapter)
1076     {
1077         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1078         return CA_STATUS_FAILED;
1079     }
1080
1081     // get start le scan method
1082     jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1083                                                         "([Ljava/util/UUID;Landroid/bluetooth/"
1084                                                         "BluetoothAdapter$LeScanCallback;)Z");
1085     if (!jni_mid_startLeScan)
1086     {
1087         OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1088         return CA_STATUS_FAILED;
1089     }
1090
1091     // get bt adapter object
1092     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1093                                                                jni_mid_getDefaultAdapter);
1094     if (!jni_obj_BTAdapter)
1095     {
1096         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1097         return CA_STATUS_FAILED;
1098     }
1099
1100     // call start le scan method
1101     jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1102                                                              jni_mid_startLeScan, uuids, callback);
1103     if (!jni_obj_startLeScan)
1104     {
1105         OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1106         return CA_STATUS_FAILED;
1107     }
1108     else
1109     {
1110         OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1111         g_isStartedScan = true;
1112     }
1113
1114     return CA_STATUS_OK;
1115 }
1116
1117 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1118 {
1119     VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1120     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1121
1122     // setting UUID
1123     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1124     if (!jni_cid_uuid)
1125     {
1126         OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1127         return NULL;
1128     }
1129
1130     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1131                                                              "(Ljava/lang/String;)"
1132                                                              "Ljava/util/UUID;");
1133     if (!jni_mid_fromString)
1134     {
1135         OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1136         return NULL;
1137     }
1138
1139     jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1140     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1141                                                           jni_uuid);
1142     if (!jni_obj_uuid)
1143     {
1144         OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1145         return NULL;
1146     }
1147
1148     return jni_obj_uuid;
1149 }
1150
1151 CAResult_t CALEClientStopScan()
1152 {
1153     if (!g_jvm)
1154     {
1155         OIC_LOG(ERROR, TAG, "g_jvm is null");
1156         return CA_STATUS_FAILED;
1157     }
1158
1159     if (!g_isStartedScan)
1160     {
1161         OIC_LOG(INFO, TAG, "scanning is already stopped");
1162         return CA_STATUS_OK;
1163     }
1164
1165     bool isAttached = false;
1166     JNIEnv* env;
1167     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1168     if (JNI_OK != res)
1169     {
1170         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1171         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1172         if (JNI_OK != res)
1173         {
1174             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1175             return CA_STATUS_FAILED;
1176         }
1177         isAttached = true;
1178     }
1179
1180     CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1181     if (CA_STATUS_OK != ret)
1182     {
1183         OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1184     }
1185     else
1186     {
1187         g_isStartedScan = false;
1188     }
1189
1190     if (isAttached)
1191     {
1192         (*g_jvm)->DetachCurrentThread(g_jvm);
1193     }
1194
1195     return ret;
1196 }
1197
1198 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1199 {
1200     OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1201     VERIFY_NON_NULL(callback, TAG, "callback is null");
1202     VERIFY_NON_NULL(env, TAG, "env is null");
1203
1204     if (!CALEIsEnableBTAdapter(env))
1205     {
1206         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1207         return CA_ADAPTER_NOT_ENABLED;
1208     }
1209
1210     // get default bt adapter class
1211     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1212     if (!jni_cid_BTAdapter)
1213     {
1214         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1215         return CA_STATUS_FAILED;
1216     }
1217
1218     // get remote bt adapter method
1219     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1220                                                                     "getDefaultAdapter",
1221                                                                     METHODID_OBJECTNONPARAM);
1222     if (!jni_mid_getDefaultAdapter)
1223     {
1224         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1225         return CA_STATUS_FAILED;
1226     }
1227
1228     // get start le scan method
1229     jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1230                                                        "(Landroid/bluetooth/"
1231                                                        "BluetoothAdapter$LeScanCallback;)V");
1232     if (!jni_mid_stopLeScan)
1233     {
1234         OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1235         return CA_STATUS_FAILED;
1236     }
1237
1238     // gat bt adapter object
1239     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1240                                                                jni_mid_getDefaultAdapter);
1241     if (!jni_obj_BTAdapter)
1242     {
1243         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1244         return CA_STATUS_FAILED;
1245     }
1246
1247     OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1248     // call start le scan method
1249     (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1250     if ((*env)->ExceptionCheck(env))
1251     {
1252         OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1253         (*env)->ExceptionDescribe(env);
1254         (*env)->ExceptionClear(env);
1255         return CA_STATUS_FAILED;
1256     }
1257
1258     return CA_STATUS_OK;
1259 }
1260
1261 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1262                              jobject callback)
1263 {
1264     OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1265     VERIFY_NON_NULL(env, TAG, "env is null");
1266     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1267     VERIFY_NON_NULL(callback, TAG, "callback is null");
1268
1269     if (!CALEIsEnableBTAdapter(env))
1270     {
1271         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1272         return CA_ADAPTER_NOT_ENABLED;
1273     }
1274
1275     jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1276     if (!jni_address)
1277     {
1278         OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1279         return CA_STATUS_FAILED;
1280     }
1281
1282     // get BluetoothDevice class
1283     OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1284     jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1285     if (!jni_cid_BluetoothDevice)
1286     {
1287         OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1288         return CA_STATUS_FAILED;
1289     }
1290
1291     // get connectGatt method
1292     OIC_LOG(DEBUG, TAG, "get connectGatt method");
1293     jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1294                                                         "(Landroid/content/Context;ZLandroid/"
1295                                                         "bluetooth/BluetoothGattCallback;)"
1296                                                         "Landroid/bluetooth/BluetoothGatt;");
1297     if (!jni_mid_connectGatt)
1298     {
1299         OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1300         return CA_STATUS_FAILED;
1301     }
1302
1303     OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1304     jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1305                                                            jni_mid_connectGatt,
1306                                                            NULL,
1307                                                            autoconnect, callback);
1308     if (!jni_obj_connectGatt)
1309     {
1310         OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1311         CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1312         CALEClientUpdateSendCnt(env);
1313         return CA_STATUS_FAILED;
1314     }
1315     else
1316     {
1317         OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1318     }
1319     return CA_STATUS_OK;
1320 }
1321
1322 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1323 {
1324     OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1325     VERIFY_NON_NULL(env, TAG, "env is null");
1326     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1327
1328     if (!CALEIsEnableBTAdapter(env))
1329     {
1330         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1331         return CA_ADAPTER_NOT_ENABLED;
1332     }
1333
1334     // get BluetoothGatt class
1335     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1336     if (!jni_cid_BluetoothGatt)
1337     {
1338         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1339         return CA_STATUS_FAILED;
1340     }
1341
1342     OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1343     jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1344                                                            "disconnect", "()V");
1345     if (!jni_mid_disconnectGatt)
1346     {
1347         OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1348         return CA_STATUS_FAILED;
1349     }
1350
1351     // call disconnect gatt method
1352     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1353     if ((*env)->ExceptionCheck(env))
1354     {
1355         OIC_LOG(ERROR, TAG, "disconnect has failed");
1356         (*env)->ExceptionDescribe(env);
1357         (*env)->ExceptionClear(env);
1358         return CA_STATUS_FAILED;
1359     }
1360
1361     OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1362
1363     return CA_STATUS_OK;
1364 }
1365
1366 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1367 {
1368     OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1369     VERIFY_NON_NULL(env, TAG, "env is null");
1370
1371     if (!g_gattObjectList)
1372     {
1373         OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1374         return CA_STATUS_FAILED;
1375     }
1376
1377     uint32_t length = u_arraylist_length(g_gattObjectList);
1378     for (uint32_t index = 0; index < length; index++)
1379     {
1380         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1381         if (!jarrayObj)
1382         {
1383             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1384             continue;
1385         }
1386         CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1387         if (CA_STATUS_OK != res)
1388         {
1389             OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1390             continue;
1391         }
1392     }
1393
1394     OICFree(g_gattObjectList);
1395     g_gattObjectList = NULL;
1396
1397     return CA_STATUS_OK;
1398 }
1399
1400 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1401 {
1402     VERIFY_NON_NULL(env, TAG, "env is null");
1403     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1404
1405     if (!CALEIsEnableBTAdapter(env))
1406     {
1407         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1408         return CA_ADAPTER_NOT_ENABLED;
1409     }
1410
1411     // get BluetoothGatt class
1412     OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1413     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1414     if (!jni_cid_BluetoothGatt)
1415     {
1416         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1417         return CA_STATUS_FAILED;
1418     }
1419
1420     OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1421     jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1422                                                              "discoverServices", "()Z");
1423     if (!jni_mid_discoverServices)
1424     {
1425         OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1426         return CA_STATUS_FAILED;
1427     }
1428     // call disconnect gatt method
1429     OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1430     jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1431     if (!ret)
1432     {
1433         OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1434         return CA_STATUS_FAILED;
1435     }
1436
1437     return CA_STATUS_OK;
1438 }
1439
1440 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1441 {
1442     VERIFY_NON_NULL(env, TAG, "env is null");
1443     VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1444
1445     // send data
1446     jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1447     if (!jni_obj_character)
1448     {
1449         CALEClientSendFinish(env, gatt);
1450         return CA_STATUS_FAILED;
1451     }
1452
1453     CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1454     if (CA_STATUS_OK != ret)
1455     {
1456         CALEClientSendFinish(env, gatt);
1457         return ret;
1458     }
1459
1460     return CA_STATUS_OK;
1461 }
1462
1463 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1464                                            jobject gattCharacteristic)
1465 {
1466     OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1467     VERIFY_NON_NULL(env, TAG, "env is null");
1468     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1469     VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1470
1471     if (!CALEIsEnableBTAdapter(env))
1472     {
1473         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1474         return CA_STATUS_FAILED;
1475     }
1476
1477     // get BluetoothGatt class
1478     OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1479     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1480     if (!jni_cid_BluetoothGatt)
1481     {
1482         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1483         return CA_STATUS_FAILED;
1484     }
1485
1486     OIC_LOG(DEBUG, TAG, "write characteristic method");
1487     jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1488                                                                 "writeCharacteristic",
1489                                                                 "(Landroid/bluetooth/"
1490                                                                 "BluetoothGattCharacteristic;)Z");
1491     if (!jni_mid_writeCharacteristic)
1492     {
1493         OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1494         return CA_STATUS_FAILED;
1495     }
1496
1497     // call disconnect gatt method
1498     OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1499     jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1500                                                        jni_mid_writeCharacteristic,
1501                                                        gattCharacteristic);
1502     if (ret)
1503     {
1504         OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
1505     }
1506     else
1507     {
1508         OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1509         return CA_STATUS_FAILED;
1510     }
1511
1512     return CA_STATUS_OK;
1513 }
1514
1515 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1516 {
1517     VERIFY_NON_NULL(env, TAG, "env is null");
1518     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1519
1520     if (!CALEIsEnableBTAdapter(env))
1521     {
1522         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1523         return CA_STATUS_FAILED;
1524     }
1525
1526     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1527     if (!jni_cid_BluetoothGatt)
1528     {
1529         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1530         return CA_STATUS_FAILED;
1531     }
1532
1533     jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1534     if (!jni_uuid)
1535     {
1536         OIC_LOG(ERROR, TAG, "jni_uuid is null");
1537         return CA_STATUS_FAILED;
1538     }
1539
1540     jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1541     if (!jni_obj_GattCharacteristic)
1542     {
1543         OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1544         return CA_STATUS_FAILED;
1545     }
1546
1547     OIC_LOG(DEBUG, TAG, "read characteristic method");
1548     jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1549                                                                "readCharacteristic",
1550                                                                "(Landroid/bluetooth/"
1551                                                                "BluetoothGattCharacteristic;)Z");
1552     if (!jni_mid_readCharacteristic)
1553     {
1554         OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1555         return CA_STATUS_FAILED;
1556     }
1557
1558     // call disconnect gatt method
1559     OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1560     jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1561                                              jni_obj_GattCharacteristic);
1562     if (ret)
1563     {
1564         OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1565     }
1566     else
1567     {
1568         OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1569         return CA_STATUS_FAILED;
1570     }
1571
1572     return CA_STATUS_OK;
1573 }
1574
1575 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1576                                                    jobject characteristic)
1577 {
1578     VERIFY_NON_NULL(env, TAG, "env is null");
1579     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1580     VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1581
1582     if (!CALEIsEnableBTAdapter(env))
1583     {
1584         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1585         return CA_ADAPTER_NOT_ENABLED;
1586     }
1587
1588     // get BluetoothGatt class
1589     OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1590     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1591     if (!jni_cid_BluetoothGatt)
1592     {
1593         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1594         return CA_STATUS_FAILED;
1595     }
1596
1597     // set Characteristic Notification
1598     jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1599                                                             "setCharacteristicNotification",
1600                                                             "(Landroid/bluetooth/"
1601                                                             "BluetoothGattCharacteristic;Z)Z");
1602     if (!jni_mid_setNotification)
1603     {
1604         OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1605         return CA_STATUS_FAILED;
1606     }
1607
1608     jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1609                                              characteristic, JNI_TRUE);
1610     if (JNI_TRUE == ret)
1611     {
1612         OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1613     }
1614     else
1615     {
1616         OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1617         return CA_STATUS_FAILED;
1618     }
1619
1620     return CA_STATUS_OK;
1621 }
1622
1623 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1624 {
1625     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1626     VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1627     VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1628
1629     if (!CALEIsEnableBTAdapter(env))
1630     {
1631         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1632         return NULL;
1633     }
1634
1635     // get BluetoothGatt class
1636     OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1637     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1638     if (!jni_cid_BluetoothGatt)
1639     {
1640         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1641         return NULL;
1642     }
1643
1644     jmethodID jni_mid_getService = (*env)->GetMethodID(
1645             env, jni_cid_BluetoothGatt, "getService",
1646             "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1647     if (!jni_mid_getService)
1648     {
1649         OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1650         return NULL;
1651     }
1652
1653     jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1654     if (!jni_obj_service_uuid)
1655     {
1656         OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1657         return NULL;
1658     }
1659
1660     // get bluetooth gatt service
1661     OIC_LOG(DEBUG, TAG, "request to get service");
1662     jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1663                                                            jni_obj_service_uuid);
1664     if (!jni_obj_gattService)
1665     {
1666         OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1667         return NULL;
1668     }
1669
1670     // get bluetooth gatt service class
1671     jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1672             env, "android/bluetooth/BluetoothGattService");
1673     if (!jni_cid_BluetoothGattService)
1674     {
1675         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1676         return NULL;
1677     }
1678
1679     OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1680     jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1681                                                               "getCharacteristic",
1682                                                               "(Ljava/util/UUID;)"
1683                                                               "Landroid/bluetooth/"
1684                                                               "BluetoothGattCharacteristic;");
1685     if (!jni_mid_getCharacteristic)
1686     {
1687         OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1688         return NULL;
1689     }
1690
1691     const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1692     if (!uuid)
1693     {
1694         OIC_LOG(ERROR, TAG, "uuid is null");
1695         return NULL;
1696     }
1697
1698     jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1699     if (!jni_obj_tx_uuid)
1700     {
1701         OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1702         (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1703         return NULL;
1704     }
1705
1706     OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1707     jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1708                                                                   jni_mid_getCharacteristic,
1709                                                                   jni_obj_tx_uuid);
1710
1711     (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1712     return jni_obj_GattCharacteristic;
1713 }
1714
1715 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1716 {
1717     OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1718     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1719     VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1720     VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1721
1722     if (!CALEIsEnableBTAdapter(env))
1723     {
1724         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1725         return NULL;
1726     }
1727
1728     jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1729     if (!jni_uuid)
1730     {
1731         OIC_LOG(ERROR, TAG, "jni_uuid is null");
1732         return NULL;
1733     }
1734
1735     jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1736     if (!jni_obj_GattCharacteristic)
1737     {
1738         OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1739         return NULL;
1740     }
1741
1742     jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1743                                                             "/BluetoothGattCharacteristic");
1744     if (!jni_cid_BTGattCharacteristic)
1745     {
1746         OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1747         return NULL;
1748     }
1749
1750     OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1751     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1752                                                      "([B)Z");
1753     if (!jni_mid_setValue)
1754     {
1755         OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1756         return NULL;
1757     }
1758
1759     jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1760                                              data);
1761     if (JNI_TRUE == ret)
1762     {
1763         OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1764     }
1765     else
1766     {
1767         OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1768         return NULL;
1769     }
1770
1771     // set Write Type
1772     jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1773                                                          "setWriteType", "(I)V");
1774     if (!jni_mid_setWriteType)
1775     {
1776         OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1777         return NULL;
1778     }
1779
1780     jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1781                                                             "WRITE_TYPE_NO_RESPONSE", "I");
1782     if (!jni_fid_no_response)
1783     {
1784         OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1785         return NULL;
1786     }
1787
1788     jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1789                                                  jni_fid_no_response);
1790
1791     (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1792
1793     return jni_obj_GattCharacteristic;
1794 }
1795
1796 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1797 {
1798     VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1799     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1800
1801     if (!CALEIsEnableBTAdapter(env))
1802     {
1803         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1804         return NULL;
1805     }
1806
1807     jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1808                                                             "BluetoothGattCharacteristic");
1809     if (!jni_cid_BTGattCharacteristic)
1810     {
1811         OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1812         return NULL;
1813     }
1814
1815     OIC_LOG(DEBUG, TAG, "get value in Characteristic");
1816     jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1817                                                      "()[B");
1818     if (!jni_mid_getValue)
1819     {
1820         OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
1821         return NULL;
1822     }
1823
1824     jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
1825                                                              jni_mid_getValue);
1826     return jni_obj_data_array;
1827 }
1828
1829 CAResult_t CALEClientCreateUUIDList()
1830 {
1831     if (!g_jvm)
1832     {
1833         OIC_LOG(ERROR, TAG, "g_jvm is null");
1834         return CA_STATUS_FAILED;
1835     }
1836
1837     bool isAttached = false;
1838     JNIEnv* env;
1839     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1840     if (JNI_OK != res)
1841     {
1842         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1843         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1844
1845         if (JNI_OK != res)
1846         {
1847             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1848             return CA_STATUS_FAILED;
1849         }
1850         isAttached = true;
1851     }
1852
1853     // create new object array
1854     jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1855     if (!jni_cid_uuid_list)
1856     {
1857         OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
1858         goto error_exit;
1859     }
1860
1861     jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
1862                                                                           jni_cid_uuid_list, NULL);
1863     if (!jni_obj_uuid_list)
1864     {
1865         OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
1866         goto error_exit;
1867     }
1868
1869     // make uuid list
1870     jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1871     if (!jni_obj_uuid)
1872     {
1873         OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1874         goto error_exit;
1875     }
1876     (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1877
1878     g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1879
1880     if (isAttached)
1881     {
1882         (*g_jvm)->DetachCurrentThread(g_jvm);
1883     }
1884
1885     return CA_STATUS_OK;
1886
1887     // error label.
1888 error_exit:
1889
1890     if (isAttached)
1891     {
1892         (*g_jvm)->DetachCurrentThread(g_jvm);
1893     }
1894     return CA_STATUS_FAILED;
1895 }
1896
1897 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
1898                                          jobject characteristic)
1899 {
1900     VERIFY_NON_NULL(env, TAG, "env is null");
1901     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1902     VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1903
1904     if (!CALEIsEnableBTAdapter(env))
1905     {
1906         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1907         return CA_ADAPTER_NOT_ENABLED;
1908     }
1909
1910     OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
1911     jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1912                                                             "BluetoothGattCharacteristic");
1913     if (!jni_cid_BTGattCharacteristic)
1914     {
1915         OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1916         return CA_STATUS_FAILED;
1917     }
1918
1919     OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1920     jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1921                                                           "getDescriptor",
1922                                                           "(Ljava/util/UUID;)Landroid/bluetooth/"
1923                                                           "BluetoothGattDescriptor;");
1924     if (!jni_mid_getDescriptor)
1925     {
1926         OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
1927         return CA_STATUS_FAILED;
1928     }
1929
1930     jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1931     if (!jni_obj_cc_uuid)
1932     {
1933         OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
1934         return CA_STATUS_FAILED;
1935     }
1936
1937     OIC_LOG(DEBUG, TAG, "request to get descriptor");
1938     jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
1939                                                           jni_mid_getDescriptor, jni_obj_cc_uuid);
1940     if (!jni_obj_descriptor)
1941     {
1942         OIC_LOG(ERROR, TAG, "jni_obj_descriptor is null");
1943         return CA_STATUS_FAILED;
1944     }
1945
1946     OIC_LOG(DEBUG, TAG, "set value in descriptor");
1947     jclass jni_cid_descriptor = (*env)->FindClass(env,
1948                                                   "android/bluetooth/BluetoothGattDescriptor");
1949     if (!jni_cid_descriptor)
1950     {
1951         OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
1952         return CA_STATUS_FAILED;
1953     }
1954
1955     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
1956     if (!jni_mid_setValue)
1957     {
1958         OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1959         return CA_STATUS_FAILED;
1960     }
1961
1962     jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
1963                                                           "ENABLE_NOTIFICATION_VALUE", "[B");
1964     if (!jni_fid_NotiValue)
1965     {
1966         OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
1967         return CA_STATUS_FAILED;
1968     }
1969
1970     OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
1971
1972     jboolean jni_setvalue = (*env)->CallBooleanMethod(
1973             env, jni_obj_descriptor, jni_mid_setValue,
1974             (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
1975     if (jni_setvalue)
1976     {
1977         OIC_LOG(DEBUG, TAG, "setValue success");
1978     }
1979     else
1980     {
1981         OIC_LOG(ERROR, TAG, "setValue has failed");
1982         return CA_STATUS_FAILED;
1983     }
1984
1985     jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
1986     if (!jni_cid_gatt)
1987     {
1988         OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
1989         return CA_STATUS_FAILED;
1990     }
1991
1992     OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
1993     jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
1994                                                             "(Landroid/bluetooth/"
1995                                                             "BluetoothGattDescriptor;)Z");
1996     if (!jni_mid_writeDescriptor)
1997     {
1998         OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
1999         return CA_STATUS_FAILED;
2000     }
2001
2002     OIC_LOG(DEBUG, TAG, "request to write descriptor");
2003     jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2004                                                  jni_obj_descriptor);
2005     if (jni_ret)
2006     {
2007         OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2008     }
2009     else
2010     {
2011         OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2012         return CA_STATUS_FAILED;
2013     }
2014
2015     return CA_STATUS_OK;
2016 }
2017
2018 void CALEClientCreateScanDeviceList(JNIEnv *env)
2019 {
2020     OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2021     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2022
2023     ca_mutex_lock(g_deviceListMutex);
2024     // create new object array
2025     if (g_deviceList == NULL)
2026     {
2027         OIC_LOG(DEBUG, TAG, "Create device list");
2028
2029         g_deviceList = u_arraylist_create();
2030     }
2031     ca_mutex_unlock(g_deviceListMutex);
2032 }
2033
2034 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2035 {
2036     OIC_LOG(DEBUG, TAG, "IN - CALEClientAddScanDeviceToList");
2037     VERIFY_NON_NULL(device, TAG, "device is null");
2038     VERIFY_NON_NULL(env, TAG, "env is null");
2039
2040     ca_mutex_lock(g_deviceListMutex);
2041
2042     if (!g_deviceList)
2043     {
2044         OIC_LOG(ERROR, TAG, "gdevice_list is null");
2045         ca_mutex_unlock(g_deviceListMutex);
2046         return CA_STATUS_FAILED;
2047     }
2048
2049     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2050     if (!jni_remoteAddress)
2051     {
2052         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2053         ca_mutex_unlock(g_deviceListMutex);
2054         return CA_STATUS_FAILED;
2055     }
2056
2057     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2058     if (!remoteAddress)
2059     {
2060         OIC_LOG(ERROR, TAG, "remoteAddress is null");
2061         ca_mutex_unlock(g_deviceListMutex);
2062         return CA_STATUS_FAILED;
2063     }
2064
2065     if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2066     {
2067         jobject gdevice = (*env)->NewGlobalRef(env, device);
2068         u_arraylist_add(g_deviceList, gdevice);
2069         OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
2070     }
2071     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2072
2073     ca_mutex_unlock(g_deviceListMutex);
2074
2075     OIC_LOG(DEBUG, TAG, "OUT - CALEClientAddScanDeviceToList");
2076     return CA_STATUS_OK;
2077 }
2078
2079 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2080 {
2081     OIC_LOG(DEBUG, TAG, "IN - CALEClientIsDeviceInScanDeviceList");
2082     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2083     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2084
2085     if (!g_deviceList)
2086     {
2087         OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2088         return true;
2089     }
2090
2091     uint32_t length = u_arraylist_length(g_deviceList);
2092     for (uint32_t index = 0; index < length; index++)
2093     {
2094         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2095         if (!jarrayObj)
2096         {
2097             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2098             return true;
2099         }
2100
2101         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2102         if (!jni_setAddress)
2103         {
2104             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2105             return true;
2106         }
2107
2108         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2109         if (!setAddress)
2110         {
2111             OIC_LOG(ERROR, TAG, "setAddress is null");
2112             return true;
2113         }
2114
2115         if (!strcmp(remoteAddress, setAddress))
2116         {
2117             OIC_LOG(DEBUG, TAG, "the device is already set");
2118             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2119             return true;
2120         }
2121
2122         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2123     }
2124
2125     OIC_LOG(DEBUG, TAG, "OUT - CALEClientIsDeviceInScanDeviceList");
2126     OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2127
2128     return false;
2129 }
2130
2131 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2132 {
2133     OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2134     VERIFY_NON_NULL(env, TAG, "env is null");
2135
2136     ca_mutex_lock(g_deviceListMutex);
2137
2138     if (!g_deviceList)
2139     {
2140         OIC_LOG(ERROR, TAG, "g_deviceList is null");
2141         ca_mutex_unlock(g_deviceListMutex);
2142         return CA_STATUS_FAILED;
2143     }
2144
2145     uint32_t length = u_arraylist_length(g_deviceList);
2146     for (uint32_t index = 0; index < length; index++)
2147     {
2148         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2149         if (!jarrayObj)
2150         {
2151             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2152             continue;
2153         }
2154         (*env)->DeleteGlobalRef(env, jarrayObj);
2155     }
2156
2157     OICFree(g_deviceList);
2158     g_deviceList = NULL;
2159
2160     ca_mutex_unlock(g_deviceListMutex);
2161     return CA_STATUS_OK;
2162 }
2163
2164 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2165 {
2166     OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2167     VERIFY_NON_NULL(address, TAG, "address is null");
2168     VERIFY_NON_NULL(env, TAG, "env is null");
2169
2170     ca_mutex_lock(g_deviceListMutex);
2171
2172     if (!g_deviceList)
2173     {
2174         OIC_LOG(ERROR, TAG, "g_deviceList is null");
2175         ca_mutex_unlock(g_deviceListMutex);
2176         return CA_STATUS_FAILED;
2177     }
2178
2179     uint32_t length = u_arraylist_length(g_deviceList);
2180     for (uint32_t index = 0; index < length; index++)
2181     {
2182         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2183         if (!jarrayObj)
2184         {
2185             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2186             ca_mutex_unlock(g_deviceListMutex);
2187             return CA_STATUS_FAILED;
2188         }
2189
2190         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2191         if (!jni_setAddress)
2192         {
2193             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2194             ca_mutex_unlock(g_deviceListMutex);
2195             return CA_STATUS_FAILED;
2196         }
2197
2198         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2199         if (!setAddress)
2200         {
2201             OIC_LOG(ERROR, TAG, "setAddress is null");
2202             ca_mutex_unlock(g_deviceListMutex);
2203             return CA_STATUS_FAILED;
2204         }
2205
2206         const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2207         if (!remoteAddress)
2208         {
2209             OIC_LOG(ERROR, TAG, "remoteAddress is null");
2210             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2211             ca_mutex_unlock(g_deviceListMutex);
2212             return CA_STATUS_FAILED;
2213         }
2214
2215         if (!strcmp(setAddress, remoteAddress))
2216         {
2217             OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2218             (*env)->DeleteGlobalRef(env, jarrayObj);
2219             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2220             (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2221
2222             CALEClientReorderingList(index, g_deviceList);
2223             ca_mutex_unlock(g_deviceListMutex);
2224             return CA_STATUS_OK;
2225         }
2226         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2227         (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2228     }
2229
2230     ca_mutex_unlock(g_deviceListMutex);
2231     OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2232
2233     return CA_STATUS_OK;
2234 }
2235
2236 /**
2237  * Gatt Object List
2238  */
2239
2240 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2241 {
2242     OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2243     VERIFY_NON_NULL(env, TAG, "env is null");
2244     VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2245
2246     ca_mutex_lock(g_gattObjectMutex);
2247
2248     jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2249     if (!jni_remoteAddress)
2250     {
2251         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2252         ca_mutex_unlock(g_gattObjectMutex);
2253         return CA_STATUS_FAILED;
2254     }
2255
2256     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2257     if (!remoteAddress)
2258     {
2259         OIC_LOG(ERROR, TAG, "remoteAddress is null");
2260         ca_mutex_unlock(g_gattObjectMutex);
2261         return CA_STATUS_FAILED;
2262     }
2263
2264     if (!CALEClientIsGattObjInList(env, remoteAddress))
2265     {
2266         jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2267         u_arraylist_add(g_gattObjectList, newGatt);
2268         OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2269     }
2270
2271     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2272     ca_mutex_unlock(g_gattObjectMutex);
2273     return CA_STATUS_OK;
2274 }
2275
2276 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2277 {
2278     OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2279     VERIFY_NON_NULL(env, TAG, "env is null");
2280     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2281
2282     uint32_t length = u_arraylist_length(g_gattObjectList);
2283     for (uint32_t index = 0; index < length; index++)
2284     {
2285
2286         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2287         if (!jarrayObj)
2288         {
2289             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2290             return true;
2291         }
2292
2293         jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2294         if (!jni_setAddress)
2295         {
2296             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2297             return true;
2298         }
2299
2300         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2301         if (!setAddress)
2302         {
2303             OIC_LOG(ERROR, TAG, "setAddress is null");
2304             return true;
2305         }
2306
2307         if (!strcmp(remoteAddress, setAddress))
2308         {
2309             OIC_LOG(DEBUG, TAG, "the device is already set");
2310             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2311             return true;
2312         }
2313         else
2314         {
2315             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2316             continue;
2317         }
2318     }
2319
2320     OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2321     return false;
2322 }
2323
2324 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2325 {
2326     OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2327     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2328     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2329
2330     ca_mutex_lock(g_gattObjectMutex);
2331     uint32_t length = u_arraylist_length(g_gattObjectList);
2332     for (uint32_t index = 0; index < length; index++)
2333     {
2334         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2335         if (!jarrayObj)
2336         {
2337             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2338             ca_mutex_unlock(g_gattObjectMutex);
2339             return NULL;
2340         }
2341
2342         jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2343         if (!jni_setAddress)
2344         {
2345             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2346             ca_mutex_unlock(g_gattObjectMutex);
2347             return NULL;
2348         }
2349
2350         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2351         if (!setAddress)
2352         {
2353             OIC_LOG(ERROR, TAG, "setAddress is null");
2354             ca_mutex_unlock(g_gattObjectMutex);
2355             return NULL;
2356         }
2357
2358         if (!strcmp(remoteAddress, setAddress))
2359         {
2360             OIC_LOG(DEBUG, TAG, "the device is already set");
2361             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2362             ca_mutex_unlock(g_gattObjectMutex);
2363             return jarrayObj;
2364         }
2365         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2366     }
2367
2368     ca_mutex_unlock(g_gattObjectMutex);
2369     OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2370     return NULL;
2371 }
2372
2373 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2374 {
2375     OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2376     VERIFY_NON_NULL(env, TAG, "env is null");
2377
2378     ca_mutex_lock(g_gattObjectMutex);
2379     if (!g_gattObjectList)
2380     {
2381         OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2382         ca_mutex_unlock(g_gattObjectMutex);
2383         return CA_STATUS_FAILED;
2384     }
2385
2386     uint32_t length = u_arraylist_length(g_gattObjectList);
2387     for (uint32_t index = 0; index < length; index++)
2388     {
2389         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2390         if (!jarrayObj)
2391         {
2392             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2393             continue;
2394         }
2395         (*env)->DeleteGlobalRef(env, jarrayObj);
2396     }
2397
2398     OICFree(g_gattObjectList);
2399     g_gattObjectList = NULL;
2400     ca_mutex_unlock(g_gattObjectMutex);
2401     return CA_STATUS_OK;
2402 }
2403
2404 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2405 {
2406     OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2407     VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2408     VERIFY_NON_NULL(env, TAG, "env is null");
2409
2410     ca_mutex_lock(g_gattObjectMutex);
2411     if (!g_gattObjectList)
2412     {
2413         OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2414         ca_mutex_unlock(g_gattObjectMutex);
2415         return CA_STATUS_FAILED;
2416     }
2417
2418     uint32_t length = u_arraylist_length(g_gattObjectList);
2419     for (uint32_t index = 0; index < length; index++)
2420     {
2421         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2422         if (!jarrayObj)
2423         {
2424             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2425             ca_mutex_unlock(g_gattObjectMutex);
2426             return CA_STATUS_FAILED;
2427         }
2428
2429         jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2430         if (!jni_setAddress)
2431         {
2432             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2433             ca_mutex_unlock(g_gattObjectMutex);
2434             return CA_STATUS_FAILED;
2435         }
2436
2437         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2438         if (!setAddress)
2439         {
2440             OIC_LOG(ERROR, TAG, "setAddress is null");
2441             ca_mutex_unlock(g_gattObjectMutex);
2442             return CA_STATUS_FAILED;
2443         }
2444
2445         jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2446         if (!jni_remoteAddress)
2447         {
2448             OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2449             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2450             ca_mutex_unlock(g_gattObjectMutex);
2451             return CA_STATUS_FAILED;
2452         }
2453
2454         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2455         if (!remoteAddress)
2456         {
2457             OIC_LOG(ERROR, TAG, "remoteAddress is null");
2458             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2459             ca_mutex_unlock(g_gattObjectMutex);
2460             return CA_STATUS_FAILED;
2461         }
2462
2463         if (!strcmp(setAddress, remoteAddress))
2464         {
2465             OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2466             (*env)->DeleteGlobalRef(env, jarrayObj);
2467             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2468             (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2469             ca_mutex_unlock(g_gattObjectMutex);
2470             return CALEClientReorderingList(index, g_gattObjectList);
2471         }
2472         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2473         (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2474     }
2475
2476     ca_mutex_unlock(g_gattObjectMutex);
2477     OIC_LOG(DEBUG, TAG, "there are no target object");
2478     return CA_STATUS_OK;
2479 }
2480
2481 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2482 {
2483     OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2484     VERIFY_NON_NULL(addr, TAG, "addr is null");
2485     VERIFY_NON_NULL(env, TAG, "env is null");
2486
2487     ca_mutex_lock(g_gattObjectMutex);
2488     if (!g_gattObjectList)
2489     {
2490         OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2491         ca_mutex_unlock(g_gattObjectMutex);
2492         return CA_STATUS_FAILED;
2493     }
2494
2495     uint32_t length = u_arraylist_length(g_gattObjectList);
2496     for (uint32_t index = 0; index < length; index++)
2497     {
2498         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2499         if (!jarrayObj)
2500         {
2501             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2502             ca_mutex_unlock(g_gattObjectMutex);
2503             return CA_STATUS_FAILED;
2504         }
2505
2506         jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2507         if (!jni_setAddress)
2508         {
2509             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2510             ca_mutex_unlock(g_gattObjectMutex);
2511             return CA_STATUS_FAILED;
2512         }
2513
2514         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2515         if (!setAddress)
2516         {
2517             OIC_LOG(ERROR, TAG, "setAddress is null");
2518             ca_mutex_unlock(g_gattObjectMutex);
2519             return CA_STATUS_FAILED;
2520         }
2521
2522         const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2523         if (!remoteAddress)
2524         {
2525             OIC_LOG(ERROR, TAG, "remoteAddress is null");
2526             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2527             ca_mutex_unlock(g_gattObjectMutex);
2528             return CA_STATUS_FAILED;
2529         }
2530
2531         if (!strcmp(setAddress, remoteAddress))
2532         {
2533             OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2534             (*env)->DeleteGlobalRef(env, jarrayObj);
2535
2536             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2537             (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2538             ca_mutex_unlock(g_gattObjectMutex);
2539             return CALEClientReorderingList(index, g_gattObjectList);
2540         }
2541         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2542         (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2543     }
2544
2545     ca_mutex_unlock(g_gattObjectMutex);
2546     OIC_LOG(DEBUG, TAG, "there are no target object");
2547     return CA_STATUS_FAILED;
2548 }
2549
2550 /**
2551  * BT State List
2552  */
2553
2554 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2555                                        uint16_t notificationState, uint16_t sendState)
2556 {
2557     VERIFY_NON_NULL(address, TAG, "address is null");
2558
2559     CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2560     if (!newstate)
2561     {
2562         OIC_LOG(ERROR, TAG, "out of memory");
2563         return CA_MEMORY_ALLOC_FAILED;
2564     }
2565
2566     if (strlen(address) > CA_MACADDR_SIZE)
2567     {
2568         OIC_LOG(ERROR, TAG, "address is not proper");
2569         OICFree(newstate);
2570         return CA_STATUS_FAILED;
2571     }
2572
2573     OICStrcpy(newstate->address, sizeof(newstate->address), address);
2574     newstate->connectedState = connectedState;
2575     newstate->notificationState = notificationState;
2576     newstate->sendState = sendState;
2577     return CALEClientAddDeviceStateToList(newstate);
2578 }
2579
2580 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2581 {
2582     VERIFY_NON_NULL(state, TAG, "state is null");
2583
2584     ca_mutex_lock(g_deviceStateListMutex);
2585
2586     if (!g_deviceStateList)
2587     {
2588         OIC_LOG(ERROR, TAG, "gdevice_list is null");
2589         ca_mutex_unlock(g_deviceStateListMutex);
2590         return CA_STATUS_FAILED;
2591     }
2592
2593     if (CALEClientIsDeviceInList(state->address))
2594     {
2595         CALEState_t* curState = CALEClientGetStateInfo(state->address);
2596         if(!curState)
2597         {
2598             OIC_LOG(ERROR, TAG, "curState is null");
2599             ca_mutex_unlock(g_deviceStateListMutex);
2600             return CA_STATUS_FAILED;
2601         }
2602
2603         if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2604         {
2605             state->notificationState = curState->notificationState;
2606         }
2607
2608         // delete previous state for update new state
2609         CAResult_t res = CALEClientRemoveDeviceState(state->address);
2610         if (CA_STATUS_OK != res)
2611         {
2612             OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2613             ca_mutex_unlock(g_deviceStateListMutex);
2614             return res;
2615         }
2616     }
2617     u_arraylist_add(g_deviceStateList, state); // update new state
2618     OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2619               state->connectedState, state->notificationState);
2620
2621     ca_mutex_unlock(g_deviceStateListMutex);
2622     return CA_STATUS_OK;
2623 }
2624
2625 bool CALEClientIsDeviceInList(const char* remoteAddress)
2626 {
2627     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2628
2629     if (!g_deviceStateList)
2630     {
2631         OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2632         return false;
2633     }
2634
2635     uint32_t length = u_arraylist_length(g_deviceStateList);
2636     for (uint32_t index = 0; index < length; index++)
2637     {
2638         CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2639         if (!state)
2640         {
2641             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2642             return false;
2643         }
2644
2645         if (!strcmp(remoteAddress, state->address))
2646         {
2647             OIC_LOG(DEBUG, TAG, "the device is already set");
2648             return true;
2649         }
2650         else
2651         {
2652             continue;
2653         }
2654     }
2655
2656     OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2657     return false;
2658 }
2659
2660 CAResult_t CALEClientRemoveAllDeviceState()
2661 {
2662     OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2663
2664     ca_mutex_lock(g_deviceStateListMutex);
2665     if (!g_deviceStateList)
2666     {
2667         OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2668         ca_mutex_unlock(g_deviceStateListMutex);
2669         return CA_STATUS_FAILED;
2670     }
2671
2672     uint32_t length = u_arraylist_length(g_deviceStateList);
2673     for (uint32_t index = 0; index < length; index++)
2674     {
2675         CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2676         if (!state)
2677         {
2678             OIC_LOG(ERROR, TAG, "jarrayObj is null");
2679             continue;
2680         }
2681         OICFree(state);
2682     }
2683
2684     OICFree(g_deviceStateList);
2685     g_deviceStateList = NULL;
2686     ca_mutex_unlock(g_deviceStateListMutex);
2687
2688     return CA_STATUS_OK;
2689 }
2690
2691 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2692 {
2693     OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2694     VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2695
2696     if (!g_deviceStateList)
2697     {
2698         OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2699         return CA_STATUS_FAILED;
2700     }
2701
2702     uint32_t length = u_arraylist_length(g_deviceStateList);
2703     for (uint32_t index = 0; index < length; index++)
2704     {
2705         CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2706         if (!state)
2707         {
2708             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2709             continue;
2710         }
2711
2712         if (!strcmp(state->address, remoteAddress))
2713         {
2714             OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2715             OICFree(state);
2716
2717             CAResult_t res = CALEClientReorderingList(index, g_deviceStateList);
2718             if(CA_STATUS_OK != res)
2719             {
2720                 OIC_LOG(ERROR, TAG, "CALEClientReorderingList has failed");
2721                 return res;
2722             }
2723             return CA_STATUS_OK;
2724         }
2725     }
2726
2727     return CA_STATUS_FAILED;
2728 }
2729
2730 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2731 {
2732     OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2733     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2734
2735     if (!g_deviceStateList)
2736     {
2737         OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2738         return NULL;
2739     }
2740
2741     uint32_t length = u_arraylist_length(g_deviceStateList);
2742     for (uint32_t index = 0; index < length; index++)
2743     {
2744         CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2745         if (!state)
2746         {
2747             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2748             continue;
2749         }
2750
2751         if (!strcmp(state->address, remoteAddress))
2752         {
2753             OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2754             return state;
2755         }
2756     }
2757     return NULL;
2758 }
2759
2760 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2761 {
2762     OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2763     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2764
2765     ca_mutex_lock(g_deviceStateListMutex);
2766     if (!g_deviceStateList)
2767     {
2768         OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2769         ca_mutex_unlock(g_deviceStateListMutex);
2770         return false;
2771     }
2772
2773     uint32_t length = u_arraylist_length(g_deviceStateList);
2774     for (uint32_t index = 0; index < length; index++)
2775     {
2776         CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2777         if (!state)
2778         {
2779             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2780             continue;
2781         }
2782
2783         if (!strcmp(state->address, remoteAddress))
2784         {
2785             OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2786
2787             if (STATE_CONNECTED == state->connectedState)
2788             {
2789                 ca_mutex_unlock(g_deviceStateListMutex);
2790                 return true;
2791             }
2792             else
2793             {
2794                 ca_mutex_unlock(g_deviceStateListMutex);
2795                 return false;
2796             }
2797         }
2798     }
2799     ca_mutex_unlock(g_deviceStateListMutex);
2800     return false;
2801 }
2802
2803 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2804 {
2805     OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2806     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2807
2808     ca_mutex_lock(g_deviceStateListMutex);
2809     if (!g_deviceStateList)
2810     {
2811         OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2812         ca_mutex_unlock(g_deviceStateListMutex);
2813         return false;
2814     }
2815
2816     uint32_t length = u_arraylist_length(g_deviceStateList);
2817     for (uint32_t index = 0; index < length; index++)
2818     {
2819         CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2820         if (!state)
2821         {
2822             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2823             continue;
2824         }
2825
2826         if (!strcmp(state->address, remoteAddress))
2827         {
2828             OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2829
2830             if (STATE_CHARACTER_SET == state->notificationState)
2831             {
2832                 ca_mutex_unlock(g_deviceStateListMutex);
2833                 return true;
2834             }
2835             else
2836             {
2837                 ca_mutex_unlock(g_deviceStateListMutex);
2838                 return false;
2839             }
2840         }
2841     }
2842
2843     ca_mutex_unlock(g_deviceStateListMutex);
2844     return false;
2845 }
2846
2847 void CALEClientCreateDeviceList()
2848 {
2849     OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2850
2851     // create new object array
2852     if (!g_gattObjectList)
2853     {
2854         OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2855
2856         g_gattObjectList = u_arraylist_create();
2857     }
2858
2859     if (!g_deviceStateList)
2860     {
2861         OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2862
2863         g_deviceStateList = u_arraylist_create();
2864     }
2865
2866     if (!g_deviceList)
2867     {
2868         OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2869
2870         g_deviceList = u_arraylist_create();
2871     }
2872 }
2873
2874 CAResult_t CALEClientReorderingList(uint32_t index, u_arraylist_t *list)
2875 {
2876     if (!list)
2877     {
2878         OIC_LOG(ERROR, TAG, "list is null");
2879         return CA_STATUS_FAILED;
2880     }
2881
2882     if (index >= list->length)
2883     {
2884         OIC_LOG(ERROR, TAG, "index is not available");
2885         return CA_STATUS_FAILED;
2886     }
2887
2888     if (index < list->length - 1)
2889     {
2890         memmove(&list->data[index], &list->data[index + 1],
2891                 (list->length - index - 1) * sizeof(void *));
2892     }
2893
2894     list->size--;
2895     list->length--;
2896
2897     return CA_STATUS_OK;
2898 }
2899
2900 /**
2901  * Check Sent Count for remove g_sendBuffer
2902  */
2903 void CALEClientUpdateSendCnt(JNIEnv *env)
2904 {
2905     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2906     // mutex lock
2907     ca_mutex_lock(g_threadMutex);
2908
2909     g_currentSentCnt++;
2910
2911     if (g_targetCnt <= g_currentSentCnt)
2912     {
2913         g_targetCnt = 0;
2914         g_currentSentCnt = 0;
2915
2916         if (g_sendBuffer)
2917         {
2918             (*env)->DeleteGlobalRef(env, g_sendBuffer);
2919             g_sendBuffer = NULL;
2920         }
2921         // notity the thread
2922         ca_cond_signal(g_threadCond);
2923         CALEClientSetSendFinishFlag(true);
2924         OIC_LOG(DEBUG, TAG, "set signal for send data");
2925     }
2926     // mutex unlock
2927     ca_mutex_unlock(g_threadMutex);
2928 }
2929
2930 CAResult_t CALEClientInitGattMutexVaraibles()
2931 {
2932     OIC_LOG(DEBUG, TAG, "IN");
2933
2934     if (NULL == g_bleReqRespClientCbMutex)
2935     {
2936         g_bleReqRespClientCbMutex = ca_mutex_new();
2937         if (NULL == g_bleReqRespClientCbMutex)
2938         {
2939             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2940             return CA_STATUS_FAILED;
2941         }
2942     }
2943
2944     if (NULL == g_bleServerBDAddressMutex)
2945     {
2946         g_bleServerBDAddressMutex = ca_mutex_new();
2947         if (NULL == g_bleServerBDAddressMutex)
2948         {
2949             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2950             return CA_STATUS_FAILED;
2951         }
2952     }
2953
2954     if (NULL == g_threadMutex)
2955     {
2956         g_threadMutex = ca_mutex_new();
2957         if (NULL == g_threadMutex)
2958         {
2959             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2960             return CA_STATUS_FAILED;
2961         }
2962     }
2963
2964     if (NULL == g_threadSendMutex)
2965     {
2966         g_threadSendMutex = ca_mutex_new();
2967         if (NULL == g_threadSendMutex)
2968         {
2969             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2970             return CA_STATUS_FAILED;
2971         }
2972     }
2973
2974     if (NULL == g_deviceListMutex)
2975     {
2976         g_deviceListMutex = ca_mutex_new();
2977         if (NULL == g_deviceListMutex)
2978         {
2979             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2980             return CA_STATUS_FAILED;
2981         }
2982     }
2983
2984     if (NULL == g_gattObjectMutex)
2985     {
2986         g_gattObjectMutex = ca_mutex_new();
2987         if (NULL == g_gattObjectMutex)
2988         {
2989             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2990             return CA_STATUS_FAILED;
2991         }
2992     }
2993
2994     if (NULL == g_deviceStateListMutex)
2995     {
2996         g_deviceStateListMutex = ca_mutex_new();
2997         if (NULL == g_deviceStateListMutex)
2998         {
2999             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3000             return CA_STATUS_FAILED;
3001         }
3002     }
3003
3004     if (NULL == g_SendFinishMutex)
3005     {
3006         g_SendFinishMutex = ca_mutex_new();
3007         if (NULL == g_SendFinishMutex)
3008         {
3009             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3010             return CA_STATUS_FAILED;
3011         }
3012     }
3013
3014     OIC_LOG(DEBUG, TAG, "OUT");
3015     return CA_STATUS_OK;
3016 }
3017
3018 void CALEClientTerminateGattMutexVariables()
3019 {
3020     OIC_LOG(DEBUG, TAG, "IN");
3021
3022     ca_mutex_free(g_bleReqRespClientCbMutex);
3023     g_bleReqRespClientCbMutex = NULL;
3024
3025     ca_mutex_free(g_bleServerBDAddressMutex);
3026     g_bleServerBDAddressMutex = NULL;
3027
3028     ca_mutex_free(g_threadMutex);
3029     g_threadMutex = NULL;
3030
3031     ca_mutex_free(g_threadSendMutex);
3032     g_threadSendMutex = NULL;
3033
3034     ca_mutex_free(g_deviceListMutex);
3035     g_deviceListMutex = NULL;
3036
3037     ca_mutex_free(g_SendFinishMutex);
3038     g_SendFinishMutex = NULL;
3039
3040     OIC_LOG(DEBUG, TAG, "OUT");
3041 }
3042
3043 void CALEClientSetSendFinishFlag(bool flag)
3044 {
3045     OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3046
3047     ca_mutex_lock(g_SendFinishMutex);
3048     g_isFinishedSendData = flag;
3049     ca_mutex_unlock(g_SendFinishMutex);
3050 }
3051
3052 /**
3053  * adapter common
3054  */
3055
3056 CAResult_t CAStartLEGattClient()
3057 {
3058     CAResult_t res = CALEClientStartMulticastServer();
3059     if (CA_STATUS_OK != res)
3060     {
3061         OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3062     }
3063     else
3064     {
3065         g_isStartedLEClient = true;
3066     }
3067
3068     return res;
3069 }
3070
3071 void CAStopLEGattClient()
3072 {
3073     OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3074
3075     if (!g_jvm)
3076     {
3077         OIC_LOG(ERROR, TAG, "g_jvm is null");
3078         return;
3079     }
3080
3081     bool isAttached = false;
3082     JNIEnv* env;
3083     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3084     if (JNI_OK != res)
3085     {
3086         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3087         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3088
3089         if (JNI_OK != res)
3090         {
3091             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3092             return;
3093         }
3094         isAttached = true;
3095     }
3096
3097     CAResult_t ret = CALEClientDisconnectAll(env);
3098     if (CA_STATUS_OK != ret)
3099     {
3100         OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3101     }
3102
3103     ret = CALEClientStopScan();
3104     if(CA_STATUS_OK != ret)
3105     {
3106         OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3107     }
3108
3109     ca_cond_signal(g_threadCond);
3110
3111     if (isAttached)
3112     {
3113         (*g_jvm)->DetachCurrentThread(g_jvm);
3114     }
3115
3116 }
3117
3118 void CATerminateLEGattClient()
3119 {
3120     OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3121     CALEClientTerminate();
3122 }
3123
3124 CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char  *data,
3125                                                 uint32_t dataLen, CALETransferType_t type,
3126                                                 int32_t position)
3127 {
3128     OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3129     VERIFY_NON_NULL(data, TAG, "data is null");
3130     VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3131
3132     if (LE_UNICAST != type || position < 0)
3133     {
3134         OIC_LOG(ERROR, TAG, "this request is not unicast");
3135         return CA_STATUS_INVALID_PARAM;
3136     }
3137
3138     return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3139 }
3140
3141 CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, uint32_t dataLen)
3142 {
3143     OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3144     VERIFY_NON_NULL(data, TAG, "data is null");
3145
3146     return CALEClientSendMulticastMessage(data, dataLen);
3147 }
3148
3149 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3150 {
3151     OIC_LOG(DEBUG, TAG, "IN");
3152
3153     ca_mutex_lock(g_bleReqRespClientCbMutex);
3154     g_CABLEClientDataReceivedCallback = callback;
3155     ca_mutex_unlock(g_bleReqRespClientCbMutex);
3156
3157     OIC_LOG(DEBUG, TAG, "OUT");
3158 }
3159
3160 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3161 {
3162     OIC_LOG(DEBUG, TAG, "IN");
3163
3164     CALEClientInitialize(handle);
3165
3166     OIC_LOG(DEBUG, TAG, "OUT");
3167 }
3168
3169 CAResult_t CAGetLEAddress(char **local_address)
3170 {
3171     VERIFY_NON_NULL(local_address, TAG, "local_address");
3172     OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3173     return CA_NOT_SUPPORTED;
3174 }
3175
3176 JNIEXPORT void JNICALL
3177 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3178                                                                     jobject callback)
3179 {
3180     OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3181     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3182     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3183     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3184
3185     g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3186 }
3187
3188 JNIEXPORT void JNICALL
3189 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3190                                                                   jobject callback)
3191 {
3192     OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3193     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3194     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3195     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3196
3197     g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3198 }
3199
3200 JNIEXPORT void JNICALL
3201 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3202                                                           jobject device)
3203 {
3204     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3205     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3206     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3207
3208     CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3209     if (CA_STATUS_OK != res)
3210     {
3211         OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3212     }
3213 }
3214
3215 /*
3216  * Class:     org_iotivity_ca_jar_caleinterface
3217  * Method:    CALeGattConnectionStateChangeCallback
3218  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3219  */
3220 JNIEXPORT void JNICALL
3221 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3222                                                                                 jobject obj,
3223                                                                                 jobject gatt,
3224                                                                                 jint status,
3225                                                                                 jint newstate)
3226 {
3227     OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3228             newstate);
3229     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3230     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3231     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3232
3233     if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3234     {
3235         jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3236         if (!jni_address)
3237         {
3238             goto error_exit;
3239         }
3240
3241         const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3242         if (address)
3243         {
3244             CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3245                                                          STATE_CHARACTER_NO_CHANGE,
3246                                                          STATE_SEND_NONE);
3247             if (CA_STATUS_OK != res)
3248             {
3249                 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3250                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3251                 goto error_exit;
3252             }
3253             (*env)->ReleaseStringUTFChars(env, jni_address, address);
3254         }
3255
3256         CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3257         if (CA_STATUS_OK != res)
3258         {
3259             OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3260             goto error_exit;
3261         }
3262
3263         res = CALEClientDiscoverServices(env, gatt);
3264         if (CA_STATUS_OK != res)
3265         {
3266             OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3267             goto error_exit;
3268         }
3269     }
3270     else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
3271     {
3272         CAResult_t res = CALEClientStartScan();
3273         if (CA_STATUS_OK != res)
3274         {
3275             OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3276         }
3277
3278         jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3279         if (!jni_address)
3280         {
3281             OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3282         }
3283
3284         const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3285         if (address)
3286         {
3287             res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3288                                               STATE_CHARACTER_NO_CHANGE,
3289                                               STATE_SEND_NONE);
3290             if (CA_STATUS_OK != res)
3291             {
3292                 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3293             }
3294             (*env)->ReleaseStringUTFChars(env, jni_address, address);
3295         }
3296
3297         res = CALEClientGattClose(env, gatt);
3298         if (CA_STATUS_OK != res)
3299         {
3300             OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3301         }
3302     }
3303     else // error
3304     {
3305         // update state
3306         jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3307         if (!jni_address)
3308         {
3309             OIC_LOG(ERROR, TAG, "jni_address is null");
3310             goto error_exit;
3311
3312         }
3313
3314         const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3315         if (address)
3316         {
3317             CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3318                                                          STATE_CHARACTER_NO_CHANGE,
3319                                                          STATE_SEND_FAILED);
3320             if (CA_STATUS_OK != res)
3321             {
3322                 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3323             }
3324         }
3325         (*env)->ReleaseStringUTFChars(env, jni_address, address);
3326
3327         CAResult_t res = CALEClientGattClose(env, gatt);
3328         if (CA_STATUS_OK != res)
3329         {
3330             OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3331         }
3332
3333         goto error_exit;
3334     }
3335     return;
3336
3337     // error label.
3338 error_exit:
3339
3340     CALEClientSendFinish(env, gatt);
3341     return;
3342 }
3343
3344 /*
3345  * Class:     org_iotivity_ca_jar_caleinterface
3346  * Method:    CALeGattServicesDiscoveredCallback
3347  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3348  */
3349 JNIEXPORT void JNICALL
3350 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3351                                                                              jobject obj,
3352                                                                              jobject gatt,
3353                                                                              jint status)
3354 {
3355     OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3356     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3357     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3358     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3359
3360     if (0 != status) // discovery error
3361     {
3362         CALEClientSendFinish(env, gatt);
3363         return;
3364     }
3365
3366     jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3367     if (!jni_address)
3368     {
3369         CALEClientSendFinish(env, gatt);
3370         return;
3371     }
3372
3373     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3374     if (!address)
3375     {
3376         CALEClientSendFinish(env, gatt);
3377         return;
3378     }
3379
3380     if (!CALEClientIsSetCharacteristic(address))
3381     {
3382         jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3383         if (!jni_uuid)
3384         {
3385             OIC_LOG(ERROR, TAG, "jni_uuid is null");
3386             goto error_exit;
3387         }
3388
3389         jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3390         if (!jni_obj_GattCharacteristic)
3391         {
3392             OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3393             goto error_exit;
3394         }
3395
3396         CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3397                                                                  jni_obj_GattCharacteristic);
3398         if (CA_STATUS_OK != res)
3399         {
3400             OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3401             goto error_exit;
3402         }
3403
3404         res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3405         if (CA_STATUS_OK != res)
3406         {
3407             OIC_LOG(INFO, TAG, "Descriptor of the uuid is not found");
3408             CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3409             if (CA_STATUS_OK != res)
3410             {
3411                 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3412                 goto error_exit;
3413             }
3414         }
3415
3416         res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3417                                           STATE_SEND_NONE);
3418         if (CA_STATUS_OK != res)
3419         {
3420             OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3421             goto error_exit;
3422         }
3423     }
3424     else
3425     {
3426         CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3427         if (CA_STATUS_OK != res)
3428         {
3429             OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3430             goto error_exit;
3431         }
3432     }
3433     (*env)->ReleaseStringUTFChars(env, jni_address, address);
3434     return;
3435
3436     // error label.
3437 error_exit:
3438     (*env)->ReleaseStringUTFChars(env, jni_address, address);
3439     CALEClientSendFinish(env, gatt);
3440     return;
3441 }
3442
3443 /*
3444  * Class:     org_iotivity_ca_jar_caleinterface
3445  * Method:    CALeGattCharacteristicWritjclasseCallback
3446  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3447  */
3448 JNIEXPORT void JNICALL
3449 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3450         JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3451         jint status)
3452 {
3453     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3454     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3455     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3456     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3457
3458     jboolean isCopy;
3459     char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3460
3461     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3462
3463     // send success & signal
3464     jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3465     if (!jni_address)
3466     {
3467         goto error_exit;
3468     }
3469
3470     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3471     if (!address)
3472     {
3473         goto error_exit;
3474     }
3475
3476     if (GATT_SUCCESS != status) // error case
3477     {
3478         OIC_LOG(ERROR, TAG, "send failure");
3479         CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3480                                                      STATE_SEND_FAILED);
3481         if (CA_STATUS_OK != res)
3482         {
3483             OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3484         }
3485         CALEClientSendFinish(env, gatt);
3486     }
3487     else
3488     {
3489         OIC_LOG(DEBUG, TAG, "send success");
3490         CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3491                                                      STATE_SEND_SUCCESS);
3492         if (CA_STATUS_OK != res)
3493         {
3494             OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3495         }
3496         CALEClientUpdateSendCnt(env);
3497     }
3498
3499     (*env)->ReleaseStringUTFChars(env, jni_address, address);
3500     return;
3501
3502     // error label.
3503 error_exit:
3504
3505     CALEClientSendFinish(env, gatt);
3506     return;
3507 }
3508
3509 /*
3510  * Class:     org_iotivity_ca_jar_caleinterface
3511  * Method:    CALeGattCharacteristicChangedCallback
3512  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3513  */
3514 JNIEXPORT void JNICALL
3515 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3516         JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3517 {
3518     OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3519     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3520     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3521     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3522     VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3523
3524     // get Byte Array and covert to char*
3525     jint length = (*env)->GetArrayLength(env, data);
3526
3527     jboolean isCopy;
3528     jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3529
3530     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %s",
3531             jni_byte_responseData);
3532
3533     char* receivedData = (char*) OICMalloc(sizeof(char) * length + 1);
3534     if (!receivedData)
3535     {
3536         OIC_LOG(ERROR, TAG, "recevicedData is null");
3537         return;
3538     }
3539
3540     memcpy(receivedData, (const char*) jni_byte_responseData, length);
3541     receivedData[length] = '\0';
3542     (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3543
3544     jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3545     if (!jni_address)
3546     {
3547         OIC_LOG(ERROR, TAG, "jni_address is null");
3548         OICFree(receivedData);
3549         return;
3550     }
3551
3552     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3553     if (!address)
3554     {
3555         OIC_LOG(ERROR, TAG, "address is null");
3556         OICFree(receivedData);
3557         return;
3558     }
3559
3560     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %s, %d",
3561               receivedData, length);
3562
3563     ca_mutex_lock(g_bleServerBDAddressMutex);
3564     uint32_t sentLength = 0;
3565     g_CABLEClientDataReceivedCallback(address, receivedData, length,
3566                                       &sentLength);
3567     ca_mutex_unlock(g_bleServerBDAddressMutex);
3568
3569     (*env)->ReleaseStringUTFChars(env, jni_address, address);
3570 }
3571
3572 /*
3573  * Class:     org_iotivity_ca_jar_caleinterface
3574  * Method:    CALeGattDescriptorWriteCallback
3575  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3576  */
3577 JNIEXPORT void JNICALL
3578 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3579                                                                          jobject gatt,
3580                                                                          jint status)
3581 {
3582     OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3583     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3584     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3585     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3586
3587     CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3588     if (CA_STATUS_OK != res)
3589     {
3590         OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3591         goto error_exit;
3592     }
3593     return;
3594
3595 // error label.
3596 error_exit:
3597
3598     CALEClientSendFinish(env, gatt);
3599     return;
3600 }