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