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