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