Imported Upstream version 1.1.1
[platform/upstream/iotivity.git] / resource / csdk / connectivity / util / src / camanager / android / caleconnectionmanager.c
1 /* ****************************************************************
2  *
3  * Copyright 2016 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 <jni.h>
22 #include "logger.h"
23 #include "cautilinterface.h"
24 #include "camanagerleinterface.h"
25 #include "camanagerleutil.h"
26 #include "caleautoconnector.h"
27 #include "cacommon.h"
28 #include "cacommonutil.h"
29 #include "camanagerdevice.h"
30 #include "caleclient.h"
31 #include "caleutils.h"
32
33 #define TAG "OIC_CA_MANAGER_LE"
34
35 static const jint SUPPORT_ADNROID_API_LEVEL = 18;
36 static const jint AUTH_FAIL = 5;
37 static const jint LINK_LOSS = 8;
38 static const jint ACCEPT_TIMEOUT_EXCEPTION = 16;
39 static const jint REMOTE_DISCONNECT = 19;
40 static const jint LOCAL_DISCONNECT = 22;
41 static const jint CONNECTION_FAILED_TO_BE_EASTABLISHED = 62;
42 static const jint USER_REMOVED_BOND = 68;
43 static JavaVM *g_jvm = NULL;
44 static jobject g_context = NULL;
45 static jobject g_connectedDeviceSet = NULL;
46
47
48 CAResult_t CASetLEClientAutoConnectionDeviceInfo(const char* address)
49 {
50     OIC_LOG(DEBUG, TAG, "CASetClientAutoConnectionDeviceInfo");
51     VERIFY_NON_NULL(address, TAG, "address");
52
53     bool isAttached = false;
54     JNIEnv* env;
55     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
56     if (JNI_OK != res)
57     {
58         OIC_LOG(DEBUG, TAG, "AttachCurrentThread will be called for JNIEnv pointer");
59         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
60
61         if (JNI_OK != res)
62         {
63             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
64             return CA_STATUS_FAILED;
65         }
66         isAttached = true;
67     }
68
69     OIC_LOG_V(DEBUG, TAG, "set [%s] for Auto Connection", address);
70     jstring jni_leAddress = (*env)->NewStringUTF(env, address);
71
72     if (!CAManagerCheckBTAddress(env, jni_leAddress))
73     {
74         OIC_LOG(ERROR, TAG, "this address is not BT address string format");
75         if (isAttached)
76         {
77             (*g_jvm)->DetachCurrentThread(g_jvm);
78         }
79         return CA_STATUS_FAILED;
80     }
81
82     // if there is target address in SharedPreference. it will be reseted.
83     if (CAManagerIsConnectedDeviceAddress(env, g_context,
84                                           jni_leAddress,
85                                           g_connectedDeviceSet))
86     {
87         if (!CAManagerRemoveConnectedDeviceAddress(env, g_context,
88                                                    jni_leAddress,
89                                                    g_connectedDeviceSet))
90         {
91             OIC_LOG(ERROR, TAG, "Preference - remove has failed");
92         }
93         else
94         {
95             OIC_LOG(INFO, TAG, "Preference - remove success");
96         }
97     }
98
99     // it will be added new target address.
100     if (!CAManagerAddConnectedDeviceAddress(env, g_context,
101                                             jni_leAddress, g_connectedDeviceSet))
102     {
103         OIC_LOG(ERROR, TAG, "Preference - putting has failed");
104     }
105     else
106     {
107         OIC_LOG(INFO, TAG, "Preference - putting success");
108     }
109
110     if (isAttached)
111     {
112         (*g_jvm)->DetachCurrentThread(g_jvm);
113     }
114
115     return CA_STATUS_OK;
116 }
117
118 CAResult_t CAUnsetLEClientAutoConnectionDeviceInfo(const char* address)
119 {
120     OIC_LOG(DEBUG, TAG, "CAUnsetClientAutoConnectionDeviceInfo");
121     VERIFY_NON_NULL(address, TAG, "address");
122
123     bool isAttached = false;
124     JNIEnv* env;
125     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
126     if (JNI_OK != res)
127     {
128         OIC_LOG(DEBUG, TAG, "AttachCurrentThread will be called for JNIEnv pointer");
129         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
130
131         if (JNI_OK != res)
132         {
133             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
134             return CA_STATUS_FAILED;
135         }
136         isAttached = true;
137     }
138
139     OIC_LOG_V(DEBUG, TAG, "unset [%s] for Auto Connection", address);
140     jstring jni_leAddress = (*env)->NewStringUTF(env, address);
141
142     if (!CAManagerCheckBTAddress(env, jni_leAddress))
143     {
144         OIC_LOG(ERROR, TAG, "this address is not BT address string format");
145         if (isAttached)
146         {
147             (*g_jvm)->DetachCurrentThread(g_jvm);
148         }
149         return CA_STATUS_FAILED;
150     }
151
152     // if there is target address in SharedPreference. it would be removed
153     if (CAManagerIsConnectedDeviceAddress(env, g_context,
154                                           jni_leAddress,
155                                           g_connectedDeviceSet))
156     {
157         if (!CAManagerRemoveConnectedDeviceAddress(env, g_context,
158                                                    jni_leAddress,
159                                                    g_connectedDeviceSet))
160         {
161             OIC_LOG(ERROR, TAG, "Preference - remove has failed");
162         }
163         else
164         {
165             OIC_LOG(INFO, TAG, "Preference - remove success");
166         }
167     }
168
169     // remove target device for auto connection
170     CAResult_t ret = CAManagerRemoveData(env, jni_leAddress);
171     if (CA_STATUS_OK != ret)
172     {
173         OIC_LOG(ERROR, TAG, "CAManagerRemoveData has failed");
174     }
175
176     if (isAttached)
177     {
178         (*g_jvm)->DetachCurrentThread(g_jvm);
179     }
180
181     return CA_STATUS_OK;
182 }
183
184 CAResult_t CAManagerLEClientInitialize(JNIEnv *env, JavaVM *jvm, jobject context)
185 {
186     OIC_LOG(DEBUG, TAG, "CAManagerClientInitialize");
187     VERIFY_NON_NULL(env, TAG, "env");
188     VERIFY_NON_NULL(jvm, TAG, "jvm");
189     VERIFY_NON_NULL(context, TAG, "context");
190
191     jint jni_int_sdk = CALEGetBuildVersion(env);
192     if (jni_int_sdk < SUPPORT_ADNROID_API_LEVEL)
193     {
194         OIC_LOG_V(ERROR, TAG, "it is not supported (%d)", jni_int_sdk);
195         return CA_STATUS_FAILED;
196     }
197
198     g_jvm = jvm;
199     g_context = (*env)->NewGlobalRef(env, context);;
200     CAManagerInitMutexVaraibles();
201     CAManagerInitLEAutoConnection();
202
203     CAManagerCreateACDataList(env);
204
205     // get last connected device list
206     jobject set = NULL;
207     set = CAManagerGetConnectedDeviceAddress(env, g_context);
208     if (!set)
209     {
210         // create new set<String> object
211         set = CAManagerCreateSetString(env);
212         if (set)
213         {
214             OIC_LOG(DEBUG, TAG, "created new SetString");
215         }
216         else
217         {
218             OIC_LOG(ERROR, TAG, "CAManagerCreateSetString has failed");
219             return CA_STATUS_FAILED;
220         }
221     }
222     else
223     {
224         OIC_LOG(DEBUG, TAG, "get previous Set<String> object");
225     }
226
227     g_connectedDeviceSet = (jobject)(*env)->NewGlobalRef(env, set);
228     if (!g_connectedDeviceSet)
229     {
230         OIC_LOG(ERROR, TAG, "g_connectedDeviceSet is null");
231         return CA_STATUS_FAILED;
232     }
233
234     return CA_STATUS_OK;
235 }
236
237 CAResult_t CAManagerLEClientTerminate(JNIEnv *env)
238 {
239     OIC_LOG(DEBUG, TAG, "CAManagerClientTerminate");
240     VERIFY_NON_NULL(env, TAG, "env");
241
242     // stop gatt connection
243     CAResult_t res = CALEClientDisconnectAll(env);
244     if (CA_STATUS_OK != res)
245     {
246         OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
247     }
248
249     res = CAManagerRemoveAllData(env);
250     if (CA_STATUS_OK != res)
251     {
252         OIC_LOG(ERROR, TAG, "CAManagerRemoveAllData has failed");
253     }
254
255     CAManagerTerminateLEAutoConnection();
256     CAManagerTerminateMutexVariables();
257
258     if (g_context)
259     {
260         (*env)->DeleteGlobalRef(env, g_context);
261         g_context = NULL;
262     }
263
264     if (g_connectedDeviceSet)
265     {
266         (*env)->DeleteGlobalRef(env, g_connectedDeviceSet);
267         g_connectedDeviceSet = NULL;
268     }
269
270     return res;
271 }
272
273 JNIEXPORT void JNICALL
274 Java_org_iotivity_ca_CaLeClientInterface_caManagerAdapterStateChangedCallback(
275         JNIEnv *env, jobject obj, jint state)
276 {
277     OIC_LOG(DEBUG, TAG, "caManagerAdapterStateChangedCallback");
278     VERIFY_NON_NULL_VOID(env, TAG, "env");
279     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
280
281     jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
282     jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
283     jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");
284
285     if (state_on == state)
286     {
287         OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_on");
288
289         // when BT state is on. recovery flag has to be reset.
290         CAManagerSetBTRecovery(false);
291
292         // find target device for autoconnect
293         size_t length = CAManagerGetACDataLength();
294         OIC_LOG_V(DEBUG, TAG, "target device : %d", length);
295         for (size_t idx = 0; idx < length; idx++)
296         {
297             jstring leAddress = CAManagerGetLEAddressFromACData(env, idx);
298             if (leAddress)
299             {
300                 CAResult_t res = CAManagerStartAutoConnection(env, leAddress);
301                 if (CA_STATUS_OK != res)
302                 {
303                     OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed");
304                     return;
305                 }
306             }
307         }
308     }
309     else if (state_off == state)
310     {
311         OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_off");
312
313         // reset autoconnect flag for all target devices
314         size_t length = CAManagerGetACDataLength();
315         for (size_t idx = 0; idx < length; idx++)
316         {
317             jstring address = CAManagerGetLEAddressFromACData(env, idx);
318             if (address)
319             {
320                 CAManagerSetAutoConnectionFlag(env, address, false);
321             }
322         }
323
324         // check whether BT recovery is needed or not
325         if (CAManagerIsRecoveryFlagSet())
326         {
327             CAManagerProcessRecovery(env, STATE_OFF);
328         }
329     }
330     else if (state_turning_off == state)
331     {
332         OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_turning_off");
333         return;
334     }
335     else
336     {
337         OIC_LOG(INFO, TAG, "AdapterStateChangedCallback state is not available");
338         return;
339     }
340 }
341
342 JNIEXPORT void JNICALL
343 Java_org_iotivity_ca_CaLeClientInterface_caManagerBondStateChangedCallback(
344         JNIEnv *env, jobject obj, jobject device)
345 {
346     OIC_LOG(DEBUG, TAG, "caManagerBondStateChangedCallback");
347     VERIFY_NON_NULL_VOID(env, TAG, "env");
348     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
349     VERIFY_NON_NULL_VOID(device, TAG, "device");
350
351     // get ble address from Bluetooth Device object
352     jstring jni_leAddress = CALEClientGetLEAddressFromBTDevice(env, device);
353     if (!jni_leAddress)
354     {
355         OIC_LOG(INFO, TAG, "unbonded : it isn't same device type");
356         return;
357     }
358
359     char* leAddress = (char*)(*env)->GetStringUTFChars(env, jni_leAddress, NULL);
360     if (!leAddress)
361     {
362         OIC_LOG(ERROR, TAG, "leAddress is null");
363         return;
364     }
365
366     // if there is no data, CAData will be created.
367     OIC_LOG_V(DEBUG, TAG, "bond none device : %s", leAddress);
368
369     CAResult_t res = CAManagerRemoveData(env, jni_leAddress);
370     if (CA_STATUS_OK != res)
371     {
372         OIC_LOG(ERROR, TAG, "CAManagerRemoveData has failed");
373     }
374
375     (*env)->ReleaseStringUTFChars(env, jni_leAddress, leAddress);
376
377     if (!CAManagerRemoveConnectedDeviceAddress(env, g_context,
378                                                jni_leAddress,
379                                                g_connectedDeviceSet))
380     {
381         OIC_LOG(ERROR, TAG, "CAManagerRemoveConnectedDeviceAddress has failed");
382     }
383
384     OIC_LOG(INFO, TAG, "bonded state changed bone_none");
385 }
386
387 JNIEXPORT void JNICALL
388 Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB(
389         JNIEnv *env, jobject obj, jobject gatt, jint status, jint newState)
390 {
391     OIC_LOG_V(DEBUG, TAG, "caManagerLeGattConnectionStateChangeCB-status(%d), newState(%d)",
392               status, newState);
393
394     VERIFY_NON_NULL_VOID(env, TAG, "env");
395     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
396     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
397
398     jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
399     jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
400     jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
401
402     jstring jni_address = CAManagerGetAddressFromGatt(env, gatt);
403     if (!jni_address)
404     {
405         OIC_LOG(ERROR, TAG, "CAManagerGetAddressFromGatt is null");
406         return;
407     }
408
409     char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
410     if (!address)
411     {
412         OIC_LOG(ERROR, TAG, "address is null");
413         return;
414     }
415
416     OIC_LOG_V(INFO, TAG, "connection state : status(%d), addr:(%s), newState(%d)",
417               status, address, newState);
418
419     if (gatt_success == status && state_connected == newState) // le connected
420     {
421         OIC_LOG(DEBUG, TAG, "LE is connected");
422         CAResult_t res = CAManagerReadRemoteRssi(env, gatt);
423         if (CA_STATUS_OK != res)
424         {
425             OIC_LOG(ERROR, TAG, "CAManagerReadRemoteRssi has failed");
426             (*env)->ReleaseStringUTFChars(env, jni_address, address);
427             return;
428         }
429     }
430     else if (state_disconnected == newState)// le disconnected
431     {
432         if (LINK_LOSS == status || REMOTE_DISCONNECT == status)
433         {
434             OIC_LOG(DEBUG, TAG, "LE is disconnected");
435
436             if (!CAManagerIsMatchedACData(env, jni_address))
437             {
438                 OIC_LOG_V(DEBUG, TAG, "this[%s] is not target address for Auto Connection",
439                           address);
440                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
441                 return;
442             }
443
444             CAManagerSetAutoConnectionFlag(env, jni_address, false);
445
446             CAResult_t res = CAManagerStartAutoConnection(env, jni_address);
447             if (CA_STATUS_OK != res)
448             {
449                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
450                 OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed");
451                 return;
452             }
453         }
454         else if (ACCEPT_TIMEOUT_EXCEPTION == status)
455         {
456             CAManagerProcessRecovery(env, START_RECOVERY);
457         }
458     }
459     (*env)->ReleaseStringUTFChars(env, jni_address, address);
460     (*env)->DeleteLocalRef(env, jni_address);
461 }
462
463 /*
464  * Class:     org_iotivity_ca_jar_caleinterface
465  * Method:    caManagerLeServicesDiscoveredCallback
466  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
467  */
468 JNIEXPORT void JNICALL
469 Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback(JNIEnv *env,
470                                                                                jobject obj,
471                                                                                jobject gatt,
472                                                                                jint status)
473 {
474     OIC_LOG_V(DEBUG, TAG, "caManagerLeServicesDiscoveredCallback - status %d: ", status);
475     VERIFY_NON_NULL_VOID(env, TAG, "env");
476     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
477     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
478
479     if (GATT_SUCCESS == status)
480     {
481         if (!g_connectedDeviceSet)
482         {
483             OIC_LOG(ERROR, TAG, "g_connectedDeviceSet is null");
484             return;
485         }
486
487         jstring jni_address = CAManagerGetAddressFromGatt(env, gatt);
488         if (!jni_address)
489         {
490             OIC_LOG(ERROR, TAG, "CAManagerGetAddressFromGatt is null");
491             return;
492         }
493
494         char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
495         if (!address)
496         {
497             OIC_LOG(ERROR, TAG, "address is null");
498             (*env)->DeleteLocalRef(env, jni_address);
499             return;
500         }
501         OIC_LOG_V(DEBUG, TAG, "ServicesDiscovered device : %s", address);
502
503         // target address for auto connection will be set in device list.
504         // check set connected address information by user
505         jclass jni_cls_set = (*env)->FindClass(env, "java/util/HashSet");
506         if (!jni_cls_set)
507         {
508             OIC_LOG(ERROR, TAG, "jni_cls_set is null");
509             (*env)->ReleaseStringUTFChars(env, jni_address, address);
510             (*env)->DeleteLocalRef(env, jni_address);
511             return;
512         }
513
514         jmethodID jni_mid_iterator = (*env)->GetMethodID(env, jni_cls_set, "iterator",
515                                                             "()Ljava/util/Iterator;");
516         if (!jni_mid_iterator)
517         {
518             OIC_LOG(ERROR, TAG, "jni_mid_iterator is null");
519             (*env)->DeleteLocalRef(env, jni_cls_set);
520             (*env)->ReleaseStringUTFChars(env, jni_address, address);
521             (*env)->DeleteLocalRef(env, jni_address);
522             return;
523         }
524
525         jobject jni_obj_iter = (*env)->CallObjectMethod(env, g_connectedDeviceSet, jni_mid_iterator);
526         if (!jni_obj_iter)
527         {
528             OIC_LOG(ERROR, TAG, "jni_obj_iter is null");
529             (*env)->DeleteLocalRef(env, jni_cls_set);
530             (*env)->ReleaseStringUTFChars(env, jni_address, address);
531             (*env)->DeleteLocalRef(env, jni_address);
532             return;
533         }
534
535         // Get the Iterator method IDs
536         jclass jni_cls_iterator = (*env)->FindClass(env, "java/util/Iterator");
537         if (!jni_cls_iterator)
538         {
539             OIC_LOG(ERROR, TAG, "jni_cls_iterator is null");
540             (*env)->DeleteLocalRef(env, jni_obj_iter);
541             (*env)->DeleteLocalRef(env, jni_cls_set);
542             (*env)->ReleaseStringUTFChars(env, jni_address, address);
543             (*env)->DeleteLocalRef(env, jni_address);
544             return;
545         }
546
547         jmethodID jni_mid_hasNext = (*env)->GetMethodID(env, jni_cls_iterator, "hasNext", "()Z");
548         if (!jni_mid_hasNext)
549         {
550             OIC_LOG(ERROR, TAG, "jni_mid_hasNext is null");
551             (*env)->DeleteLocalRef(env, jni_cls_iterator);
552             (*env)->DeleteLocalRef(env, jni_obj_iter);
553             (*env)->DeleteLocalRef(env, jni_cls_set);
554             (*env)->ReleaseStringUTFChars(env, jni_address, address);
555             (*env)->DeleteLocalRef(env, jni_address);
556             return;
557         }
558
559         jmethodID jni_mid_next = (*env)->GetMethodID(env, jni_cls_iterator, "next",
560                                                         "()Ljava/lang/Object;");
561         if (!jni_mid_next)
562         {
563             OIC_LOG(ERROR, TAG, "jni_mid_next is null");
564             (*env)->DeleteLocalRef(env, jni_cls_iterator);
565             (*env)->DeleteLocalRef(env, jni_obj_iter);
566             (*env)->DeleteLocalRef(env, jni_cls_set);
567             (*env)->ReleaseStringUTFChars(env, jni_address, address);
568             (*env)->DeleteLocalRef(env, jni_address);
569             return;
570         }
571
572         // Iterate over the entry Set
573         while ((*env)->CallBooleanMethod(env, jni_obj_iter, jni_mid_hasNext))
574         {
575             jstring jni_str_entry = (jstring)(*env)->CallObjectMethod(env, jni_obj_iter,
576                                                                         jni_mid_next);
577             if (!jni_str_entry)
578             {
579                 OIC_LOG(ERROR, TAG, "jni_str_entry is null");
580                 (*env)->DeleteLocalRef(env, jni_cls_iterator);
581                 (*env)->DeleteLocalRef(env, jni_obj_iter);
582                 (*env)->DeleteLocalRef(env, jni_cls_set);
583                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
584                 (*env)->DeleteLocalRef(env, jni_address);
585                 return;
586             }
587             const char* foundAddress = (*env)->GetStringUTFChars(env, jni_str_entry, NULL);
588             if (!foundAddress)
589             {
590                 OIC_LOG(ERROR, TAG, "addr is null");
591                 (*env)->DeleteLocalRef(env, jni_str_entry);
592                 (*env)->DeleteLocalRef(env, jni_cls_iterator);
593                 (*env)->DeleteLocalRef(env, jni_obj_iter);
594                 (*env)->DeleteLocalRef(env, jni_cls_set);
595                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
596                 (*env)->DeleteLocalRef(env, jni_address);
597                 return;
598             }
599             OIC_LOG_V(INFO, TAG, "found last connected address [%s] from SharedPreferences",
600                       foundAddress);
601
602             if (!strcmp(foundAddress, address))
603             {
604                 // if BLE address is matched each other
605                 // this address will be added into auto connection list.
606                 OIC_LOG(INFO, TAG, "AC list - address will be added into ACData list");
607                 CAManagerAddACData(env, jni_address);
608                 CAManagerSetAutoConnectionFlag(env, jni_address, false);
609
610                 // next connection will be requested as JNI_TRUE flag
611                 // after first connection
612                 CALEClientSetFlagToState(env, jni_str_entry, CA_LE_AUTO_CONNECT_FLAG, JNI_TRUE);
613             }
614             else
615             {
616                 OIC_LOG(INFO, TAG, "AC list - device is not matched");
617             }
618
619             (*env)->ReleaseStringUTFChars(env, jni_str_entry, foundAddress);
620             (*env)->DeleteLocalRef(env, jni_str_entry);
621         }
622
623         (*env)->DeleteLocalRef(env, jni_cls_iterator);
624         (*env)->DeleteLocalRef(env, jni_obj_iter);
625         (*env)->DeleteLocalRef(env, jni_cls_set);
626         (*env)->ReleaseStringUTFChars(env, jni_address, address);
627         (*env)->DeleteLocalRef(env, jni_address);
628         OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
629     }
630     else
631     {
632         OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
633     }
634 }
635
636 /*
637  * Class:     org_iotivity_ca_jar_caleinterface
638  * Method:    caManagerLeRemoteRssiCallback
639  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
640  */
641 JNIEXPORT void JNICALL
642 Java_org_iotivity_ca_CaLeClientInterface_caManagerLeRemoteRssiCallback(JNIEnv *env,
643                                                                        jobject obj,
644                                                                        jobject gatt,
645                                                                        jint rssi,
646                                                                        jint status)
647 {
648     OIC_LOG_V(DEBUG, TAG, "caManagerLeRemoteRssiCallback - rssi : %d: ", rssi);
649     OIC_LOG_V(DEBUG, TAG, "caManagerLeRemoteRssiCallback - status : %d: ", status);
650     VERIFY_NON_NULL_VOID(env, TAG, "env");
651     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
652     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
653 }