To add connection manager for client for android BLE.
authorjihwan.seo <jihwan.seo@samsung.com>
Fri, 19 Feb 2016 03:03:33 +0000 (12:03 +0900)
committerJon A. Cruz <jonc@osg.samsung.com>
Wed, 2 Mar 2016 09:14:40 +0000 (09:14 +0000)
Change-Id: I54557c69c58d4f3dd4a1434d492d40c1d25a5ffa
Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/5061
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jonc@osg.samsung.com>
13 files changed:
android/android_api/base/jni/JniCaInterface.c
android/android_api/base/src/main/java/org/iotivity/ca/CaLeClientInterface.java
resource/csdk/connectivity/src/bt_le_adapter/android/calenwmonitor.c
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeClientInterface.h
resource/csdk/connectivity/util/SConscript
resource/csdk/connectivity/util/src/camanager/android/caleautoconnector.c [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/android/caleautoconnector.h [new file with mode: 0644]
resource/csdk/connectivity/util/src/camanager/android/caleconnectionmanager.c
resource/csdk/connectivity/util/src/camanager/android/camanagerdevice.c [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/android/camanagerdevice.h [new file with mode: 0644]
resource/csdk/connectivity/util/src/camanager/android/camanagerleutil.c [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/android/camanagerleutil.h [new file with mode: 0644]
resource/csdk/connectivity/util/src/cautilinterface.c

index 6819f9d..3cb4019 100644 (file)
@@ -222,6 +222,8 @@ Java_org_iotivity_ca_CaInterface_caManagerInitialize(JNIEnv *env, jclass clazz,
 
     g_listenerObject = (*env)->NewGlobalRef(env, listener);
 
+    CAUtilClientInitialize(env, g_jvm, context);
+
     CARegisterNetworkMonitorHandler(CAManagerAdapterStateChangedCB,
                                     CAManagerConnectionStateChangedCB);
 }
index 3b43b57..5d0d90b 100644 (file)
@@ -82,6 +82,10 @@ public class CaLeClientInterface {
     private native static void caLeGattConnectionStateChangeCallback(
             BluetoothGatt gatt, int status, int newState);
 
+    // BluetoothGattCallback for Connection Manager
+    private native static void caManagerLeGattConnectionStateChangeCB(
+            BluetoothGatt gatt, int status, int newState);
+
     private native static void caLeGattServicesDiscoveredCallback(BluetoothGatt gatt, int status);
 
     private native static void caLeGattCharacteristicWriteCallback(
@@ -102,7 +106,19 @@ public class CaLeClientInterface {
     private native static void caLeStateChangedCallback(int state);
 
     // bond state
-    private native static void caLeBondStateChangedCallback(String address, boolean connected);
+    private native static void caLeBondStateChangedCallback(String address);
+
+    // adapter state
+    private native static void caManagerAdapterStateChangedCallback(int state);
+
+    // bond state
+    private native static void caManagerBondStateChangedCallback(BluetoothDevice address);
+
+    private native static void caManagerLeServicesDiscoveredCallback(BluetoothGatt gatt,
+                                                                     int status);
+
+    private native static void caManagerLeRemoteRssiCallback(BluetoothGatt gatt, int rssi,
+                                                             int status);
 
     // Callback
     private static BluetoothAdapter.LeScanCallback mLeScanCallback =
@@ -117,6 +133,7 @@ public class CaLeClientInterface {
                     Log.d(TAG, "UUID : " + uuid.toString());
                     if(uuid.toString().contains(SERVICE_UUID.toLowerCase())) {
                         Log.d(TAG, "we found that has the Device");
+                        Log.d(TAG, "scanned device address : " + device.getAddress());
                         caLeScanCallback(device);
                     }
                 }
@@ -181,6 +198,7 @@ public class CaLeClientInterface {
             super.onConnectionStateChange(gatt, status, newState);
 
             caLeGattConnectionStateChangeCallback(gatt, status, newState);
+            caManagerLeGattConnectionStateChangeCB(gatt, status, newState);
         }
 
         @Override
@@ -188,6 +206,7 @@ public class CaLeClientInterface {
             super.onServicesDiscovered(gatt, status);
 
             caLeGattServicesDiscoveredCallback(gatt, status);
+            caManagerLeServicesDiscoveredCallback(gatt, status);
         }
 
         @Override
@@ -234,6 +253,7 @@ public class CaLeClientInterface {
         @Override
         public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
             super.onReadRemoteRssi(gatt, rssi, status);
+            caManagerLeRemoteRssiCallback(gatt, rssi, status);
         }
     };
 
@@ -249,9 +269,11 @@ public class CaLeClientInterface {
                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                                BluetoothAdapter.ERROR);
 
-                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF)
+                if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF
+                        || state == BluetoothAdapter.STATE_TURNING_OFF)
                 {
                     caLeStateChangedCallback(state);
+                    caManagerAdapterStateChangedCallback(state);
                 }
             }
 
@@ -266,7 +288,8 @@ public class CaLeClientInterface {
                             BluetoothDevice device = intent
                                 .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
 
-                        caLeBondStateChangedCallback(device.getAddress(), false);
+                        caManagerBondStateChangedCallback(device);
+                        caLeBondStateChangedCallback(device.getAddress());
                     }
                 }
             }
index 1b77c60..1fa93b8 100644 (file)
@@ -326,7 +326,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
 
 JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback(JNIEnv *env, jobject obj,
-                                                                       jstring jaddr, jboolean jconnected)
+                                                                      jstring jaddr)
 {
     OIC_LOG(DEBUG, TAG, "CaLeClientInterface - Bond State Changed");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
@@ -368,6 +368,4 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback(JNIEnv *en
         OIC_LOG(ERROR, TAG, "address is null");
         return;
     }
-
-    g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, (bool)jconnected);
 }
index 5fc2136..a39910b 100644 (file)
@@ -112,11 +112,56 @@ Java_org_iotivity_ca_caLeClientInterface_caLeStateChangedCallback
 /*
  * Class:     org_iotivity_ca_caLeClientInterface
  * Method:    caLeBondStateChangedCallback
- * Signature: (Ljava/lang/String;Z)V
+ * Signature: (Ljava/lang/String;)V
  */
 JNIEXPORT void JNICALL
 Java_org_iotivity_ca_caLeClientInterface_caLeBondStateChangedCallback
-(JNIEnv *, jobject, jstring, jboolean);
+(JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caManagerLeGattConnectionStateChangeCB
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB
+(JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caManagerAdapterStateChangedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerAdapterStateChangedCallback
+(JNIEnv *, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_caLeClientInterface
+ * Method:    caManagerBondStateChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerBondStateChangedCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_ca_jar_caleinterface
+ * Method:    caManagerLeServicesDiscoveredCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback
+(JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_ca_jar_caleinterface
+ * Method:    caManagerLeRemoteRssiCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerLeRemoteRssiCallback
+(JNIEnv *, jobject, jobject, jint, jint);
 
 #ifdef __cplusplus
 }
index dc8e341..33b6c12 100644 (file)
@@ -20,6 +20,9 @@ env.AppendUnique(CPPPATH = [ os.path.join(root_dir, 'inc'),
                              os.path.join(root_dir, 'common/inc'),
                              os.path.join(root_dir, 'util/inc') ])
 
+if ca_os == 'android':
+       env.AppendUnique(CPPPATH = [ os.path.join(root_dir, 'util/src/android') ])
+
 ######################################################################
 # Source files to build common for platforms
 ######################################################################
@@ -33,4 +36,7 @@ if (('BLE' in ca_transport) or ('ALL' in ca_transport)):
 
     if ca_os == 'android':
                env.AppendUnique(CA_SRC = [
-               os.path.join(src_dir,'camanager/android/caleconnectionmanager.c')])
\ No newline at end of file
+               os.path.join(src_dir,'camanager/android/caleconnectionmanager.c'),
+               os.path.join(src_dir,'camanager/android/caleautoconnector.c'),
+               os.path.join(src_dir,'camanager/android/camanagerleutil.c'),
+               os.path.join(src_dir,'camanager/android/camanagerdevice.c')])
\ No newline at end of file
diff --git a/resource/csdk/connectivity/util/src/camanager/android/caleautoconnector.c b/resource/csdk/connectivity/util/src/camanager/android/caleautoconnector.c
new file mode 100755 (executable)
index 0000000..76f439c
--- /dev/null
@@ -0,0 +1,237 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <jni.h>
+#include "cacommon.h"
+#include "caleclient.h"
+#include "camanagerleutil.h"
+#include "camanagerdevice.h"
+#include "caleautoconnector.h"
+#include "cacommonutil.h"
+#include "logger.h"
+#include "camutex.h"
+
+#define TAG "OIC_CA_LE_AUTO_CONN"
+
+static const size_t MAX_RETRY_COUNT = 5;
+static const size_t TIMEOUT = 1000000;
+static const size_t WAITING_TIME = 500000;
+
+static ca_mutex g_connectRetryMutex = NULL;
+static ca_cond g_connectRetryCond = NULL;
+
+static ca_mutex g_recoveryMutex = NULL;
+static ca_cond g_recoveryCond = NULL;
+
+CAResult_t CAManagerInitLEAutoConnection()
+{
+    if (NULL == g_connectRetryMutex)
+    {
+        g_connectRetryMutex = ca_mutex_new();
+        if (NULL == g_connectRetryMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_connectRetryCond)
+    {
+        g_connectRetryCond = ca_cond_new();
+        if (NULL == g_connectRetryCond)
+        {
+            OIC_LOG(ERROR, TAG, "ca_cond_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_recoveryMutex)
+    {
+        g_recoveryMutex = ca_mutex_new();
+        if (NULL == g_recoveryMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_recoveryCond)
+    {
+        g_recoveryCond = ca_cond_new();
+        if (NULL == g_recoveryCond)
+        {
+            OIC_LOG(ERROR, TAG, "ca_cond_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+void CAManagerTerminateLEAutoConnection()
+{
+    if (g_connectRetryCond)
+    {
+        ca_cond_signal(g_connectRetryCond);
+        ca_cond_free(g_connectRetryCond);
+        g_connectRetryCond = NULL;
+    }
+
+    if (g_connectRetryMutex)
+    {
+        ca_mutex_free(g_connectRetryMutex);
+        g_connectRetryMutex = NULL;
+    }
+
+    if (g_recoveryCond)
+    {
+        ca_cond_signal(g_recoveryCond);
+        ca_cond_free(g_recoveryCond);
+        g_recoveryCond = NULL;
+    }
+
+    if (g_recoveryMutex)
+    {
+        ca_mutex_free(g_recoveryMutex);
+        g_recoveryMutex = NULL;
+    }
+}
+
+CAResult_t CAManagerStartAutoConnection(JNIEnv *env, jstring remote_le_address)
+{
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(remote_le_address, TAG, "remote_le_address is null");
+
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerStartAutoConnection");
+
+    if (true == CAManagerGetAutoConnectionFlag(env, remote_le_address))
+    {
+        OIC_LOG(INFO, TAG, "auto connecting.");
+        return CA_STATUS_FAILED;
+    }
+
+    ca_mutex_lock(g_connectRetryMutex);
+
+    for (size_t retry_cnt = 0 ; retry_cnt < MAX_RETRY_COUNT ; retry_cnt++)
+    {
+        // there is retry logic 5 times when connectGatt call has failed
+        // because BT adapter might be not ready yet.
+        if (NULL == CAManagerConnectGatt(env, remote_le_address))
+        {
+            OIC_LOG_V(INFO, TAG, "retry will be started at least %d times after delay 1sec",
+                      MAX_RETRY_COUNT - retry_cnt - 1);
+            if (ca_cond_wait_for(g_connectRetryCond, g_connectRetryMutex, TIMEOUT) == 0)
+            {
+                OIC_LOG(INFO, TAG, "request to connect gatt was canceled");
+                ca_mutex_unlock(g_connectRetryMutex);
+                return CA_STATUS_OK;
+            }
+            // time out. retry connection
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "ConnectGatt has called successfully");
+            break;
+        }
+    }
+    ca_mutex_unlock(g_connectRetryMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerStartAutoConnection");
+    return CA_STATUS_OK;
+}
+
+jobject CAManagerConnectGatt(JNIEnv *env, jstring remote_le_address)
+{
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+    VERIFY_NON_NULL_RET(remote_le_address, TAG, "remote_le_address", NULL);
+
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerConnectGatt");
+
+    jobject jni_bluetooth = CAManagerGetRemoteDevice(env, remote_le_address);
+    if (!jni_bluetooth)
+    {
+        OIC_LOG(ERROR, TAG, "jni_bluetooth is null");
+        return NULL;
+    }
+
+    if (!CAManagerIsDeviceBonded(env, jni_bluetooth))
+    {
+        OIC_LOG(INFO, TAG, "device is BONDED_NONE");
+    }
+
+    // request to connection with AutoConnection Flag
+    OIC_LOG(INFO, TAG, "request to gatt connection for auto connection");
+    jobject newGatt = (jobject)CALEClientConnect(env, jni_bluetooth, JNI_TRUE);
+    if (NULL == newGatt)
+    {
+        OIC_LOG(INFO, TAG, "re-connection will be started");
+        return NULL;
+    }
+
+    // set flag auto connection is requested.
+    CAManagerSetAutoConnectionFlag(env, remote_le_address, true);
+
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerConnectGatt");
+    return newGatt;
+}
+
+CAResult_t CAManagerProcessRecovery(JNIEnv *env, uint16_t adapter_state)
+{
+    VERIFY_NON_NULL(env, TAG, "env");
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerProcessRecovery");
+
+    ca_mutex_lock(g_recoveryMutex);
+    CAResult_t res = CA_STATUS_OK;
+
+    switch(adapter_state)
+    {
+        case STATE_OFF:
+            // adapter will be enabled automatically after WAITING_TIME.
+            if (ca_cond_wait_for(g_recoveryCond, g_recoveryMutex, WAITING_TIME) == 0)
+            {
+                OIC_LOG(INFO, TAG, "BT recovery was canceled");
+            }
+            else
+            {
+                // enabled
+                if (!CAManagerControlAdapter(env, true))
+                {
+                    OIC_LOG(ERROR, TAG, "BT recovery(enable) failure");
+                    res = CA_STATUS_FAILED;
+                }
+            }
+            CAManagerSetBTRecovery(false);
+            break;
+        case START_RECOVERY:
+            if (!CAManagerControlAdapter(env, false))
+            {
+                OIC_LOG(ERROR, TAG, "BT recovery(disable) failure");
+                res = CA_STATUS_FAILED;
+            }
+            CAManagerSetBTRecovery(true);
+            break;
+        default:
+            break;
+    }
+
+    ca_mutex_unlock(g_recoveryMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerProcessRecovery");
+
+    return res;
+}
diff --git a/resource/csdk/connectivity/util/src/camanager/android/caleautoconnector.h b/resource/csdk/connectivity/util/src/camanager/android/caleautoconnector.h
new file mode 100644 (file)
index 0000000..4875a88
--- /dev/null
@@ -0,0 +1,74 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#ifndef CA_AUTO_CONNECTOR_H_
+#define CA_AUTO_CONNECTOR_H_
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define STATE_OFF 10
+#define START_RECOVERY 1
+
+/**
+ * start auto connection.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   remote_le_address     remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerStartAutoConnection(JNIEnv *env, jstring remote_le_address);
+
+/**
+ * request connect gatt on client in adapter
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   remote_le_address     remote address.
+ * @return  gatt profile object.
+ */
+jobject CAManagerConnectGatt(JNIEnv *env, jstring remote_le_address);
+
+/**
+ * initialize LE AutoConnection.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerInitLEAutoConnection();
+
+/**
+ * terminate LE AutoConnection
+ */
+void CAManagerTerminateLEAutoConnection();
+
+/**
+ * process BT recovery.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   adapter_state         recovery state to process.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerProcessRecovery(JNIEnv *env, uint16_t adapter_state);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_AUTO_CONNECTOR_H_ */
+
index 0660579..b479219 100644 (file)
  *
  ******************************************************************/
 
+#include <jni.h>
+#include "logger.h"
+#include "cautilinterface.h"
 #include "camanagerleinterface.h"
+#include "camanagerleutil.h"
+#include "caleautoconnector.h"
 #include "cacommon.h"
-#include "logger.h"
+#include "cacommonutil.h"
+#include "camanagerdevice.h"
+#include "caleclient.h"
+#include "caleutils.h"
 
-#define TAG "OIC_CA_MANAGER_AN_LE"
+#define TAG "OIC_CA_MANAGER_LE"
 
 static CAAdapterStateChangedCB g_adapterStateCB = NULL;
 static CAConnectionStateChangedCB g_connStateCB = NULL;
 
+static const jint SUPPORT_ADNROID_API_LEVEL = 18;
+static const jint AUTH_FAIL = 5;
+static const jint LINK_LOSS = 8;
+static const jint ACCEPT_TIMEOUT_EXCEPTION = 16;
+static const jint REMOTE_DISCONNECT = 19;
+static const jint LOCAL_DISCONNECT = 22;
+static const jint CONNECTION_FAILED_TO_BE_EASTABLISHED = 62;
+static const jint USER_REMOVED_BOND = 68;
+static JavaVM *g_jvm = NULL;
+static jobject g_context = NULL;
+static jobject g_connectedDeviceSet = NULL;
+
 void CASetLENetworkMonitorCallbacks(CAAdapterStateChangedCB adapterStateCB,
                                     CAConnectionStateChangedCB connStateCB)
 {
@@ -38,24 +58,577 @@ void CASetLENetworkMonitorCallbacks(CAAdapterStateChangedCB adapterStateCB,
 
 CAResult_t CASetLEClientAutoConnectionDeviceInfo(const char* address)
 {
-    OIC_LOG(DEBUG, TAG, "CASetLEClientAutoConnectionDeviceInfo");
+    OIC_LOG(DEBUG, TAG, "CASetClientAutoConnectionDeviceInfo");
+    VERIFY_NON_NULL(address, TAG, "address");
+
+    bool isAttached = false;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        OIC_LOG(DEBUG, TAG, "AttachCurrentThread will be called for JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
+        }
+        isAttached = true;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "set [%s] for Auto Connection", address);
+    jstring jni_leAddress = (*env)->NewStringUTF(env, address);
 
-    return CA_NOT_SUPPORTED;
+    if (!CAManagerCheckBTAddress(env, jni_leAddress))
+    {
+        OIC_LOG(ERROR, TAG, "this address is not BT address string format");
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+        return CA_STATUS_FAILED;
+    }
+
+    // if there is target address in SharedPreference. it will be reseted.
+    if (CAManagerIsConnectedDeviceAddress(env, g_context,
+                                          jni_leAddress,
+                                          g_connectedDeviceSet))
+    {
+        if (!CAManagerRemoveConnectedDeviceAddress(env, g_context,
+                                                   jni_leAddress,
+                                                   g_connectedDeviceSet))
+        {
+            OIC_LOG(ERROR, TAG, "Preference - remove has failed");
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "Preference - remove success");
+        }
+    }
+
+    // it will be added new target address.
+    if (!CAManagerAddConnectedDeviceAddress(env, g_context,
+                                            jni_leAddress, g_connectedDeviceSet))
+    {
+        OIC_LOG(ERROR, TAG, "Preference - putting has failed");
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "Preference - putting success");
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return CA_STATUS_OK;
 }
 
 CAResult_t CAUnsetLEClientAutoConnectionDeviceInfo(const char* address)
 {
-    OIC_LOG(DEBUG, TAG, "CAUnsetLEClientAutoConnectionDeviceInfo");
+    OIC_LOG(DEBUG, TAG, "CAUnsetClientAutoConnectionDeviceInfo");
+    VERIFY_NON_NULL(address, TAG, "address");
+
+    bool isAttached = false;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        OIC_LOG(DEBUG, TAG, "AttachCurrentThread will be called for JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-    return CA_NOT_SUPPORTED;
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
+        }
+        isAttached = true;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "unset [%s] for Auto Connection", address);
+    jstring jni_leAddress = (*env)->NewStringUTF(env, address);
+
+    if (!CAManagerCheckBTAddress(env, jni_leAddress))
+    {
+        OIC_LOG(ERROR, TAG, "this address is not BT address string format");
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+        return CA_STATUS_FAILED;
+    }
+
+    // if there is target address in SharedPreference. it would be removed
+    if (CAManagerIsConnectedDeviceAddress(env, g_context,
+                                          jni_leAddress,
+                                          g_connectedDeviceSet))
+    {
+        if (!CAManagerRemoveConnectedDeviceAddress(env, g_context,
+                                                   jni_leAddress,
+                                                   g_connectedDeviceSet))
+        {
+            OIC_LOG(ERROR, TAG, "Preference - remove has failed");
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "Preference - remove success");
+        }
+    }
+
+    // remove target device for auto connection
+    CAResult_t ret = CAManagerRemoveData(env, jni_leAddress);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerRemoveData has failed");
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return CA_STATUS_OK;
 }
 
-void CAStartServerLEAdvertising()
+CAResult_t CAManagerLEClientInitialize(JNIEnv *env, JavaVM *jvm, jobject context)
 {
-    OIC_LOG(DEBUG, TAG, "CAStartServerLEAdvertising");
+    OIC_LOG(DEBUG, TAG, "CAManagerClientInitialize");
+    VERIFY_NON_NULL(env, TAG, "env");
+    VERIFY_NON_NULL(jvm, TAG, "jvm");
+    VERIFY_NON_NULL(context, TAG, "context");
+
+    jint jni_int_sdk = CALEGetBuildVersion(env);
+    if (jni_int_sdk < SUPPORT_ADNROID_API_LEVEL)
+    {
+        OIC_LOG_V(ERROR, TAG, "it is not supported (%d)", jni_int_sdk);
+        return CA_STATUS_FAILED;
+    }
+
+    g_jvm = jvm;
+    g_context = (*env)->NewGlobalRef(env, context);;
+    CAManagerInitMutexVaraibles();
+    CAManagerInitLEAutoConnection();
+
+    CAManagerCreateACDataList(env);
+
+    // get last connected device list
+    jobject set = NULL;
+    set = CAManagerGetConnectedDeviceAddress(env, g_context);
+    if (!set)
+    {
+        // create new set<String> object
+        set = CAManagerCreateSetString(env);
+        if (set)
+        {
+            OIC_LOG(DEBUG, TAG, "created new SetString");
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "CAManagerCreateSetString has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "get previous Set<String> object");
+    }
+
+    g_connectedDeviceSet = (jobject)(*env)->NewGlobalRef(env, set);
+    if (!g_connectedDeviceSet)
+    {
+        OIC_LOG(ERROR, TAG, "g_connectedDeviceSet is null");
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAManagerLEClientTerminate(JNIEnv *env)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerClientTerminate");
+    VERIFY_NON_NULL(env, TAG, "env");
+
+    // stop gatt connection
+    CAResult_t res = CALEClientDisconnectAll(env);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
+    }
+
+    res = CAManagerRemoveAllData(env);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerRemoveAllData has failed");
+    }
+
+    CAManagerTerminateLEAutoConnection();
+    CAManagerTerminateMutexVariables();
+
+    if (g_context)
+    {
+        (*env)->DeleteGlobalRef(env, g_context);
+    }
+
+    if (g_connectedDeviceSet)
+    {
+        (*env)->DeleteGlobalRef(env, g_connectedDeviceSet);
+    }
+
+    return res;
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerAdapterStateChangedCallback(
+        JNIEnv *env, jobject obj, jint state)
+{
+    OIC_LOG(DEBUG, TAG, "caManagerAdapterStateChangedCallback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+    VERIFY_NON_NULL_VOID(obj, TAG, "obj");
+
+    jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
+    jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
+    jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");
+
+    if (state_on == state)
+    {
+        OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_on");
+        if (g_adapterStateCB)
+        {
+            g_adapterStateCB(CA_ADAPTER_GATT_BTLE, true);
+        }
+
+        // when BT state is on. recovery flag has to be reset.
+        CAManagerSetBTRecovery(false);
+
+        // find target device for autoconnect
+        size_t length = CAManagerGetACDataLength();
+        OIC_LOG_V(DEBUG, TAG, "target device : %d", length);
+        for (size_t idx = 0; idx < length; idx++)
+        {
+            jstring leAddress = CAManagerGetLEAddressFromACData(env, idx);
+            if (leAddress)
+            {
+                CAResult_t res = CAManagerStartAutoConnection(env, leAddress);
+                if (CA_STATUS_OK != res)
+                {
+                    OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed");
+                    return;
+                }
+            }
+        }
+    }
+    else if (state_off == state)
+    {
+        OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_off");
+        if (g_adapterStateCB)
+        {
+            g_adapterStateCB(CA_ADAPTER_GATT_BTLE, false);
+        }
+
+        // reset autoconnect flag for all target devices
+        size_t length = CAManagerGetACDataLength();
+        for (size_t idx = 0; idx < length; idx++)
+        {
+            jstring address = CAManagerGetLEAddressFromACData(env, idx);
+            if (address)
+            {
+                CAManagerSetAutoConnectionFlag(env, address, false);
+            }
+        }
+
+        // check whether BT recovery is needed or not
+        if (CAManagerIsRecoveryFlagSet())
+        {
+            CAManagerProcessRecovery(env, STATE_OFF);
+        }
+    }
+    else if (state_turning_off == state)
+    {
+        OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_turning_off");
+        return;
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "AdapterStateChangedCallback state is not available");
+        return;
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerBondStateChangedCallback(
+        JNIEnv *env, jobject obj, jobject device)
+{
+    OIC_LOG(DEBUG, TAG, "caManagerBondStateChangedCallback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+    VERIFY_NON_NULL_VOID(obj, TAG, "obj");
+    VERIFY_NON_NULL_VOID(device, TAG, "device");
+
+    // get ble address from Bluetooth Device object
+    jstring jni_leAddress = CALEClientGetLEAddressFromBTDevice(env, device);
+    if (!jni_leAddress)
+    {
+        OIC_LOG(INFO, TAG, "unbonded : it isn't same device type");
+        return;
+    }
+
+    char* leAddress = (char*)(*env)->GetStringUTFChars(env, jni_leAddress, NULL);
+    if (!leAddress)
+    {
+        OIC_LOG(ERROR, TAG, "leAddress is null");
+        return;
+    }
+
+    // if there is no data, CAData will be created.
+    OIC_LOG_V(DEBUG, TAG, "bond none device : %s", leAddress);
+
+    CAResult_t res = CAManagerRemoveData(env, jni_leAddress);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerRemoveData has failed");
+    }
+
+    (*env)->ReleaseStringUTFChars(env, jni_leAddress, leAddress);
+
+    if (!CAManagerRemoveConnectedDeviceAddress(env, g_context,
+                                               jni_leAddress,
+                                               g_connectedDeviceSet))
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerRemoveConnectedDeviceAddress has failed");
+    }
+
+    OIC_LOG(INFO, TAG, "bonded state changed bone_none");
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB(
+        JNIEnv *env, jobject obj, jobject gatt, jint status, jint newState)
+{
+    OIC_LOG_V(DEBUG, TAG, "caManagerLeGattConnectionStateChangeCB-status(%d), newState(%d)",
+              status, newState);
+
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+    VERIFY_NON_NULL_VOID(obj, TAG, "obj");
+    VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
+
+    jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
+    jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
+    jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
+
+    jstring jni_address = CAManagerGetAddressFromGatt(env, gatt);
+    if (!jni_address)
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerGetAddressFromGatt is null");
+        return;
+    }
+
+    char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is null");
+        return;
+    }
+
+    OIC_LOG_V(INFO, TAG, "connection state : status(%d), addr:(%s), newState(%d)",
+              status, address, newState);
+
+    if (gatt_success == status && state_connected == newState) // le connected
+    {
+        OIC_LOG(DEBUG, TAG, "LE is connected");
+        CAResult_t res = CAManagerReadRemoteRssi(env, gatt);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CAManagerReadRemoteRssi has failed");
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+            return;
+        }
+    }
+    else if (state_disconnected == newState)// le disconnected
+    {
+        if (LINK_LOSS == status || REMOTE_DISCONNECT == status)
+        {
+            OIC_LOG(DEBUG, TAG, "LE is disconnected");
+
+            if (g_connStateCB)
+            {
+                OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %d, %s", newState, address);
+                g_connStateCB(CA_ADAPTER_GATT_BTLE, address, false);
+                OIC_LOG(DEBUG, TAG, "LE Disconnected state callback is called");
+            }
+
+            if (!CAManagerIsMatchedACData(env, jni_address))
+            {
+                OIC_LOG_V(DEBUG, TAG, "this[%s] is not target address for Auto Connection",
+                          address);
+                (*env)->ReleaseStringUTFChars(env, jni_address, address);
+                return;
+            }
+
+            CAManagerSetAutoConnectionFlag(env, jni_address, false);
+
+            CAResult_t res = CAManagerStartAutoConnection(env, jni_address);
+            if (CA_STATUS_OK != res)
+            {
+                (*env)->ReleaseStringUTFChars(env, jni_address, address);
+                OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed");
+                return;
+            }
+        }
+        else if (ACCEPT_TIMEOUT_EXCEPTION == status)
+        {
+            CAManagerProcessRecovery(env, START_RECOVERY);
+        }
+    }
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    (*env)->DeleteLocalRef(env, jni_address);
+}
+
+/*
+ * Class:     org_iotivity_ca_jar_caleinterface
+ * Method:    caManagerLeServicesDiscoveredCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback(JNIEnv *env,
+                                                                               jobject obj,
+                                                                               jobject gatt,
+                                                                               jint status)
+{
+    OIC_LOG_V(DEBUG, TAG, "caManagerLeServicesDiscoveredCallback - status %d: ", status);
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+    VERIFY_NON_NULL_VOID(obj, TAG, "obj");
+    VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
+
+    if (GATT_SUCCESS == status)
+    {
+        jstring jni_address = CAManagerGetAddressFromGatt(env, gatt);
+        if (!jni_address)
+        {
+            OIC_LOG(ERROR, TAG, "CAManagerGetAddressFromGatt is null");
+            return;
+        }
+
+        char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
+        if (!address)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            return;
+        }
+        OIC_LOG_V(DEBUG, TAG, "ServicesDiscovered device : %s", address);
+
+        // target address for auto connection will be set in device list.
+        // check set connected address information by user
+        jclass jni_cls_set = (*env)->FindClass(env, "java/util/HashSet");
+        if (!jni_cls_set)
+        {
+            OIC_LOG(ERROR, TAG, "jni_cls_set is null");
+            return;
+        }
+
+        jmethodID jni_mid_iterator = (*env)->GetMethodID(env, jni_cls_set, "iterator", "()Ljava/util/Iterator;");
+        if (!jni_mid_iterator)
+        {
+            OIC_LOG(ERROR, TAG, "jni_mid_iterator is null");
+            return;
+        }
+
+        jobject jni_obj_iter = (*env)->CallObjectMethod(env, g_connectedDeviceSet, jni_mid_iterator);
+        if (!jni_obj_iter)
+        {
+            OIC_LOG(ERROR, TAG, "jni_obj_iter is null");
+            return;
+        }
+
+        // Get the Iterator method IDs
+        jclass jni_cls_iterator = (*env)->FindClass(env, "java/util/Iterator");
+        if (!jni_cls_iterator)
+        {
+            OIC_LOG(ERROR, TAG, "jni_cls_iterator is null");
+            return;
+        }
+
+        jmethodID jni_mid_hasNext = (*env)->GetMethodID(env, jni_cls_iterator, "hasNext", "()Z");
+        if (!jni_mid_hasNext)
+        {
+            OIC_LOG(ERROR, TAG, "jni_mid_hasNext is null");
+            return;
+        }
+
+        jmethodID jni_mid_next = (*env)->GetMethodID(env, jni_cls_iterator, "next", "()Ljava/lang/Object;");
+        if (!jni_mid_next)
+        {
+            OIC_LOG(ERROR, TAG, "jni_mid_next is null");
+            return;
+        }
+
+        // Iterate over the entry Set
+        while ((*env)->CallBooleanMethod(env, jni_obj_iter, jni_mid_hasNext))
+        {
+            jstring jni_str_entry = (jstring)(*env)->CallObjectMethod(env, jni_obj_iter, jni_mid_next);
+            const char* foundAddress = (*env)->GetStringUTFChars(env, jni_str_entry, NULL);
+            if (!foundAddress)
+            {
+                OIC_LOG(ERROR, TAG, "addr is null");
+                return;
+            }
+            OIC_LOG_V(INFO, TAG, "found last connected address [%s] from SharedPreferences",
+                      foundAddress);
+
+            if (!strcmp(foundAddress, address))
+            {
+                // if BLE address is matched each other
+                // this address will be added into auto connection list.
+                OIC_LOG(INFO, TAG, "AC list - address will be added into ACData list");
+                CAManagerAddACData(env, jni_address);
+                CAManagerSetAutoConnectionFlag(env, jni_address, false);
+
+                // next connection will be requested as JNI_TRUE flag
+                // after first connection
+            }
+            else
+            {
+                OIC_LOG(INFO, TAG, "AC list - device is not matched");
+            }
+
+            (*env)->ReleaseStringUTFChars(env, jni_str_entry, foundAddress);
+            (*env)->DeleteLocalRef(env, jni_str_entry);
+        }
+
+        if (g_connStateCB)
+        {
+            g_connStateCB(CA_ADAPTER_GATT_BTLE, address, true);
+            OIC_LOG(DEBUG, TAG, "LE Connected callback is called");
+        }
+        (*env)->ReleaseStringUTFChars(env, jni_address, address);
+        (*env)->DeleteLocalRef(env, jni_address);
+        (*env)->DeleteLocalRef(env, jni_cls_set);
+        (*env)->DeleteLocalRef(env, jni_obj_iter);
+        (*env)->DeleteLocalRef(env, jni_cls_iterator);
+
+        OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
+    }
 }
 
-void CAStopServerLEAdvertising()
+/*
+ * Class:     org_iotivity_ca_jar_caleinterface
+ * Method:    caManagerLeRemoteRssiCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caManagerLeRemoteRssiCallback(JNIEnv *env,
+                                                                       jobject obj,
+                                                                       jobject gatt,
+                                                                       jint rssi,
+                                                                       jint status)
 {
-    OIC_LOG(DEBUG, TAG, "CAStopServerLEAdvertising");
+    OIC_LOG_V(DEBUG, TAG, "caManagerLeRemoteRssiCallback - rssi : %d: ", rssi);
+    OIC_LOG_V(DEBUG, TAG, "caManagerLeRemoteRssiCallback - status : %d: ", status);
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+    VERIFY_NON_NULL_VOID(obj, TAG, "obj");
+    VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
 }
diff --git a/resource/csdk/connectivity/util/src/camanager/android/camanagerdevice.c b/resource/csdk/connectivity/util/src/camanager/android/camanagerdevice.c
new file mode 100755 (executable)
index 0000000..6950361
--- /dev/null
@@ -0,0 +1,427 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <jni.h>
+#include "cacommon.h"
+#include "logger.h"
+#include "cacommonutil.h"
+#include "camanagerleutil.h"
+#include "uarraylist.h"
+#include "camutex.h"
+#include "camanagerdevice.h"
+#include "oic_malloc.h"
+
+#define TAG "OIC_CA_MANAGER_DEVICE"
+
+static u_arraylist_t *g_deviceACDataList = NULL;
+static ca_mutex g_deviceACDataListMutex = NULL;
+static bool g_isBTRecovery = false;
+
+jstring CAManagerGetLEAddressFromACData(JNIEnv *env, size_t idx)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerGetLEAddressFromACData");
+    OIC_LOG_V(DEBUG, TAG, "idx : %d", idx);
+    if (idx <= u_arraylist_length(g_deviceACDataList))
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(
+                g_deviceACDataList, idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            return NULL;
+        }
+
+        const char* address = (*env)->GetStringUTFChars(env, curData->address, NULL);
+        if (!address)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            return NULL;
+        }
+        OIC_LOG_V(INFO, TAG, "found out target address : %s", address);
+        (*env)->ReleaseStringUTFChars(env, curData->address, address);
+
+        return curData->address;
+    }
+    return NULL;
+}
+
+void CAManagerCreateACDataList(JNIEnv *env)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerCreateACDataList");
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+
+    ca_mutex_lock(g_deviceACDataListMutex);
+    // create new object array
+    if (g_deviceACDataList == NULL)
+    {
+        OIC_LOG(DEBUG, TAG, "Create AC Data list");
+
+        g_deviceACDataList = u_arraylist_create();
+    }
+    ca_mutex_unlock(g_deviceACDataListMutex);
+}
+
+CAResult_t CAManagerInitMutexVaraibles()
+{
+    if (NULL == g_deviceACDataListMutex)
+    {
+        g_deviceACDataListMutex = ca_mutex_new();
+        if (NULL == g_deviceACDataListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+    return CA_STATUS_OK;
+}
+
+void CAManagerTerminateMutexVariables()
+{
+    if (g_deviceACDataListMutex)
+    {
+        ca_mutex_free(g_deviceACDataListMutex);
+        g_deviceACDataListMutex = NULL;
+    }
+}
+
+static CAManagerACData_t *CAManagerCreateACData(jstring jaddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerCreateACData");
+    VERIFY_NON_NULL_RET(jaddress, TAG, "jaddress", NULL);
+
+    // create block data
+    CAManagerACData_t *data = (CAManagerACData_t *) OICCalloc(1, sizeof(*data));
+    if (!data)
+    {
+        OIC_LOG(ERROR, TAG, "memory alloc has failed");
+        return NULL;
+    }
+
+    data->address = jaddress;
+    data->isAutoConnect = false;
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerCreateACData");
+    return data;
+}
+
+bool CAManagerIsMatchedACData(JNIEnv *env, jstring jaddress)
+{
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+    VERIFY_NON_NULL_RET(jaddress, TAG, "jaddress", false);
+
+    const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is null");
+        return false;
+    }
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            return false;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, curData->address, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            return false;
+        }
+
+        if (!strcmp(setAddress, address))
+        {
+            (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            return true;
+        }
+        (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+    }
+    (*env)->ReleaseStringUTFChars(env, jaddress, address);
+
+    return false;
+}
+
+void CAManagerAddACData(JNIEnv *env, jstring jaddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerAddACData");
+
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+    VERIFY_NON_NULL_VOID(jaddress, TAG, "jaddress");
+
+    ca_mutex_lock(g_deviceACDataListMutex);
+
+    if(!CAManagerIsMatchedACData(env, jaddress))
+    {
+        OIC_LOG(DEBUG, TAG, "ACdata will be added");
+        // add CAManagerACData
+        jobject gaddress = (*env)->NewGlobalRef(env, jaddress);
+
+        CAManagerACData_t *data = CAManagerCreateACData(gaddress);
+        u_arraylist_add(g_deviceACDataList, data);
+    }
+    ca_mutex_unlock(g_deviceACDataListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerAddACData");
+}
+
+CAResult_t CAManagerRemoveData(JNIEnv *env, jstring jaddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerRemoveData");
+    VERIFY_NON_NULL(env, TAG, "env");
+    VERIFY_NON_NULL(jaddress, TAG, "jaddress");
+
+    ca_mutex_lock(g_deviceACDataListMutex);
+
+    const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is null");
+        ca_mutex_unlock(g_deviceACDataListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "(%s) will be removed", address);
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, curData->address, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (!strcmp(setAddress, address))
+        {
+            if (NULL == u_arraylist_remove(g_deviceACDataList, idx))
+            {
+                OIC_LOG(ERROR, TAG, "removal has failed.");
+                (*env)->ReleaseStringUTFChars(env, jaddress, address);
+                (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+                ca_mutex_unlock(g_deviceACDataListMutex);
+                return CA_STATUS_FAILED;
+            }
+
+            (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+
+            if (curData->address)
+            {
+                (*env)->DeleteGlobalRef(env, curData->address);
+            }
+
+            OICFree(curData);
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            OIC_LOG(DEBUG, TAG, "remove done");
+            return CA_STATUS_OK;
+        }
+        (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+    }
+
+    (*env)->ReleaseStringUTFChars(env, jaddress, address);
+    ca_mutex_unlock(g_deviceACDataListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerRemoveData");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAManagerRemoveAllData(JNIEnv *env)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerRemoveAllData");
+    VERIFY_NON_NULL(env, TAG, "env");
+
+    ca_mutex_lock(g_deviceACDataListMutex);
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (NULL == u_arraylist_remove(g_deviceACDataList, idx))
+        {
+            OIC_LOG(ERROR, TAG, "removal has failed.");
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (curData->address)
+        {
+            (*env)->DeleteGlobalRef(env, curData->address);
+        }
+
+        OICFree(curData);
+    }
+    ca_mutex_unlock(g_deviceACDataListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerRemoveAllData");
+    return CA_STATUS_OK;
+}
+
+bool CAManagerGetAutoConnectionFlag(JNIEnv *env, jstring jaddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerGetAutoConnectionFlag");
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+    VERIFY_NON_NULL_RET(jaddress, TAG, "jaddress", NULL);
+
+    ca_mutex_lock(g_deviceACDataListMutex);
+
+    const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is null");
+        ca_mutex_unlock(g_deviceACDataListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, curData->address, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (!strcmp(setAddress, address))
+        {
+            (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            OIC_LOG_V(DEBUG, TAG, "flag is %d", curData->isAutoConnect);
+            return curData->isAutoConnect;
+        }
+        (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+    }
+    (*env)->ReleaseStringUTFChars(env, jaddress, address);
+    ca_mutex_unlock(g_deviceACDataListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerGetAutoConnectionFlag");
+    return false;
+}
+
+void CAManagerSetAutoConnectionFlag(JNIEnv *env, jstring jaddress, bool flag)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerSetAutoConnectionFlag");
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+    VERIFY_NON_NULL_VOID(jaddress, TAG, "jaddress");
+
+    ca_mutex_lock(g_deviceACDataListMutex);
+
+    const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is null");
+        ca_mutex_unlock(g_deviceACDataListMutex);
+        return;
+    }
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, curData->address, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return;
+        }
+
+        if (!strcmp(setAddress, address))
+        {
+            OIC_LOG_V(DEBUG, TAG, "flag is set to %d", flag);
+            curData->isAutoConnect = flag;
+            (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+            (*env)->ReleaseStringUTFChars(env, jaddress, address);
+            ca_mutex_unlock(g_deviceACDataListMutex);
+            return;
+        }
+        (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
+    }
+    (*env)->ReleaseStringUTFChars(env, jaddress, address);
+    ca_mutex_unlock(g_deviceACDataListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerSetAutoConnectionFlag");
+}
+
+size_t CAManagerGetACDataLength()
+{
+    return u_arraylist_length(g_deviceACDataList);
+}
+
+void CAManagerSetBTRecovery(bool flag)
+{
+    g_isBTRecovery = flag;
+    OIC_LOG_V(DEBUG, TAG, "BT recovery flag : %d", g_isBTRecovery);
+}
+
+bool CAManagerIsRecoveryFlagSet()
+{
+    return g_isBTRecovery;
+}
diff --git a/resource/csdk/connectivity/util/src/camanager/android/camanagerdevice.h b/resource/csdk/connectivity/util/src/camanager/android/camanagerdevice.h
new file mode 100644 (file)
index 0000000..f3ec358
--- /dev/null
@@ -0,0 +1,135 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#ifndef CA_MANAGER_DEVICE_H_
+#define CA_MANAGER_DEVICE_H_
+
+#include <jni.h>
+#include "uarraylist.h"
+#include "camutex.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * Auto Connection Target Device Identity
+ */
+typedef struct
+{
+    jstring address;      /**< remote address */
+    bool isAutoConnect;   /**< auto connection flag */
+} CAManagerACData_t;
+
+/**
+ * get address from auto connection list.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   idx                   index of auto connection data list.
+ * @return  address
+ */
+jstring CAManagerGetLEAddressFromACData(JNIEnv *env, size_t idx);
+
+/**
+ * create auto connection list.
+ * @param[in]   env                   JNI interface pointer.
+ */
+void CAManagerCreateACDataList(JNIEnv *env);
+
+/**
+ * initialize mutex.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerInitMutexVaraibles();
+
+/**
+ * terminate mutex.
+ */
+void CAManagerTerminateMutexVariables();
+
+/**
+ * check whether target address is already contained in list or not.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jaddress              ble address.
+ */
+bool CAManagerIsMatchedACData(JNIEnv *env, jstring jaddress);
+
+/**
+ * add auto connection data into list.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jaddress              ble address.
+ */
+void CAManagerAddACData(JNIEnv *env, jstring jaddress);
+
+/**
+ * remove auto connection data for selected ble address.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jaddress              ble address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerRemoveData(JNIEnv *env, jstring jaddress);
+
+/**
+ * remove auto connection data for all devices.
+ * @param[in]   env                   JNI interface pointer.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerRemoveAllData(JNIEnv *env);
+
+/**
+ * get current auto connection flag.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jaddress              ble address.
+ * @return  true or false
+ */
+bool CAManagerGetAutoConnectionFlag(JNIEnv *env, jstring jaddress);
+
+/**
+ * set auto connection flag.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jaddress              ble address.
+ * @param[in]   flag                  auto connection flag.
+ */
+void CAManagerSetAutoConnectionFlag(JNIEnv *env, jstring jaddress, bool flag);
+
+/**
+ * get length of auto connection list.
+ * @return  list size
+ */
+size_t CAManagerGetACDataLength();
+
+/**
+ * set BT adapter recovery flag.
+ * @param[in]   flag                  recovery flag.
+ */
+void CAManagerSetBTRecovery(bool flag);
+
+/**
+ * get BT adapter recovery flag.
+ * @return  recovery flag.
+ */
+bool CAManagerIsRecoveryFlagSet();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_MANAGER_DEVICE_H_ */
+
diff --git a/resource/csdk/connectivity/util/src/camanager/android/camanagerleutil.c b/resource/csdk/connectivity/util/src/camanager/android/camanagerleutil.c
new file mode 100755 (executable)
index 0000000..67ed86e
--- /dev/null
@@ -0,0 +1,807 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <jni.h>
+#include "cacommon.h"
+#include "logger.h"
+#include "cacommonutil.h"
+#include "camanagerleutil.h"
+#include "caleclient.h"
+#include "caleutils.h"
+
+#define TAG "OIC_CA_MANAGER_UTIL"
+
+static const char CLASSPATH_CONTENT_PREF[] = "android/content/SharedPreferences";
+static const char CLASSPATH_CONTENT_PREF_EDITOR[] = "android/content/SharedPreferences$Editor";
+static const char CLASSPATH_CONTEXT[] = "android/content/Context";
+
+static const char PREF_NAME_CONNECTED_DEVICE[] = "PREF_NAME_CONNECTED_DEVICE";
+static const char PREF_KEY_CONNECTED_DEVICE[] = "PREF_KEY_CONNECTED_DEVICE";
+
+static const char METHODID_BOOLEAN_RET_STRING_PARAM[] = "(Ljava/lang/String;)Z";
+
+static jobject CAManagerGetAdapterContext(JNIEnv *env)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerGetAdapterContext");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                                                    "getDefaultAdapter",
+                                                                    METHODID_OBJECTNONPARAM);
+    if (!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        return NULL;
+    }
+
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
+                                                               jni_mid_getDefaultAdapter);
+    if (!jni_obj_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        return NULL;
+    }
+    return jni_obj_BTAdapter;
+}
+
+jobject CAManagerGetRemoteDevice(JNIEnv *env, jstring address)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerGetRemoteDevice");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(address, TAG, "address is null", NULL);
+
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
+        return NULL;
+    }
+
+    // get remote bt adapter method
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                                                    "getDefaultAdapter",
+                                                                    METHODID_OBJECTNONPARAM);
+    if (!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        return NULL;
+    }
+
+    // gat bt adapter object
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
+                                                               jni_mid_getDefaultAdapter);
+    if (!jni_obj_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+                                                            "getRemoteDevice",
+                                                            METHODID_BT_REMOTE_DEVICE);
+    if (!jni_mid_getRemoteDevice)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getRemoteDevice is null");
+        return NULL;
+    }
+
+    jobject jni_obj_device = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+                                                      jni_mid_getRemoteDevice,
+                                                      address);
+    if (!jni_obj_device)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_device is null");
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetRemoteDevice");
+    return jni_obj_device;
+}
+
+jstring CAManagerGetAddressFromGatt(JNIEnv *env, jobject gatt)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
+
+    jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
+    if (!jni_cid_gattdevice_list)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
+                                                      METHODID_BT_DEVICE);
+    if (!jni_mid_getDevice)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
+        return NULL;
+    }
+
+    jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
+    if (!jni_obj_device)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_device is null");
+        return NULL;
+    }
+
+    jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
+    if (!jni_address)
+    {
+        OIC_LOG(ERROR, TAG, "jni_address is null");
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
+    return jni_address;
+}
+
+bool CAManagerIsDeviceBonded(JNIEnv *env, jobject btDevice)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerIsDeviceBonded");
+
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(btDevice, TAG, "btDevice is null");
+
+    jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
+    if (!jni_cid_BTDevice)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTDevice is null");
+        return false;
+    }
+
+    jmethodID jni_mid_getBondState = (*env)->GetMethodID(env, jni_cid_BTDevice,
+                                                         "getBondState", "()I");
+    if (!jni_mid_getBondState)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getBondState is null");
+        return false;
+    }
+
+    jint jni_bond_state = (*env)->CallIntMethod(env, btDevice, jni_mid_getBondState);
+    OIC_LOG_V(DEBUG, TAG, "bond state is %d", jni_bond_state);
+
+    // BOND_BONDED - Constant value : 12 (0x0000000c)
+    jfieldID id_bonded = (*env)->GetStaticFieldID(env, jni_cid_BTDevice,
+                                                  "BOND_BONDED", "I");
+    if (!id_bonded)
+    {
+        OIC_LOG(ERROR, TAG, "id_bonded is null");
+        return false;;
+    }
+
+    jint jni_bonded_const = (*env)->GetStaticIntField(env, jni_cid_BTDevice, id_bonded);
+
+    if (jni_bond_state == jni_bonded_const)
+    {
+        OIC_LOG(INFO, TAG, "it is not bonded to each other");
+        return false;
+    }
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerIsDeviceBonded");
+    return true;
+}
+
+bool CAManagerControlAdapter(JNIEnv *env, bool control_flag)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerControlAdapter");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+
+    jobject jni_obj_BTAdapter = CAManagerGetAdapterContext(env);
+    if (!jni_obj_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        return false;
+    }
+
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
+        return NULL;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "change adapter : %d", control_flag);
+    jmethodID jni_mid_control = NULL;
+    if (control_flag)
+    {
+        // enable()
+        jni_mid_control = (*env)->GetMethodID(env, jni_cid_BTAdapter, "enable", "()Z");
+    }
+    else
+    {
+        // disable()
+        jni_mid_control = (*env)->GetMethodID(env, jni_cid_BTAdapter, "disable", "()Z");
+    }
+
+    if (!jni_mid_control)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_control is null");
+        return false;
+    }
+
+    OIC_LOG(DEBUG, TAG, "CALL API - Adapter Will be Changed");
+    jboolean jni_res = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_control);
+
+    return jni_res;
+}
+
+CAResult_t CAManagerReadRemoteRssi(JNIEnv *env, jobject bluetoothGatt)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerReadRemoteRssi");
+
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+
+    if (!CALEIsEnableBTAdapter(env))
+    {
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    // get BluetoothGatt class
+    OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
+    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
+    if (!jni_cid_BluetoothGatt)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "discovery gatt services method");
+    jmethodID jni_mid_readRemoteRssi = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
+                                                             "readRemoteRssi", "()Z");
+    if (!jni_mid_readRemoteRssi)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_readRemoteRssi is null");
+        return CA_STATUS_FAILED;
+    }
+    // call disconnect gatt method
+    OIC_LOG(DEBUG, TAG, "CALL API - request readremoteRssi");
+    jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readRemoteRssi);
+    if (!ret)
+    {
+        OIC_LOG(ERROR, TAG, "readremoteRssi has not been called");
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
+}
+
+jobject CAManagerGetSharedPreference(JNIEnv *env, jobject context, jstring prefName)
+{
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+    VERIFY_NON_NULL_RET(context, TAG, "context", NULL);
+    VERIFY_NON_NULL_RET(prefName, TAG, "prefName", NULL);
+
+    jclass jni_cls_context = (*env)->FindClass(env, CLASSPATH_CONTEXT);
+    if (!jni_cls_context)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_context is null");
+        return NULL;
+    }
+
+    // getSharedPreferences
+    jmethodID jni_mid_getPref = (*env)->GetMethodID(env, jni_cls_context, "getSharedPreferences",
+                                                    "(Ljava/lang/String;I)"
+                                                    "Landroid/content/SharedPreferences;");
+    if (!jni_mid_getPref)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getPref is null");
+        return NULL;
+    }
+
+    jobject jni_obj_sharedPref = (*env)->CallObjectMethod(env, context,
+                                                          jni_mid_getPref,
+                                                          prefName,
+                                                          0);
+    if (!jni_obj_sharedPref)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_sharedPref is null");
+        return NULL;
+    }
+
+    return jni_obj_sharedPref;
+}
+
+jobject CAManagerGetPrefEditObject(JNIEnv *env, jobject context)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerGetPrefEditObject");
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+    VERIFY_NON_NULL_RET(context, TAG, "context", NULL);
+
+    jstring jni_str_prefName = (*env)->NewStringUTF(env, PREF_NAME_CONNECTED_DEVICE);
+    if (!jni_str_prefName)
+    {
+        OIC_LOG(ERROR, TAG, "jni_str_prefName is null");
+        return NULL;
+    }
+
+    jstring jni_str_prefKey = (*env)->NewStringUTF(env, PREF_KEY_CONNECTED_DEVICE);
+    if (!jni_str_prefKey)
+    {
+        OIC_LOG(ERROR, TAG, "jni_str_prefKey is null");
+        return NULL;
+    }
+
+    // get SharedPreference
+    jobject jni_obj_pref = CAManagerGetSharedPreference(env, context, jni_str_prefName);
+    if (!jni_obj_pref)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_pref is null");
+        return NULL;
+    }
+
+    // edit()
+    jobject jni_cls_pref = (*env)->FindClass(env, CLASSPATH_CONTENT_PREF);
+    if (!jni_cls_pref)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_pref is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_prefEdit = (*env)->GetMethodID(env, jni_cls_pref, "edit",
+                                                     "()Landroid/content/SharedPreferences$Editor;");
+    if (!jni_mid_prefEdit)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_prefEdit is null");
+        return NULL;
+    }
+
+    jobject jni_obj_prefEdit = (*env)->CallObjectMethod(env, jni_obj_pref, jni_mid_prefEdit);
+    if (!jni_obj_prefEdit)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_prefEdit is null");
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerGetPrefEditObject");
+    return jni_obj_prefEdit;
+}
+
+bool CAManagerUpdatePrefStringSet(JNIEnv *env, jobject context, jobject set)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerUpdatePrefStringSet");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+    VERIFY_NON_NULL_RET(context, TAG, "context", false);
+    VERIFY_NON_NULL_RET(set, TAG, "set", false);
+
+    jstring jni_str_prefKey = (*env)->NewStringUTF(env, PREF_KEY_CONNECTED_DEVICE);
+    if (!jni_str_prefKey)
+    {
+        OIC_LOG(ERROR, TAG, "jni_str_prefKey is null");
+        return false;
+    }
+
+    jobject jni_obj_prefEdit = CAManagerGetPrefEditObject(env, context);
+    if (!jni_obj_prefEdit)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_prefEdit is null");
+        return false;
+    }
+
+    // putString()
+    jobject jni_cls_edit = (*env)->FindClass(env, CLASSPATH_CONTENT_PREF_EDITOR);
+    if (!jni_cls_edit)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_edit is null");
+        return false;
+    }
+
+    // get putString method interface
+    jmethodID jni_mid_PrefPutStringSet = (*env)->GetMethodID(env, jni_cls_edit, "putStringSet",
+                                                             "(Ljava/lang/String;Ljava/util/Set;)"
+                                                             "Landroid/content/SharedPreferences"
+                                                             "$Editor;");
+    if (!jni_mid_PrefPutStringSet)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_PrefPutStringSet is null");
+        return false;
+    }
+
+    jobject gSetString = (jobject)(*env)->NewGlobalRef(env, set);
+    if (!gSetString)
+    {
+        OIC_LOG(ERROR, TAG, "gAddress is null");
+        return false;
+    }
+
+    OIC_LOG(DEBUG, TAG, "CALL API - request putString for SharedPreferences.Editor");
+    (*env)->CallObjectMethod(env, jni_obj_prefEdit, jni_mid_PrefPutStringSet,
+                             jni_str_prefKey, gSetString);
+
+    // get commit method interface
+    jmethodID jni_mid_PrefCommit = (*env)->GetMethodID(env, jni_cls_edit, "commit",
+                                                       "()Z");
+    if (!jni_mid_PrefCommit)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_PrefCommit is null");
+        return false;
+    }
+
+    jboolean res = (*env)->CallBooleanMethod(env, jni_obj_prefEdit, jni_mid_PrefCommit);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerUpdatePrefStringSet");
+    return res;
+}
+
+jobject CAManagerGetPrefStringSet(JNIEnv *env, jobject context)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerGetPrefStringSet");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+    VERIFY_NON_NULL_RET(context, TAG, "context", NULL);
+
+    jstring jni_str_prefName = (*env)->NewStringUTF(env, PREF_NAME_CONNECTED_DEVICE);
+    if (!jni_str_prefName)
+    {
+        OIC_LOG(ERROR, TAG, "jni_str_prefName is null");
+        return NULL;
+    }
+
+    jstring jni_str_prefKey = (*env)->NewStringUTF(env, PREF_KEY_CONNECTED_DEVICE);
+    if (!jni_str_prefKey)
+    {
+        OIC_LOG(ERROR, TAG, "jni_str_prefKey is null");
+        return NULL;
+    }
+
+    // get SharedPreference
+    jobject jni_obj_pref = CAManagerGetSharedPreference(env, context, jni_str_prefName);
+    if (!jni_obj_pref)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_pref is null");
+        return NULL;
+    }
+
+    // contains(String key)
+    jobject jni_cls_pref = (*env)->FindClass(env, CLASSPATH_CONTENT_PREF);
+    if (!jni_cls_pref)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_pref is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_getStringSet = (*env)->GetMethodID(env, jni_cls_pref, "getStringSet",
+                                                         "(Ljava/lang/String;Ljava/util/Set;)"
+                                                         "Ljava/util/Set;");
+    if (!jni_mid_getStringSet)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getStringSet is null");
+        return NULL;
+    }
+
+    jobject jni_defSet = CAManagerCreateSetString(env);
+    if (!jni_defSet)
+    {
+        OIC_LOG(ERROR, TAG, "jni_defSet is null");
+        return NULL;
+    }
+
+    jobject value = (*env)->CallObjectMethod(env, jni_obj_pref,
+                                             jni_mid_getStringSet,
+                                             jni_str_prefKey,
+                                             jni_defSet);
+
+    return value;
+}
+
+bool CAManagerContainsPrefStringSet(JNIEnv *env, jobject context)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerContainsPrefStringSet");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+    VERIFY_NON_NULL_RET(context, TAG, "context", false);
+
+    jstring jni_str_prefName = (*env)->NewStringUTF(env, PREF_NAME_CONNECTED_DEVICE);
+    if (!jni_str_prefName)
+    {
+        OIC_LOG(ERROR, TAG, "jni_str_prefName is null");
+        return false;
+    }
+
+    jstring jni_str_prefKey = (*env)->NewStringUTF(env, PREF_KEY_CONNECTED_DEVICE);
+    if (!jni_str_prefKey)
+    {
+        OIC_LOG(ERROR, TAG, "jni_str_prefKey is null");
+        return false;
+    }
+
+    // get SharedPreference
+    jobject jni_obj_pref = CAManagerGetSharedPreference(env, context, jni_str_prefName);
+    if (!jni_obj_pref)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_pref is null");
+        return false;
+    }
+
+    // contains(String key)
+    jobject jni_cls_pref = (*env)->FindClass(env, CLASSPATH_CONTENT_PREF);
+    if (!jni_cls_pref)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_pref is null");
+        return false;
+    }
+
+    jmethodID jni_mid_prefContains = (*env)->GetMethodID(env, jni_cls_pref, "contains",
+                                                         METHODID_BOOLEAN_RET_STRING_PARAM);
+    if (!jni_mid_prefContains)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_prefContains is null");
+        return false;
+    }
+
+    jboolean res = (*env)->CallBooleanMethod(env, jni_obj_pref,
+                                             jni_mid_prefContains,
+                                             jni_str_prefKey);
+
+    OIC_LOG_V(DEBUG, TAG, "Preference - contains (%d)", res);
+    return res;
+}
+
+bool CAManagerRemovePrefStringSet(JNIEnv *env, jobject context)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerRemovePrefStringSet");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+    VERIFY_NON_NULL_RET(context, TAG, "context", false);
+
+    jstring jni_str_prefKey = (*env)->NewStringUTF(env, PREF_KEY_CONNECTED_DEVICE);
+    if (!jni_str_prefKey)
+    {
+        OIC_LOG(ERROR, TAG, "jni_str_prefKey is null");
+        return false;
+    }
+
+    jobject jni_obj_prefEdit = CAManagerGetPrefEditObject(env, context);
+    if (!jni_obj_prefEdit)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_prefEdit is null");
+        return false;
+    }
+
+    // putString()
+    jobject jni_cls_edit = (*env)->FindClass(env, CLASSPATH_CONTENT_PREF_EDITOR);
+    if (!jni_cls_edit)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_edit is null");
+        return false;
+    }
+
+    // get remove method interface
+    jmethodID jni_mid_PrefRemove = (*env)->GetMethodID(env, jni_cls_edit, "remove",
+                                                       "(Ljava/lang/String;)"
+                                                       "Landroid/content/SharedPreferences"
+                                                       "$Editor;");
+    if (!jni_mid_PrefRemove)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_PrefRemove is null");
+        return false;
+    }
+
+    OIC_LOG(DEBUG, TAG, "CALL API - request remove for SharedPreferences.Editor");
+    (*env)->CallObjectMethod(env, jni_obj_prefEdit, jni_mid_PrefRemove, jni_str_prefKey);
+
+    // get commit method interface
+    jmethodID jni_mid_PrefCommit = (*env)->GetMethodID(env, jni_cls_edit, "commit",
+                                                       "()Z");
+    if (!jni_mid_PrefCommit)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_PrefCommit is null");
+        return false;
+    }
+
+    jboolean res = (*env)->CallBooleanMethod(env, jni_obj_prefEdit, jni_mid_PrefCommit);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerAddConnectedDeviceAddress");
+    return res;
+}
+
+bool CAManagerAddConnectedDeviceAddress(JNIEnv *env, jobject context,
+                                        jstring address, jobject set)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerAddConnectedDeviceAddress");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+    VERIFY_NON_NULL_RET(context, TAG, "context", false);
+    VERIFY_NON_NULL_RET(address, TAG, "address", false);
+    VERIFY_NON_NULL_RET(set, TAG, "set", false);
+
+    if (CAManagerCallFuncSetString(env, address, set, CM_CONTAINS))
+    {
+        OIC_LOG(DEBUG, TAG, "it's already done");
+        return true;
+    }
+
+    if (!CAManagerCallFuncSetString(env, address, set, CM_ADD))
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerAddSetString has failed");
+        return false;
+    }
+
+    return CAManagerUpdatePrefStringSet(env, context, set);
+}
+
+bool CAManagerIsConnectedDeviceAddress(JNIEnv *env, jobject context,
+                                       jstring address, jobject set)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerIsConnectedDeviceAddress");
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+    VERIFY_NON_NULL_RET(context, TAG, "context", false);
+
+    return CAManagerCallFuncSetString(env, address, set, CM_CONTAINS);
+}
+
+jobject CAManagerGetConnectedDeviceAddress(JNIEnv *env, jobject context)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerGetConnectedDeviceAddress");
+
+    if (!CAManagerContainsPrefStringSet(env, context))
+    {
+        OIC_LOG(DEBUG, TAG, "there is no set data");
+        return NULL;
+    }
+
+    return CAManagerGetPrefStringSet(env, context);
+}
+
+bool CAManagerRemoveConnectedDeviceAddress(JNIEnv *env, jobject context,
+                                           jstring address, jobject set)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerRemoveConnectedDeviceAddress");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+    VERIFY_NON_NULL_RET(context, TAG, "context", false);
+    VERIFY_NON_NULL_RET(address, TAG, "address", false);
+    VERIFY_NON_NULL_RET(set, TAG, "set", false);
+
+    if (!CAManagerCallFuncSetString(env, address, set, CM_CONTAINS))
+    {
+        OIC_LOG(DEBUG, TAG, "it's already done");
+        return true;
+    }
+
+    if (!CAManagerCallFuncSetString(env, address, set, CM_REMOVE))
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerAddSetString has failed");
+        return false;
+    }
+
+    return CAManagerUpdatePrefStringSet(env, context, set);
+}
+
+jboolean CAManagerCheckBTAddress(JNIEnv *env, jstring address)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerCheckBTAddress");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", JNI_FALSE);
+    VERIFY_NON_NULL_RET(address, TAG, "address is null", JNI_FALSE);
+
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
+        return JNI_FALSE;
+    }
+
+    // get remote bt adapter method
+    jmethodID jni_mid_checkBTAddress =
+            (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                      "checkBluetoothAddress",
+                                      METHODID_BOOLEAN_RET_STRING_PARAM);
+    if (!jni_mid_checkBTAddress)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_checkBTAddress is null");
+        return JNI_FALSE;
+    }
+
+    jboolean jni_obj_isAddress = (*env)->CallStaticBooleanMethod(env, jni_cid_BTAdapter,
+                                                                 jni_mid_checkBTAddress,
+                                                                 address);
+    return jni_obj_isAddress;
+}
+
+jobject CAManagerCreateSetString(JNIEnv *env)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerCallFuncSetString");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+
+    jclass jclazzMap = (*env)->FindClass(env, "java/util/HashSet" );
+    if (!jclazzMap)
+    {
+        OIC_LOG(ERROR, TAG, "jclazzMap is null");
+        return NULL;
+    }
+
+    jmethodID jinitMap = (*env)->GetMethodID(env, jclazzMap, "<init>", "()V");
+    if (!jinitMap)
+    {
+        OIC_LOG(ERROR, TAG, "jinitMap is null");
+        return NULL;
+    }
+
+    jobject jpropertyMap = (*env)->NewObject(env, jclazzMap, jinitMap);
+    if (!jpropertyMap)
+    {
+        OIC_LOG(ERROR, TAG, "jpropertyMap is null");
+        return NULL;
+    }
+
+    return jpropertyMap;
+}
+
+bool CAManagerCallFuncSetString(JNIEnv *env, jstring address, jobject set,
+                                CASetMethod_t method_type)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerCallFuncSetString");
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+    VERIFY_NON_NULL_RET(address, TAG, "address", false);
+    VERIFY_NON_NULL_RET(set, TAG, "set", false);
+
+    jclass jni_cls_set = (*env)->FindClass(env, "java/util/HashSet");
+    if (!jni_cls_set)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_set is null");
+        return false;
+    }
+
+    jmethodID jni_mid_setMethod = NULL;
+    switch (method_type)
+    {
+        case CM_CONTAINS:
+            OIC_LOG(DEBUG, TAG, "java/util/HashSet.contains");
+            jni_mid_setMethod = (*env)->GetMethodID(env, jni_cls_set, "contains",
+                                                    "(Ljava/lang/Object;)Z");
+            break;
+        case CM_ADD:
+            OIC_LOG(DEBUG, TAG, "java/util/HashSet.add");
+            jni_mid_setMethod = (*env)->GetMethodID(env, jni_cls_set, "add",
+                                                    "(Ljava/lang/Object;)Z");
+            break;
+        case CM_REMOVE:
+            OIC_LOG(DEBUG, TAG, "java/util/HashSet.remove");
+            jni_mid_setMethod = (*env)->GetMethodID(env, jni_cls_set, "remove",
+                                                    "(Ljava/lang/Object;)Z");
+            break;
+        default:
+            break;
+    }
+    if (!jni_mid_setMethod)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_setMethod is null");
+        return false;
+    }
+
+    jboolean res = (*env)->CallBooleanMethod(env, set, jni_mid_setMethod, address);
+    OIC_LOG_V(DEBUG, TAG, "method return result : %d", res);
+    return res;
+}
diff --git a/resource/csdk/connectivity/util/src/camanager/android/camanagerleutil.h b/resource/csdk/connectivity/util/src/camanager/android/camanagerleutil.h
new file mode 100644 (file)
index 0000000..95b648b
--- /dev/null
@@ -0,0 +1,189 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#ifndef CA_MANAGER_LE_UTILS_H_
+#define CA_MANAGER_LE_UTILS_H_
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum {
+    CM_CONTAINS = 1,
+    CM_ADD,
+    CM_REMOVE
+} CASetMethod_t;
+/**
+ * get bluetooth device object from bluetooth adapter.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   remote_address        remote address.
+ * @return  bluetooth device object.
+ */
+jobject CAManagerGetRemoteDevice(JNIEnv *env, jstring address);
+
+/**
+ * get address from gatt profile object.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   gatt                  gatt profile object.
+ * @return  LE address.
+ */
+jstring CAManagerGetAddressFromGatt(JNIEnv *env, jobject gatt);
+
+/**
+ * check whether the devie is bonded or not.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   btDevice              bluetooth device object.
+ * @return  true(bonded) or false(bond none)
+ */
+bool CAManagerIsDeviceBonded(JNIEnv *env, jobject btDevice);
+
+/**
+ * change bluetooth adapter state.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   controlFlag           true : enable(), false : disable()
+ * @return  true or false
+ */
+bool CAManagerControlAdapter(JNIEnv *env, bool controlFlag);
+
+/**
+ * request to get rssi value from bluetooth
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   bluetoothGatt         connected gatt object.
+ * @return  ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAManagerReadRemoteRssi(JNIEnv *env, jobject bluetoothGatt);
+
+/**
+ * get SharedPreference from context of application.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @param[in]   prefName              preferences name.
+ * @return  SharedPreferences object.
+ */
+jobject CAManagerGetSharedPreference(JNIEnv *env, jobject context, jstring prefName);
+
+/**
+ * check whether the device is already put or not.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @param[in]   address               LE address.
+ * @param[in]   set                   set<String> object related to connected list.
+ * @return  true or false
+ */
+bool CAManagerIsConnectedDeviceAddress(JNIEnv *env, jobject context,
+                                       jstring address, jobject set);
+
+/**
+ * get SharedPreferences.Editor object.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @return  SharedPreferences.Editor object.
+ */
+jobject CAManagerGetPrefStringSet(JNIEnv *env, jobject context);
+
+/**
+ * update SharedPreferences for set<String> object.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @param[in]   set                   set<String> object related to connected list.
+ * @return  true or false
+ */
+bool CAManagerUpdatePrefStringSet(JNIEnv *env, jobject context, jobject set);
+
+/**
+ * get SharedPreferences for set<String> object.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @return  set<String> object from SharedPreferences
+ */
+jobject CAManagerGetPrefStringSet(JNIEnv *env, jobject context);
+
+/**
+ * checks whether the preferences contains a preference.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @return  true or false
+ */
+bool CAManagerContainsPrefStringSet(JNIEnv *env, jobject context);
+
+/**
+ * add connected device into SharedPreference.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @param[in]   address               ble address.
+ * @param[in]   set                   set<String> object related to connected list.
+ * @return  true or false
+ */
+bool CAManagerAddConnectedDeviceAddress(JNIEnv *env, jobject context,
+                                        jstring address, jobject set);
+
+/**
+ * get connected device from SharedPreference.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @return  LE address of connected device.
+ */
+jobject CAManagerGetConnectedDeviceAddress(JNIEnv *env, jobject context);
+
+/**
+ * remove connected device to SharedPreference.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   context               Application context interface.
+ * @param[in]   address               LE address.
+ * @param[in]   set                   set<String> object related to connected list.
+ * @return  true or false
+ */
+bool CAManagerRemoveConnectedDeviceAddress(JNIEnv *env, jobject context,
+                                           jstring address, jobject set);
+
+/**
+ * Vaildate a String bluetooth address.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   address               LE address.
+ * @return  JNI_TRUE or JNI_FALSE
+ */
+jboolean CAManagerCheckBTAddress(JNIEnv *env, jstring address);
+
+/**
+ * create new set<String> object.
+ * @param[in]   env                   JNI interface pointer.
+ * @return  set<String> object
+ */
+jobject CAManagerCreateSetString(JNIEnv *env);
+
+/**
+ * remove connected device to SharedPreference.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   address               LE address.
+ * @param[in]   set                   set<String> object related to connected list.
+ * @param[in]   method_type           method name to get its ID.
+ * @return  true or false
+ */
+bool CAManagerCallFuncSetString(JNIEnv *env, jstring address,
+                                jobject set, CASetMethod_t method_type);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_MANAGER_LE_UTILS_H_ */
index 99a873a..311145b 100644 (file)
@@ -35,6 +35,8 @@ CAResult_t CARegisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateC
     CASetLENetworkMonitorCallbacks(adapterStateCB, connStateCB);
     return CA_STATUS_OK;
 #else
+    (void)adapterStateCB;
+    (void)connStateCB;
     return CA_NOT_SUPPORTED;
 #endif
 
@@ -47,6 +49,7 @@ CAResult_t CASetAutoConnectionDeviceInfo(const char *address)
 #ifdef LE_ADAPTER
     return CASetLEClientAutoConnectionDeviceInfo(address);
 #else
+    (void)address;
     return CA_NOT_SUPPORTED;
 #endif
 }
@@ -58,6 +61,7 @@ CAResult_t CAUnsetAutoConnectionDeviceInfo(const char *address)
 #ifdef LE_ADAPTER
     return CAUnsetLEClientAutoConnectionDeviceInfo(address);
 #else
+    (void)address;
     return CA_NOT_SUPPORTED;
 #endif
 }
@@ -73,13 +77,14 @@ CAResult_t CAUtilClientInitialize(JNIEnv *env, JavaVM *jvm, jobject context)
 {
     OIC_LOG(DEBUG, TAG, "CAUtilClientInitialize");
 #ifdef LE_ADAPTER
-
+    return CAManagerLEClientInitialize(env, jvm, context);
 #else
     OIC_LOG(DEBUG, TAG, "it is not supported");
+    (void)env;
+    (void)jvm;
+    (void)context;
     return CA_NOT_SUPPORTED;
 #endif
-
-    return CA_STATUS_OK;
 }
 
 /**
@@ -90,12 +95,11 @@ CAResult_t CAUtilClientTerminate(JNIEnv *env)
 {
     OIC_LOG(DEBUG, TAG, "CAUtilClientTerminate");
 #ifdef LE_ADAPTER
-
+    return CAManagerLEClientTerminate(env);
 #else
     OIC_LOG(DEBUG, TAG, "it is not supported");
+    (void)env;
     return CA_NOT_SUPPORTED;
 #endif
-
-    return CA_STATUS_OK;
 }
 #endif