BLE implemention for Android Platform
authorErich Keane <erich.keane@intel.com>
Mon, 4 May 2015 22:12:31 +0000 (15:12 -0700)
committerErich Keane <erich.keane@intel.com>
Mon, 4 May 2015 23:06:24 +0000 (23:06 +0000)
it had been modified by fragmentation logic applied.

Change-Id: Ic3687fc016f2e28671a1d3962992d66481244288
Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
Signed-off-by: Erich Keane <erich.keane@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/753
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
16 files changed:
resource/csdk/connectivity/inc/calecore.h [deleted file]
resource/csdk/connectivity/inc/caleserver.h [deleted file]
resource/csdk/connectivity/inc/caleutils.h [deleted file]
resource/csdk/connectivity/src/bt_le_adapter/SConscript
resource/csdk/connectivity/src/bt_le_adapter/android/caleadapter.c [deleted file]
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/calenwmonitor.c
resource/csdk/connectivity/src/bt_le_adapter/android/calenwmonitor.h [moved from resource/csdk/connectivity/inc/calenwmonitor.h with 59% similarity]
resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/com_iotivity_jar_caleinterface.h [deleted file]
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleclientinterface.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleserverinterface.h [new file with mode: 0644]

diff --git a/resource/csdk/connectivity/inc/calecore.h b/resource/csdk/connectivity/inc/calecore.h
deleted file mode 100644 (file)
index f3c2cdf..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-/* ****************************************************************
- *
- * Copyright 2014 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.
- *
- ******************************************************************/
-
-/**
- * @file
- *
- * This file contains the APIs for BT LE communications.
- */
-
-#ifndef __CA_LECORE_H_
-#define __CA_LECORE_H_
-
-#include "cacommon.h"
-#include "cathreadpool.h"
-#include "jni.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief Callback to be notified on reception of any data from remote devices.
- * @param  address          [IN] MAC address of remote device.
- * @param  data             [IN] Data received from remote device.
- * @return NONE
- * @pre  Callback must be registered using CALESetCallback(CAPacketReceiveCallback callback)
- */
-typedef void (*CAPacketReceiveCallback)(const char *address, const char *data);
-
-/**
- * @brief   set context of application
- * @param   env              [IN] JNI interface pointer
- * @param   context          [IN] context of application
- * @return  None
- */
-void CALEClientJNISetContext(JNIEnv *env, jobject context);
-
-/**
- * @brief   create interface object and initialize the object
- * @return  None
- */
-void CALeCreateJniInterfaceObject();
-
-/**
- * @brief   initialize client for BLE
- * @param   handle           [IN] thread pool handle object
- * @return  None
- */
-void CALEInitialize(ca_thread_pool_t handle);
-
-/**
- * @brief   terminate client for BLE
- * @return  None
- */
-void CALETerminate();
-
-/**
- * @brief   for destroy sending routine
- * @param   env              [IN] JNI interface pointer
- * @param   gatt             [IN] Gatt profile object
- * @return  None
- */
-void CANativeSendFinish(JNIEnv *env, jobject gatt);
-
-/**
- * @brief   send data for unicast (interface)
- * @param   address          [IN] remote address
- * @param   data             [IN] data for transmission
- * @param   dataLen          [IN] data length
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALESendUnicastMessage(const char *address, const char *data, const uint32_t dataLen);
-
-/**
- * @brief   send data for multicast (interface)
- * @param   data             [IN] data for transmission
- * @param   dataLen          [IN] data length
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALESendMulticastMessage(const char *data, const uint32_t dataLen);
-
-/**
- * @brief   start unicast server
- * @param   address          [IN] remote address
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEStartUnicastServer(const char *address);
-
-/**
- * @brief   start multicast server (start discovery)
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEStartMulticastServer();
-
-/**
- * @brief   stop unicast server
- * @return  None
- */
-void CALEStopUnicastServer();
-
-/**
- * @brief   stop multicast server (stop discovery)
- * @return  None
- */
-void CALEStopMulticastServer();
-
-/**
- * @brief   set this callback for receiving data packets from peer devices.
- * @param   callback         [IN] callback to be notified on reception of
- *                                unicast/multicast data packets.
- * @return  None
- */
-void CALESetCallback(CAPacketReceiveCallback callback);
-
-/**
- * @brief   get local address (interface)
- * @param   address          [OUT] local address
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEGetInterfaceInfo(char **address);
-
-/**
- * @brief   get local address (inplement)
- * @param   address          [OUT] local address
- * @return  None
- */
-void CALEGetLocalAddress(char** address);
-
-/**
- * @brief   send data for unicast (implement)
- * @param   address          [IN] remote address
- * @param   data             [IN] data for transmission
- * @param   dataLen          [IN] data length
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALESendUnicastMessageImpl(const char *address, const char *data, const uint32_t dataLen);
-
-/**
- * @brief   send data for multicast (implement)
- * @param   address          [IN] remote address
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALESendMulticastMessageImpl(const char *data, const uint32_t dataLen);
-
-/**
- * BT Common Method : JNI
- */
-/**
- * @brief   get address from bluetooth gatt object
- * @param   env              [IN] JNI interface pointer
- * @param   gatt             [IN] Gatt profile object
- * @return  bluetooth address
- */
-jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt);
-
-/**
- * @brief   get remote address from bluetooth socket object
- * @param   env                   [IN] JNI interface pointer
- * @param   bluetoothSocketObj    [IN] bluetooth socket
- * @return  bluetooth address
- */
-jstring CANativeGetRemoteAddress(JNIEnv *env, jobject bluetoothSocketObj);
-
-/**
- * @brief   close gatt
- * @param   env                   [IN] JNI interface pointer
- * @param   bluetoothGatt         [IN] Gatt profile object
- * @return  None
- */
-void CANativeGattClose(JNIEnv *env, jobject bluetoothGatt);
-
-/**
- * @brief   start to scan whole bluetooth devices (interface)
- * @return  None
- */
-void CANativeLEStartScan();
-
-/**
- * @brief   start to scan whole bluetooth devices (implement)
- * @param   env              [IN] JNI interface pointer
- * @param   callback         [IN] callback to receive device object by scanning
- * @return  None
- */
-void CANativeLEStartScanImpl(JNIEnv *env, jobject callback);
-
-/**
- * @brief   start to scan target bluetooth devices for service uuid (implement)
- * @param   env              [IN] JNI interface pointer
- * @param   uuids            [IN] target UUID
- * @param   callback         [IN] callback to receive device object by scanning
- * @return  None
- */
-void CANativeLEStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback);
-
-/**
- * @brief   get uuid object
- * @param   env              [IN] JNI interface pointer
- * @param   uuid             [IN] uuid
- * @return  uuid object
- */
-jobject CANativeGetUUIDObject(JNIEnv *env, const char *uuid);
-
-/**
- * @brief   stop scan (interface)
- * @return  None
- */
-void CANativeLEStopScan();
-
-/**
- * @brief   stop scan (implement)
- * @param   env              [IN] JNI interface pointer
- * @param   callback         [IN] callback to receive device object by scanning
- * @return  None
- */
-void CANativeLEStopScanImpl(JNIEnv *env, jobject callback);
-
-/**
- * @brief   connect to gatt server hosted
- * @param   env              [IN] JNI interface pointer
- * @param   bluetoothDevice  [IN] bluetooth Device object
- * @param   context          [IN] context of application
- * @param   autoconnect      [IN] whether to directly connect to the remote device(false) or
- *                                to automatically connect as soon as the remote device
- *                                becomes available
- * @param   callback         [IN] callback for connection state change
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context,
-                          jboolean autoconnect, jobject callback);
-
-/**
- * @brief   disconnect to gatt server by a target device
- * @param   env              [IN] JNI interface pointer
- * @param   bluetoothGatt    [IN] Gatt profile object
- * @return  None
- */
-void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt);
-
-/**
- * @brief   disconnect to gatt server by whole devices
- * @param   env              [IN] JNI interface pointer
- * @return  None
- */
-void CANativeLEDisconnectAll(JNIEnv *env);
-
-/**
- * @brief   start discovery server
- * @param   env              [IN] JNI interface pointer
- * @param   bluetoothGatt    [IN] Gatt profile object
- * @return  None
- */
-void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt);
-
-/**
- * @brief   request to write gatt characteristic
- * @param   env                   [IN] JNI interface pointer
- * @param   bluetoothGatt         [IN] Gatt profile object
- * @param   gattCharacteristic    [IN] characteristic object that contain data to send
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CANativeWriteCharacteristic(JNIEnv *env, jobject bluetoothGatt, jobject gattCharacteristic);
-
-/**
- * @brief   request to read gatt characteristic
- * @param   env                   [IN] JNI interface pointer
- * @param   bluetoothGatt         [IN] Gatt profile object
- * @return  None
- */
-void CANativeReadCharacteristic(JNIEnv *env, jobject bluetoothGatt);
-
-/**
- * @brief   enable notification for a target device
- * @param   env                   [IN] JNI interface pointer
- * @param   bluetoothGatt         [IN] Gatt profile object
- * @param   uuid                  [IN] for set BluetoothGattCharacteristic object
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_ADAPTER_NOT_ENABLED Adapter is not enabled
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CANativeSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
-                                                 const char* uuid);
-
-/**
- * @brief   create gatt characteristic object
- * @param   env                   [IN] JNI interface pointer
- * @param   bluetoothGatt         [IN] Gatt profile object
- * @param   data                  [IN] for make Characteristic with data
- * @return  Gatt Characteristic object
- */
-jobject CANativeCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data);
-
-/**
- * @brief   get gatt service
- * @param   env                   [IN] JNI interface pointer
- * @param   bluetoothGatt         [IN] Gatt profile object
- * @param   characterUUID         [IN] for make BluetoothGattCharacteristic object
- * @return  Gatt Service
- */
-jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID);
-
-/**
- * @brief   get value from characteristic
- * @param   env                   [IN] JNI interface pointer
- * @param   characteristic        [IN] Characteristic object
- * @return  value in characteristic
- */
-jbyteArray CANativeGetValueFromCharacteristic(JNIEnv *env, jobject characteristic);
-
-/**
- * @brief   create UUID List
- * @return  None
- */
-void CANativeCreateUUIDList();
-
-/**
- * BluetoothDevice List
- */
-/**
- * @brief   create scan device list
- * @param   env                   [IN] JNI interface pointer
- * @return  None
- */
-void CANativeCreateScanDeviceList(JNIEnv *env);
-
-/**
- * @brief   add device object to scan device list
- * @param   env                   [IN] JNI interface pointer
- * @param   device                [IN] bluetooth device object
- * @return  None
- */
-void CANativeAddScanDeviceToList(JNIEnv *env, jobject device);
-
-/**
- * @brief   check whether the device exist in list or not
- * @param   env                   [IN] JNI interface pointer
- * @param   remoteAddress         [IN] remote address
- * @return  TRUE or FALSE
- */
-jboolean CANativeIsDeviceInList(JNIEnv *env, const char *remoteAddress);
-
-/**
- * @brief   remove all devices in scan device list
- * @param   env                   [IN] JNI interface pointer
- * @return  None
- */
-void CANativeRemoveAllDevices(JNIEnv *env);
-
-/**
- * @brief   remove target device in scan device list
- * @param   env                   [IN] JNI interface pointer
- * @param   remoteAddress         [IN] remote address
- * @return  None
- */
-void CANativeRemoveDevice(JNIEnv *env, jstring remoteAddress);
-
-/**
- * @brief   Reordering for scan device list
- * @param   index                 [IN] index of device list that want to reordering
- * @return  None
- */
-void CAReorderingDeviceList(uint32_t index);
-
-/**
- * BluetoothGatt List
- */
-/**
- * @brief   create gatt object list
- * @param   env                   [IN] JNI interface pointer
- * @return  None
- */
-void CANativeCreateGattObjList(JNIEnv *env);
-
-/**
- * @brief   add gatt object to gatt object list
- * @param   env                   [IN] JNI interface pointer
- * @param   gatt                  [IN] Gatt profile object
- * @return  None
- */
-void CANativeAddGattobjToList(JNIEnv *env, jobject gatt);
-
-/**
- * @brief   check whether the gatt object exist in list or not
- * @param   env                   [IN] JNI interface pointer
- * @param   remoteAddress         [IN] remote address
- * @return  TRUE or FALSE
- */
-jboolean CANativeIsGattObjInList(JNIEnv *env, const char *remoteAddress);
-
-/**
- * @brief   remove all gatt objects in gatt object list
- * @param   env                   [IN] JNI interface pointer
- * @return  None
- */
-void CANativeRemoveAllGattObjsList(JNIEnv *env);
-
-/**
- * @brief   remove target device in gatt object list
- * @param   env                   [IN] JNI interface pointer
- * @param   gatt                  [IN] Gatt profile object
- * @return  None
- */
-void CANativeRemoveGattObj(JNIEnv *env, jobject gatt);
-
-/**
- * @brief   Reordering for gatt object list
- * @param   index                 [IN] index of device list that want to reordering
- * @return  None
- */
-void CAReorderingGattList(uint32_t index);
-
-/**
- * @brief   check whether target device which send data is exist or not
- * @param   env                   [IN] JNI interface pointer
- * @return  None
- */
-void CANativeupdateSendCnt(JNIEnv *env);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
-
diff --git a/resource/csdk/connectivity/inc/caleserver.h b/resource/csdk/connectivity/inc/caleserver.h
deleted file mode 100644 (file)
index 3d4885b..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/* ****************************************************************
-*
-* Copyright 2014 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.
-*
-******************************************************************/
-
-/**
- * @file
- *
- * This file contains the APIs for BT LE communications.
- */
-
-#ifndef __CA_LESERVER_H_
-#define __CA_LESERVER_H_
-
-#include "cacommon.h"
-#include "cathreadpool.h"
-#include "uarraylist.h"
-#include "jni.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief Callback to be notified on reception of any data from remote devices.
- * @param  address          [IN] MAC address of remote device.
- * @param  data             [IN] Data received from remote device.
- * @return None
- * @pre  Callback must be registered using CALEServerSetCallback(CAPacketReceiveCallback callback)
- */
-typedef void (*CAPacketReceiveCallback)(const char *address,
-        const char *data);
-
-/**
- * @brief   initialize server for BLE
- * @param   handle           [IN] thread pool handle object
- * @return  None
- */
-void CALEServerInitialize(ca_thread_pool_t handle);
-
-/**
- * @brief   terminate client for BLE
- * @return  None
- */
-void CALEServerTerminate();
-
-/**
- * @brief   send data for unicast (interface)
- * @param   address          [IN] remote address
- * @param   data             [IN] data for transmission
- * @param   dataLen          [IN] data length
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEServerSendUnicastMessage(const char *address, const char *data,
-        uint32_t dataLen);
-
-/**
- * @brief   send data for multicast (interface)
- * @param   data             [IN] data for transmission
- * @param   dataLen          [IN] data length
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEServerSendMulticastMessage(const char *data, uint32_t dataLen);
-
-/**
- * @brief   start unicast server
- * @param   address          [IN] remote address
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEServerStartUnicastServer(const char *address);
-
-/**
- * @brief   start multicast server (start advertise)
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEServerStartMulticastServer();
-
-/**
- * @brief   stop unicast server
- * @return  None
- */
-CAResult_t CALEServerStopUnicastServer();
-
-/**
- * @brief   stop multicast server (stop discovery)
- * @return  None
- */
-CAResult_t CALEServerStopMulticastServer();
-
-/**
- * @brief   set this callback for receiving data packets from peer devices.
- * @param   callback         [IN] callback to be notified on reception of
- *                                unicast/multicast data packets.
- * @return  None
- */
-void CALEServerSetCallback(CAPacketReceiveCallback callback);
-
-/**
- * @brief  Get local adapter network information.
- * @param  info              [OUT] local connectivity information
- * @param  size              [OUT] connectivity count
- * @return  None
- */
-void CALEServerGetInterfaceInfo(CALocalConnectivity_t **info,
-        uint32_t *size);
-
-/**
- * @brief   get local address
- * @param   address          [OUT] local address
- * @return  None
- */
-void CALEServerGetLocalAddress(char *address);
-
-/**
- * @brief   send data for unicast (implement)
- * @param   env              [IN] JNI interface pointer
- * @param   address          [IN] remote address
- * @param   data             [IN] data for transmission
- * @param   dataLen          [IN] data length
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char *address,
-        const char *data, uint32_t dataLen);
-
-/**
- * @brief   send data for multicast (implement)
- * @param   env              [IN] JNI interface pointer
- * @param   address          [IN] remote address
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char *data,
-        uint32_t dataLen);
-
-/* Android BLE Server Functions */
-/**
- * @brief   set context of application
- * @param   env              [IN] JNI interface pointer
- * @param   context          [IN] context of application
- * @return  None
- */
-void CALEServerJNISetContext(JNIEnv *env, jobject context);
-
-/**
- * @brief   initialize JNI object
- * @param   env              [IN] JNI interface pointer
- * @param   jvm              [IN] java virtual machine pointer
- * @return  None
- */
-void CALeServerJniInit(JNIEnv *env, JavaVM* jvm);
-
-/**
- * @brief   create interface object and initialize the object
- * @return  None
- */
-void CALeServerCreateJniInterfaceObject();
-
-/**
- * @brief   start advertise in gatt server
- * @param   env                [IN] JNI interface pointer
- * @param   advertiseCallback  [IN] callback to be notified on reception of
- *                                advertisement result
- * @return  None
- */
-void CANativeLEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback);
-
-/**
- * @brief   stop advertise in gatt server
- * @param   env                [IN] JNI interface pointer
- * @param   advertiseCallback  [IN] callback to be notified on reception of
- *                                advertisement result
- * @return  None
- */
-void CANativeLEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback);
-
-/**
- * @brief   open a gatt server
- * @param   env                [IN] JNI interface pointer
- * @return  gatt server object
- */
-jobject CANativeLEServerOpenGattServer(JNIEnv *env);
-
-/**
- * @brief   create gatt service
- * @param   env                [IN] JNI interface pointer
- * @return  gatt service object
- */
-jobject CANativeLEServerCreateGattService(JNIEnv *env);
-
-/**
- * @brief   create gatt service
- * @param   env                [IN] JNI interface pointer
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_ADAPTER_NOT_ENABLED Adapter is not enabled
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CANativeLEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
-        jobject bluetoothGattService);
-
-/**
- * @brief   start gatt server
- * @param   env                  [IN] JNI interface pointer
- * @param   gattServerCallback   [IN] callback to be notified on reception of
- *                                state change of gatt server
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_ADAPTER_NOT_ENABLED Adapter is not enabled
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEStartGattServer(JNIEnv *env, jobject gattServerCallback);
-
-/**
- * @brief   send data
- * @param   env                  [IN] JNI interface pointer
- * @param   bluetoothDevice      [IN] bluetooth device object
- * @param   data                 [IN] data which send
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_SEND_FAILED  Send request failed
- * @retval  #CA_ADAPTER_NOT_ENABLED Adapter is not enabled
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jstring data);
-
-/**
- * @brief   set data in BluetoothGattCharacteristic
- * @param   env                  [IN] JNI interface pointer
- * @param   bluetoothDevice      [IN] bluetooth device object
- * @return  BluetoothGattCharacteristic object
- */
-jobject CANativeLEServerSetResponseData(JNIEnv *env, jbyteArray responseData);
-
-/**
- * @brief   send data through notifyCharacteristicChanged api of android
- * @param   env                  [IN] JNI interface pointer
- * @param   bluetoothDevice      [IN] bluetooth device object
- * @param   data                 [IN] data which send
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_SEND_FAILED  Send request failed
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CANativeLEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData);
-
-/**
- * @brief   send a response to a write request to a remote device
- * @param   env                  [IN] JNI interface pointer
- * @param   device               [IN] bluetooth device object
- * @param   requestId            [IN] the id of request
- * @param   status               [IN] the status of the request to be sent to the remote devices
- * @param   offset               [IN] value offset for partial write response
- * @param   value                [IN] the value of the attribute that written (optional)
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_SEND_FAILED  Send request failed
- * @retval  #CA_ADAPTER_NOT_ENABLED Adapter is not enabled
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CANativeLEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
-        jint offset, jbyteArray value);
-
-/**
- * @brief   connect BLE to remote device form gatt server
- * @param   env                  [IN] JNI interface pointer
- * @param   bluetoothDevice      [IN] bluetooth device object
- * @return  #CA_STATUS_OK or Appropriate error code
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_ADAPTER_NOT_ENABLED Adapter is not enabled
- * @retval  #CA_STATUS_FAILED Operation failed
- */
-CAResult_t CANativeLEServerConnect(JNIEnv *env, jobject bluetoothDevice);
-
-/**
- * @brief   disconnect BLE to remote device form gatt server
- * @param   env                  [IN] JNI interface pointer
- * @param   bluetoothDevice      [IN] bluetooth device object
- * @return  None
- */
-void CANativeLEServerDisconnect(JNIEnv *env, jobject bluetoothDevice);
-
-/* BLE Server Utils */
-/**
- * @brief   create connected device list
- * @return  None
- */
-void CALEServerCreateCachedDeviceList();
-
-/**
- * @brief   check whether the device exist in the list or not
- * @param   env                   [IN] JNI interface pointer
- * @param   remoteAddress         [IN] remote address
- * @return  TRUE or FALSE
- */
-jboolean CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress);
-
-/**
- * @brief   add device object to the list (connected device list)
- * @param   env                   [IN] JNI interface pointer
- * @param   device                [IN] bluetooth device object
- * @return  None
- */
-void CALEServerAddDeviceToList(JNIEnv *env, jobject device);
-
-/**
- * @brief   remove all devices objects in the list (connected device list)
- * @param   env                   [IN] JNI interface pointer
- * @return  None
- */
-void CALEServerRemoveAllDevices(JNIEnv *env);
-
-/**
- * @brief   remove target device in the list (connected device list)
- * @param   env                   [IN] JNI interface pointer
- * @param   gatt                  [IN] Gatt profile object
- * @return  None
- */
-void CALEServerRemoveDevice(JNIEnv *env, jstring address);
-
-/**
- * @brief   Reordering for the list (connected device list)
- * @param   index                 [IN] index of device list that want to reordering
- * @return  None
- */
-void CALEServerReorderinglist(uint32_t index);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* __CA_LESERVER_H_ */
-
diff --git a/resource/csdk/connectivity/inc/caleutils.h b/resource/csdk/connectivity/inc/caleutils.h
deleted file mode 100644 (file)
index dc9a92f..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ****************************************************************
-*
-* Copyright 2014 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.
-*
-******************************************************************/
-
-/**
- * @file
- *
- * This file contains the APIs for BT LE communications.
- */
-
-#ifndef __CA_LEUTILES_H_
-#define __CA_LEUTILES_H_
-
-#include "cacommon.h"
-#include "cathreadpool.h"
-#include "uarraylist.h"
-#include "jni.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief   get uuid(jni object) from uuid(character)
- * @param   env              [IN] JNI interface pointer
- * @param   uuid             [IN] uuid(character)
- * @return  uuid(jni object)
- */
-jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid);
-
-/**
- * @brief   get parcel uuid object
- * @param   env              [IN] JNI interface pointer
- * @param   uuid             [IN] uuid (jni object)
- * @return  parcel uuid object
- */
-jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid);
-
-/**
- * @brief   get address from a local device
- * @param   env              [IN] JNI interface pointer
- * @return  local address
- */
-jstring CALEGetLocalDeviceAddress(JNIEnv *env);
-
-/**
- * @brief   get bonded list
- * @param   env              [IN] JNI interface pointer
- * @return  bonded list
- */
-jobjectArray CALEGetBondedDevices(JNIEnv *env);
-
-/**
- * @brief   get constants information of bluetooth state-on
- * @param   env              [IN] JNI interface pointer
- * @return  constants information of bluetooth state-on
- */
-jint CALEGetBTStateOnInfo(JNIEnv *env);
-
-/**
- * @brief   get bluetooth adapter state information
- * @param   env              [IN] JNI interface pointer
- * @return  true if the local adapter is turned on
- */
-jboolean CALEIsEnableBTAdapter(JNIEnv *env);
-
-/**
- * @brief   get address from remote device
- * @param   env              [IN] JNI interface pointer
- * @param   bluetoothDevice  [IN] bluetooth device object
- * @return  remote address
- */
-jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
-
index bddb6f7..62707b7 100644 (file)
@@ -18,7 +18,7 @@ if target_os != 'arduino':
        env.AppendUnique(CA_SRC=[src_dir+'caleadapter.c'])
 else:
        env.AppendUnique(CA_SRC=[src_dir+'caleadapter_singlethread.c'])
-       
+
 #Source files to build in Linux platform
 if target_os == 'linux':
        env.AppendUnique(CA_SRC=[src_dir+'linux/caleadapter.c',
@@ -44,7 +44,10 @@ if target_os == 'arduino':
 
 #Source files to build in Android platform
 if target_os == 'android':
-       env.AppendUnique(CA_SRC=[src_dir+'android/caleadapter.c',
+       env.PrependUnique(CPPPATH = [src_dir + 'android'])
+       env.AppendUnique(CA_SRC=[
                        src_dir+'android/caleclient.c',
                        src_dir+'android/caleserver.c',
+                       src_dir+'android/calenwmonitor.c',
+                       src_dir+'android/caleutils.c'
                        ])
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleadapter.c b/resource/csdk/connectivity/src/bt_le_adapter/android/caleadapter.c
deleted file mode 100644 (file)
index 4a3abec..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/******************************************************************
- *
- * Copyright 2014 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "jni.h"
-#include "caleadapter.h"
-#include "calecore.h"
-#include "caleserver.h"
-#include "calenwmonitor.h"
-#include "logger.h"
-#include "caadapterutils.h"
-#include "oic_malloc.h"
-
-#define TAG PCF("CA_LE_ADAPTER")
-
-// GATT server type
-static jboolean g_isBluetoothGattServer;
-
-// received packet callback
-static CANetworkPacketReceivedCallback gLEReceivedCallback = NULL;
-static CANetworkChangeCallback gLENetworkChangeCallback = NULL;
-
-static void CALEPacketReceiveCallback(const char* address, const char* data)
-{
-    OIC_LOG_V(DEBUG, TAG,
-            "CALEPacketReceiveCallback, from: %s, data: %s", address, data);
-
-    // call the callback
-    if (gLEReceivedCallback != NULL)
-    {
-        CARemoteEndpoint_t* endpoint = NULL;
-        endpoint = (CARemoteEndpoint_t*) OICMalloc(sizeof(CARemoteEndpoint_t));
-
-        if (endpoint == NULL)
-        {
-            OIC_LOG(DEBUG, TAG, "CALEPacketReceiveCallback, Memory allocation failed !");
-            return;
-        }
-
-        // set address
-        memset((void*) endpoint->addressInfo.BT.btMacAddress, 0, CA_MACADDR_SIZE);
-        if (CA_MACADDR_SIZE > strlen(address))
-        {
-            strcpy((char*) endpoint->addressInfo.BT.btMacAddress, address);
-        }
-
-        // set connectivity type
-        endpoint->connectivityType = CA_LE;
-
-        gLEReceivedCallback(endpoint, (void *) data, strlen(data));
-    }
-}
-
-static void CALENetStateChangeCallback(const char* address, const uint32_t status)
-{
-    OIC_LOG_V(DEBUG, TAG,
-            "CALENetStateChangeCallback, status:%d", status);
-
-    // call the callback
-    if (gLENetworkChangeCallback != NULL)
-    {
-        CANetworkStatus_t netStatus = CA_INTERFACE_DOWN;
-        if (status == 12)
-        {
-            netStatus = CA_INTERFACE_UP;
-        }
-        else if (status == 10)
-        {
-            netStatus = CA_INTERFACE_DOWN;
-        }
-
-        CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_LE, address);
-        if (!localEndpoint)
-        {
-            OIC_LOG(ERROR, TAG, "Out of memory");
-            return;
-        }
-
-        gLENetworkChangeCallback(localEndpoint, netStatus);
-
-        CAAdapterFreeLocalEndpoint(localEndpoint);
-
-    }
-}
-
-CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
-                          CANetworkPacketReceivedCallback reqRespCallback,
-                          CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, TAG, "IntializeBLE");
-
-    gLEReceivedCallback = reqRespCallback;
-    gLENetworkChangeCallback = netCallback;
-
-    // register handlers
-    CAConnectivityHandler_t handler;
-    memset(&handler, 0, sizeof(CAConnectivityHandler_t));
-
-    handler.startAdapter = CAStartLE;
-    handler.startListenServer = CAStartLEListeningServer;
-    handler.startDiscoveryServer = CAStartLEDiscoveryServer;
-    handler.sendData = CASendLEUnicastData;
-    handler.sendDataToAll = CASendLEMulticastData;
-    handler.GetnetInfo = CAGetLEInterfaceInformation;
-    handler.readData = CAReadLEData;
-    handler.stopAdapter = CAStopLE;
-    handler.terminate = CATerminateLE;
-    registerCallback(handler, CA_LE);
-
-    CALEInitialize(handle);
-    CALEServerInitialize(handle);
-
-    CALESetCallback(CALEPacketReceiveCallback);
-    CALESetNetStateCallback(CALENetStateChangeCallback);
-    CALEServerSetCallback(CALEPacketReceiveCallback);
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartLE()
-{
-    OIC_LOG(DEBUG, TAG, "CAStartLE");
-    //CANativeLEStartScan();
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartLEListeningServer()
-{
-    OIC_LOG(DEBUG, TAG, "CAStartLEListeningServer");
-
-    g_isBluetoothGattServer = JNI_TRUE;
-
-    // start gatt service
-    CALEServerStartMulticastServer();
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartLEDiscoveryServer()
-{
-    OIC_LOG(DEBUG, TAG, "CAStartLEDiscoveryServer");
-
-    g_isBluetoothGattServer = JNI_FALSE;
-
-    // start scan through gatt client
-    CALEStartMulticastServer();
-
-    return CA_STATUS_OK;
-}
-
-int32_t CASendLEUnicastData(const CARemoteEndpoint_t* endpoint, const void* data, uint32_t dataLen)
-{
-
-    if (g_isBluetoothGattServer == JNI_FALSE)
-    {
-        OIC_LOG(DEBUG, TAG, "CALESendUnicastData");
-        CALESendUnicastMessage(endpoint->addressInfo.BT.btMacAddress, data, dataLen);
-    }
-    else
-    {
-        OIC_LOG(DEBUG, TAG, "CALEServerSendUnicastData");
-        CALEServerSendUnicastMessage(endpoint->addressInfo.BT.btMacAddress, data, dataLen);
-    }
-
-    return dataLen;
-}
-
-int32_t CASendLEMulticastData(const void* data, uint32_t dataLen)
-{
-    if (g_isBluetoothGattServer == JNI_FALSE)
-    {
-        OIC_LOG(DEBUG, TAG, "CASendLEMulticastData");
-        CALESendMulticastMessage(data, dataLen);
-    }
-    else
-    {
-        OIC_LOG(DEBUG, TAG, "CALEServerSendMulticastMessage");
-        CALEServerSendMulticastMessage(data, dataLen);
-    }
-
-    return dataLen;
-}
-
-CAResult_t CAStartLENotifyServer()
-{
-    OIC_LOG(DEBUG, TAG, "CAStartLENotifyServer");
-
-    return CA_STATUS_OK;
-}
-
-uint32_t CASendLENotification(const CARemoteEndpoint_t* endpoint, const void* data,
-                              uint32_t dataLen)
-{
-    if (g_isBluetoothGattServer == JNI_FALSE)
-    {
-        OIC_LOG(DEBUG, TAG, "not server mode");
-        return -1;
-    }
-    else
-    {
-        OIC_LOG(DEBUG, TAG, "CALEServerSendLEUnicastData");
-        CALEServerSendUnicastMessage(endpoint->addressInfo.BT.btMacAddress, data, dataLen);
-    }
-
-    return 0;
-}
-
-CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t** info, uint32_t* size)
-{
-    OIC_LOG(DEBUG, TAG, "CAGetLEInterfaceInformation");
-
-    CALocalConnectivity_t *netInfo = NULL;
-
-    int32_t netInfoSize = 1;
-
-    netInfo = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t) * netInfoSize);
-    if (NULL == netInfo)
-    {
-        OIC_LOG(ERROR, TAG, "Invalid input..");
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-    memset(netInfo, 0, sizeof(CALocalConnectivity_t) * netInfoSize);
-
-    char *macAddress = NULL;
-    CAResult_t ret = CALEGetInterfaceInfo(&macAddress);
-    OIC_LOG_V(ERROR, TAG, "address : %s", macAddress);
-    if (CA_STATUS_OK != ret || NULL == macAddress)
-    {
-        OIC_LOG_V(ERROR, TAG, "Failed to get interface info [%d]", ret);
-
-        OICFree(netInfo);
-        OICFree(macAddress);
-        return ret;
-    }
-
-    // Create local endpoint using util function
-    CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_LE, macAddress);
-    if (NULL == endpoint)
-    {
-        OIC_LOG_V(ERROR, TAG, "Failed to create Local Endpoint!",
-                CA_MEMORY_ALLOC_FAILED);
-        OICFree(netInfo);
-        OICFree(macAddress);
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    // copy unciast server information
-    endpoint->isSecured = false;
-    memcpy(&netInfo[0], endpoint, sizeof(CALocalConnectivity_t));
-    *size = 1;
-    *info = netInfo;
-
-    OICFree(macAddress);
-    CAAdapterFreeLocalEndpoint(endpoint);
-
-    OIC_LOG(INFO, TAG, "GetLEInterfaceInformation success");
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAReadLEData()
-{
-    OIC_LOG(DEBUG, TAG, "Read LE Data");
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStopLE()
-{
-
-    if (g_isBluetoothGattServer == JNI_FALSE)
-    {
-        OIC_LOG(DEBUG, TAG, "CA Stop LE Scan");
-        CANativeLEStopScan();
-    }
-    else
-    {
-        OIC_LOG(DEBUG, TAG, "CA Stop Gatt Server");
-    }
-
-    return CA_STATUS_OK;
-}
-
-void CATerminateLE()
-{
-    if (g_isBluetoothGattServer == JNI_FALSE)
-    {
-        OIC_LOG(DEBUG, TAG, "Terminat Gatt Client");
-        CALETerminate();
-    }
-    else
-    {
-        OIC_LOG(DEBUG, TAG, "Terminat Gatt Server");
-        CALEServerTerminate();
-    }
-}
index 4e23a99..06c1c05 100644 (file)
 #include <jni.h>
 #include <unistd.h>
 
-#include "calecore.h"
+#include "caleclient.h"
 #include "caleserver.h"
 #include "caleutils.h"
+#include "caleinterface.h"
+#include "caadapterutils.h"
 
 #include "logger.h"
 #include "oic_malloc.h"
 #include "cathreadpool.h" /* for thread pool */
 #include "camutex.h"
 #include "uarraylist.h"
-#include "com_iotivity_jar_caleinterface.h"
+#include "org_iotivity_jar_caleclientinterface.h"
 
-//#define DEBUG_MODE
 #define TAG PCF("CA_LE_CLIENT")
 
 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
-static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;";
-static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
+static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
 
-static const char IOTIVITY_GATT_SERVIE_UUID[] = "713d0000-503e-4c75-ba94-3148f18d941e";
-static const char IOTIVITY_GATT_TX_UUID[] = "713d0003-503e-4c75-ba94-3148f18d941e";
-static const char IOTIVITY_GATT_RX_UUID[] = "713d0002-503e-4c75-ba94-3148f18d941e";
-
-static const uint32_t STATE_CONNECTED = 2;
-static const uint32_t STATE_DISCONNECTED = 0;
-static const uint32_t GATT_SUCCESS = 0;
-
-static const size_t MAX_PDU_BUFFER = 1400;
-
 JavaVM *g_jvm;
-static u_arraylist_t *g_deviceList = NULL;
+static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
 static u_arraylist_t *g_gattObjectList = NULL;
+static u_arraylist_t *g_deviceStateList = NULL;
+
 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
 static ca_thread_pool_t g_threadPoolHandle = NULL;
-static jobject g_leScanCallback;
-static jobject g_leGattCallback;
-static jobject g_context;
-static jobjectArray g_UUIDList;
-static jboolean g_isStartServer;
-static jboolean g_isFinishSendData;
-
-static jbyteArray g_sendBuffer;
+static jobject g_leScanCallback = NULL;
+static jobject g_leGattCallback = NULL;
+static jobject g_context = NULL;
+static jobjectArray g_uuidList = NULL;
+
+// it will be prevent to start send logic when adapter has stopped.
+static bool g_isStartedLEClient = false;
+static bool g_isStartedMulticastServer = false;
+static bool g_isStartedScan = false;
+
+static jbyteArray g_sendBuffer = NULL;
 static uint32_t g_targetCnt = 0;
 static uint32_t g_currentSentCnt = 0;
+static bool g_isFinishedSendData = false;
+static ca_mutex g_SendFinishMutex = false;
+static ca_mutex g_threadMutex = NULL;
+static ca_cond g_threadCond = NULL;
+
+static bool g_isRequestedSend = false;
+static bool g_isReceivedWriteCB = false;
+static ca_mutex g_writeCharacteristicCBMutex = false;
+static ca_mutex g_theSendRequestMutex = false;
+static ca_mutex g_threadSendCBMutex = NULL;
+static ca_cond g_threadSendCBCond = NULL;
+
+static ca_mutex g_threadSendMutex = NULL;
+static ca_cond g_threadSendCond = NULL;
 
-/** mutex for synchrnoization **/
-static ca_mutex g_threadMutex;
-/** conditional mutex for synchrnoization **/
-static ca_cond g_threadCond;
+static ca_mutex g_bleReqRespClientCbMutex = NULL;
+static ca_mutex g_bleServerBDAddressMutex = NULL;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-//FIXME getting context
-void CALEClientJNISetContext(JNIEnv *env, jobject context)
+static ca_mutex g_deviceListMutex = NULL;
+static ca_mutex g_gattObjectMutex = NULL;
+static ca_mutex g_deviceStateListMutex = NULL;
+
+static CABLEClientDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
+
+//getting jvm
+void CALEClientJniInit()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
+    g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
+}
+
+void CALEClientJNISetContext()
 {
     OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
+    g_context = (jobject) CANativeJNIGetContext();
+}
+
+CAResult_t CALECreateJniInterfaceObject()
+{
+    OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
 
-    if (context == NULL)
+    if (!g_context)
     {
-        OIC_LOG(ERROR, TAG, "context is null");
-        return;
+        OIC_LOG(ERROR, TAG, "g_context is null");
+        return CA_STATUS_FAILED;
     }
 
-    g_context = (*env)->NewGlobalRef(env, context);
-}
-
-void CALeCreateJniInterfaceObject()
-{
-    OIC_LOG(DEBUG, TAG, "CALeCreateJniInterfaceObject");
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
-            return;
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    jclass LeJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CALeInterface");
-    if (!LeJniInterface)
+    jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/jar/caleclientinterface");
+    if (!jni_LEInterface)
     {
-        OIC_LOG(DEBUG, TAG, "Could not get CALeInterface class");
-        return;
+        OIC_LOG(ERROR, TAG, "Could not get caleclientinterface class");
+        goto error_exit;
     }
 
-    jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, LeJniInterface, "<init>",
+    jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
                                                                  "(Landroid/content/Context;)V");
     if (!LeInterfaceConstructorMethod)
     {
-        OIC_LOG(DEBUG, TAG, "Could not get CALeInterface constructor method");
-        return;
+        OIC_LOG(ERROR, TAG, "Could not get caleclientinterface constructor method");
+        goto error_exit;
     }
 
-    (*env)->NewObject(env, LeJniInterface, LeInterfaceConstructorMethod, g_context);
-    OIC_LOG(DEBUG, TAG, "Create CALeInterface instance");
+    (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
+    OIC_LOG(DEBUG, TAG, "Create instance for caleclientinterface");
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
-}
 
-JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
-{
-    OIC_LOG(DEBUG, TAG, "JNI_OnLoad in calecore");
+    return CA_STATUS_OK;
 
-    JNIEnv* env;
-    if ((*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
+error_exit:
+
+    if (isAttached)
     {
-        return -1;
+        (*g_jvm)->DetachCurrentThread(g_jvm);
     }
-    g_jvm = jvm; /* cache the JavaVM pointer */
-
-    //JVM required for WifiCore to work with JNI interface
-    CAWiFiJniInit(jvm);
-    CALeServerJniInit(env, jvm);
-    CAEDRCoreJniInit(env, jvm);
 
-    return JNI_VERSION_1_6;
+    return CA_STATUS_FAILED;
 }
 
-void JNI_OnUnload(JavaVM *jvm, void *reserved)
+CAResult_t CALEClientInitialize(ca_thread_pool_t handle)
 {
-    OIC_LOG(DEBUG, TAG, "JNI_OnUnload in calecore");
+    OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
+
+    CALEClientJniInit();
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
 
+    bool isAttached = false;
     JNIEnv* env;
-    if ((*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
     {
-        return;
+        OIC_LOG(INFO, TAG, "Could not get 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;
     }
-    g_jvm = 0;
-    return;
-}
 
-void CALEInitialize(ca_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, TAG, "CALEInitialize");
+    CAResult_t ret = CALECheckPlatformVersion(env, 18);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "it is not supported");
+
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+
+        return ret;
+    }
 
     g_threadPoolHandle = handle;
 
+    ret = CALEClientInitGattMutexVaraibles();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
+        CALEClientTerminateGattMutexVariables();
+
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+
+        return ret;
+    }
+
     // init mutex for send logic
-    g_threadMutex = ca_mutex_new();
     g_threadCond = ca_cond_new();
+    g_threadSendCond = ca_cond_new();
+    g_threadSendCBCond = ca_cond_new();
 
-    CANativeCreateUUIDList();
+    CALEClientCreateDeviceList();
+    CALEClientJNISetContext();
 
-    CALeCreateJniInterfaceObject(); /* create java CALeInterface instance*/
+    ret = CALEClientCreateUUIDList();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
+
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+
+        return ret;
+    }
+
+    ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
+
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+
+        return ret;
+    }
+    g_isStartedLEClient = true;
+
+    return CA_STATUS_OK;
 }
 
-void CALETerminate()
+void CALEClientTerminate()
 {
-    OIC_LOG(DEBUG, TAG, "CALETerminate");
+    OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return;
+    }
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return;
         }
-        isAttached = JNI_TRUE;
-    }
-
-    CANativeLEDisconnectAll(env);
-
-    if (g_leScanCallback)
-    {
-        CANativeLEStopScanImpl(env, g_leScanCallback);
-        sleep(1);
+        isAttached = true;
     }
 
     if (g_leScanCallback)
@@ -218,233 +298,307 @@ void CALETerminate()
         (*env)->DeleteGlobalRef(env, g_leGattCallback);
     }
 
-    if (g_context)
+    if (g_sendBuffer)
     {
-        (*env)->DeleteGlobalRef(env, g_context);
+        (*env)->DeleteGlobalRef(env, g_sendBuffer);
     }
 
-    if (g_sendBuffer)
+    if (g_uuidList)
     {
-        (*env)->DeleteGlobalRef(env, g_sendBuffer);
+        (*env)->DeleteGlobalRef(env, g_uuidList);
     }
 
-    if (g_UUIDList)
+    CAResult_t ret = CALEClientRemoveAllDeviceState();
+    if (CA_STATUS_OK != ret)
     {
-        (*env)->DeleteGlobalRef(env, g_UUIDList);
+        OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
     }
 
-    CANativeRemoveAllDevices(env);
-    CANativeRemoveAllGattObjsList(env);
-    g_isStartServer = JNI_FALSE;
-    g_isFinishSendData = JNI_FALSE;
+    ret = CALEClientRemoveAllScanDevices(env);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
+    }
 
-    if (isAttached)
+    ret = CALEClientRemoveAllGattObjs(env);
+    if (CA_STATUS_OK != ret)
     {
-        (*g_jvm)->DetachCurrentThread(g_jvm);
+        OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
     }
 
-    // delete mutex object
-    ca_mutex_free(g_threadMutex);
-    g_threadMutex = NULL;
-    ca_cond_signal(g_threadCond);
+    g_isStartedMulticastServer = false;
+    g_isStartedScan = false;
+    CALEClientSetSendFinishFlag(false);
+    CALEClientSetTheSendRequestFlag(false);
+    CALEClientSetWriteCharacteristicCBFlag(false);
+
+    CALEClientTerminateGattMutexVariables();
+
     ca_cond_free(g_threadCond);
+    ca_cond_free(g_threadSendCond);
+    ca_cond_free(g_threadSendCBCond);
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
 }
 
-void CANativeSendFinish(JNIEnv *env, jobject gatt)
+void CALEClientSendFinish(JNIEnv *env, jobject gatt)
 {
-    OIC_LOG(DEBUG, TAG, "CANativeSendFinish");
+    OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
 
     if (gatt)
     {
-        CANativeLEDisconnect(env, gatt);
+        CAResult_t res = CALEClientDisconnect(env, gatt);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
+        }
     }
-    CANativeupdateSendCnt(env);
+    CALEClientUpdateSendCnt(env);
 }
 
-CAResult_t CALESendUnicastMessage(const char* address, const char* data, const uint32_t dataLen)
+CAResult_t CALEClientSendUnicastMessage(const char* address, const char* data,
+                                        const uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessage(%s, %s)", address, data);
+    OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %s)", address, data);
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
 
-    return CALESendUnicastMessageImpl(address, data, dataLen);
+    return CALEClientSendUnicastMessageImpl(address, data, dataLen);
 }
 
-CAResult_t CALESendMulticastMessage(const char* data, const uint32_t dataLen)
+CAResult_t CALEClientSendMulticastMessage(const char* data, const uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALESendMulticastMessage(%s)", data);
+    OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%s)", data);
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    bool isAttached = false;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        OIC_LOG(INFO, TAG, "Could not get 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;
+    }
+
+    CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
 
-    return CALESendMulticastMessageImpl(data, dataLen);
+    return ret;
 }
 
-CAResult_t CALEStartUnicastServer(const char* address)
+CAResult_t CALEClientStartUnicastServer(const char* address)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALEStartUnicastServer(%s)", address);
+    OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
 
-    return CA_STATUS_OK;
+    return CA_NOT_SUPPORTED;
 }
 
-CAResult_t CALEStartMulticastServer()
+CAResult_t CALEClientStartMulticastServer()
 {
-    OIC_LOG(DEBUG, TAG, "CALEStartMulticastServer");
+    OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
 
-    if (g_isStartServer)
+    if (g_isStartedMulticastServer)
     {
         OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
         return CA_STATUS_FAILED;
     }
 
-    jboolean isAttached = JNI_FALSE;
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    g_isStartServer = JNI_TRUE;
-
-    CANativeLEStartScan();
+    g_isStartedMulticastServer = true;
+    CAResult_t ret = CALEClientStartScan();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+    }
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
-    return CA_STATUS_OK;
+    return ret;
 }
 
-void CALEStopUnicastServer()
+void CALEClientStopUnicastServer()
 {
-    OIC_LOG(DEBUG, TAG, "CALEStopUnicastServer");
+    OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
 }
 
-void CALEStopMulticastServer()
+void CALEClientStopMulticastServer()
 {
-    OIC_LOG(DEBUG, TAG, "CALEStopMulticastServer");
-    g_isStartServer = JNI_FALSE;
-    CANativeLEStopScan();
+    OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
+    g_isStartedMulticastServer = false;
+    CAResult_t res = CALEClientStopScan();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        return;
+    }
 }
 
-void CALESetCallback(CAPacketReceiveCallback callback)
+void CALEClientSetCallback(CAPacketReceiveCallback callback)
 {
     g_packetReceiveCallback = callback;
 }
 
-CAResult_t CALEGetInterfaceInfo(char **address)
+CAResult_t CALEClientGetInterfaceInfo(char **address)
 {
-    CALEGetLocalAddress(address);
-    return CA_STATUS_OK;
+    OIC_LOG(INFO, TAG, "CALEClientGetInterfaceInfo is not supported");
+    return CA_NOT_SUPPORTED;
 }
 
-void CALEGetLocalAddress(char** address)
+CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const char* data,
+                                      const uint32_t dataLen)
 {
-    jboolean isAttached = JNI_FALSE;
-    JNIEnv* env;
-    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
-    {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
-        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
-        if (res != JNI_OK)
-        {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
-            return;
-        }
-        isAttached = JNI_TRUE;
-    }
-
-    jstring jni_address = CALEGetLocalDeviceAddress(env);
-    if (jni_address)
-    {
-        const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
-        uint32_t length = strlen(localAddress);
-        *address = (char*) OICMalloc(length + 1);
-        if (*address == NULL)
-        {
-            return;
-        }
-        memcpy(*address, localAddress, length + 1);
-    }
+    OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %s", address,
+              data);
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
 
-    OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
-    if (isAttached)
+    if (!g_jvm)
     {
-        (*g_jvm)->DetachCurrentThread(g_jvm);
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
     }
-}
-
-CAResult_t CALESendUnicastMessageImpl(const char* address, const char* data, const uint32_t dataLen)
-{
-    OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessageImpl, address: %s, data: %s", address, data);
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
-    }
-
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] set byteArray for data");
-    if (g_sendBuffer)
-    {
-        (*env)->DeleteGlobalRef(env, g_sendBuffer);
+        isAttached = true;
     }
-    jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
-    (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
-    g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
 
-    // connect to gatt server
-    CANativeLEStopScanImpl(env, g_leScanCallback);
-    sleep(1);
+    ca_mutex_lock(g_threadSendMutex);
 
-    jobject jni_obj_bluetoothDevice = NULL;
+    CAResult_t ret = CA_STATUS_OK;
     if (g_context && g_deviceList)
     {
-        jint index;
-        for (index = 0; index < u_arraylist_length(g_deviceList); index++)
+        uint32_t length = u_arraylist_length(g_deviceList);
+        for (uint32_t index = 0; index < length; index++)
         {
             jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
             if (!jarrayObj)
             {
-                OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
-                return CA_STATUS_FAILED;
+                OIC_LOG(ERROR, TAG, "jarrayObj is null");
+                goto error_exit;
             }
 
             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
             if (!jni_setAddress)
             {
-                OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
-                return CA_STATUS_FAILED;
+                OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+                goto error_exit;
             }
+
             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+            if (!setAddress)
+            {
+                OIC_LOG(ERROR, TAG, "setAddress is null");
+                goto error_exit;
+            }
+
+            OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
 
             if (!strcmp(setAddress, address))
             {
-                jni_obj_bluetoothDevice = jarrayObj;
+                (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+
+                // connect to gatt server
+                ret = CALEClientStopScan();
+                if (CA_STATUS_OK != ret)
+                {
+                    OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
+                    goto error_exit;
+                }
+
+                if (g_sendBuffer)
+                {
+                    (*env)->DeleteGlobalRef(env, g_sendBuffer);
+                }
+                jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+                (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
+                g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+
+                ret = CALEClientSendData(env, jarrayObj);
+                if (CA_STATUS_OK != ret)
+                {
+                    OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
+                    goto error_exit;
+                }
+                else
+                {
+                    CALEClientSetTheSendRequestFlag(true);
+                    ca_cond_signal(g_threadSendCBCond);
+
+                    if (!g_isReceivedWriteCB)
+                    {
+                        OIC_LOG(INFO, TAG, "wait..(unicast)");
+                        ca_cond_wait(g_threadSendCond, g_threadSendMutex);
+                    }
+                    else
+                    {
+                        CALEClientSetWriteCharacteristicCBFlag(false);
+                    }
+                }
+
+                OIC_LOG(INFO, TAG, "wake up");
                 break;
             }
-        }
-
-        if (jni_obj_bluetoothDevice)
-        {
-            jboolean autoConnect = JNI_FALSE;
-            CANativeLEConnect(env, jni_obj_bluetoothDevice, g_context, autoConnect,
-                              g_leGattCallback);
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
         }
     }
 
@@ -453,37 +607,64 @@ CAResult_t CALESendUnicastMessageImpl(const char* address, const char* data, con
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
+    ret = CALECheckSendState(address);
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "send has failed");
+        goto error_exit;
+    }
+
+    // start LE Scan again
+    ret = CALEClientStartScan();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        ca_mutex_unlock(g_threadSendMutex);
+        return res;
+    }
+
+    ca_mutex_unlock(g_threadSendMutex);
+    OIC_LOG(INFO, TAG, "unicast - send success");
     return CA_STATUS_OK;
-}
 
-CAResult_t CALESendMulticastMessageImpl(const char* data, const uint32_t dataLen)
-{
-    OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
+    // error label.
+error_exit:
 
-    jboolean isAttached = JNI_FALSE;
-    JNIEnv* env;
-    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    // start LE Scan again
+    ret = CALEClientStartScan();
+    if (CA_STATUS_OK != ret)
     {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
-        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
-        if (res != JNI_OK)
-        {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
-            return CA_STATUS_FAILED;
-        }
-        isAttached = JNI_TRUE;
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        ca_mutex_unlock(g_threadSendMutex);
+        return res;
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
     }
+    ca_mutex_unlock(g_threadSendMutex);
+    return CA_SEND_FAILED;
+}
+
+CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const char* data,
+                                              const uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
+    VERIFY_NON_NULL(data, TAG, "data is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
     if (!g_deviceList)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] g_deviceList is null");
+        OIC_LOG(ERROR, TAG, "g_deviceList is null");
         return CA_STATUS_FAILED;
-    }OIC_LOG(DEBUG, TAG, "set wait");
+    }
 
-    g_isFinishSendData = JNI_FALSE;
+    ca_mutex_lock(g_threadSendMutex);
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] set byteArray for data");
+    CALEClientSetSendFinishFlag(false);
+
+    OIC_LOG(DEBUG, TAG, "set byteArray for data");
     if (g_sendBuffer)
     {
         (*env)->DeleteGlobalRef(env, g_sendBuffer);
@@ -493,91 +674,243 @@ CAResult_t CALESendMulticastMessageImpl(const char* data, const uint32_t dataLen
     g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
 
     // connect to gatt server
-    CANativeLEStopScanImpl(env, g_leScanCallback);
-    sleep(1);
-
-    // reset gatt list
-    CANativeRemoveAllGattObjsList(env);
-    CANativeCreateGattObjList(env);
-
-    g_targetCnt = u_arraylist_length(g_deviceList);
+    CAResult_t res = CALEClientStopScan();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
+        ca_mutex_unlock(g_threadSendMutex);
+        return res;
+    }
 
-    jint index = 0;
+    uint32_t length = u_arraylist_length(g_deviceList);
+    g_targetCnt = length;
+    if (0 == length)
+    {
+        goto error_exit;
+    }
 
-    while (index < u_arraylist_length(g_deviceList))
+    uint32_t index = 0;
+    while (index < length)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
             continue;
         }
 
-        if (CA_STATUS_FAILED
-                == CANativeLEConnect(env, jarrayObj, g_context, JNI_FALSE, g_leGattCallback))
+        res = CALEClientSendData(env, jarrayObj);
+        if (res != CA_STATUS_OK)
+        {
+            OIC_LOG(ERROR, TAG, "BT device[%d] - send has failed");
+        }
+        else
+        {
+            CALEClientSetTheSendRequestFlag(true);
+            ca_cond_signal(g_threadSendCBCond);
+
+            if (!g_isReceivedWriteCB)
+            {
+                OIC_LOG(INFO, TAG, "wait..(multicast)");
+                ca_cond_wait(g_threadSendCond, g_threadSendMutex);
+            }
+            else
+            {
+                CALEClientSetWriteCharacteristicCBFlag(false);
+            }
+        }
+
+        jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
+        if (!jni_address)
+        {
+            OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+            goto error_exit;
+        }
+
+        const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+        if (!address)
+        {
+            OIC_LOG(ERROR, TAG, "address is not available");
+            goto error_exit;
+        }
+
+        res = CALECheckSendState(address);
+        if (CA_STATUS_OK != res)
         {
-            // connection failure
+            OIC_LOG(ERROR, TAG, "send has failed");
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+            goto error_exit;
         }
+
+        (*env)->ReleaseStringUTFChars(env, jni_address, address);
+
         index++;
-        sleep(1);
     }
 
+    OIC_LOG(DEBUG, TAG, "connection routine is finished");
+
     // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
-    if (!g_isFinishSendData)
+    if (!g_isFinishedSendData)
     {
         ca_mutex_lock(g_threadMutex);
         ca_cond_wait(g_threadCond, g_threadMutex);
-        OIC_LOG(DEBUG, TAG, "unset wait");
+        OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
         ca_mutex_unlock(g_threadMutex);
     }
 
     // start LE Scan again
-#ifdef DEBUG_MODE
-    CANativeLEStartScan();
-#endif
-
-    if (isAttached)
+    res = CALEClientStartScan();
+    if (CA_STATUS_OK != res)
     {
-        (*g_jvm)->DetachCurrentThread(g_jvm);
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        ca_mutex_unlock(g_threadSendMutex);
+        return res;
     }
 
+    ca_mutex_unlock(g_threadSendMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
     return CA_STATUS_OK;
-}
 
-jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt)
-{
-    if (!gatt)
+error_exit:
+    res = CALEClientStartScan();
+    if (CA_STATUS_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] gatt is null");
-        return NULL;
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        ca_mutex_unlock(g_threadSendMutex);
+        return res;
     }
 
-    jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
-    if (!jni_cid_gattdevice_list)
+    ca_mutex_unlock(g_threadSendMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
+    return CA_SEND_FAILED;
+}
+
+CAResult_t CALECheckSendState(const char* address)
+{
+    VERIFY_NON_NULL(address, TAG, "address is null");
+
+    ca_mutex_lock(g_deviceStateListMutex);
+    CALEState_t* state = CALEClientGetStateInfo(address);
+    if (NULL == state)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_gattdevice_list is null");
-        return NULL;
+        OIC_LOG(ERROR, TAG, "state is null");
+        ca_mutex_unlock(g_deviceStateListMutex);
+        return CA_SEND_FAILED;
     }
 
-    jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
-                                                      "()Landroid/bluetooth/BluetoothDevice;");
-    if (!jni_mid_getDevice)
+    if (STATE_SEND_SUCCESS != state->sendState)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getDevice is null");
-        return NULL;
+        OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
+        ca_mutex_unlock(g_deviceStateListMutex);
+        return CA_SEND_FAILED;
     }
+    ca_mutex_unlock(g_deviceStateListMutex);
+    return CA_STATUS_OK;
+}
 
-    jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
+CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
+    VERIFY_NON_NULL(device, TAG, "device is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    jstring jni_address = CALEGetAddressFromBTDevice(env, device);
+    if (!jni_address)
+    {
+        OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+        return CA_STATUS_FAILED;
+    }
+
+    const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is not available");
+        return CA_STATUS_FAILED;
+    }
+
+    ca_mutex_lock(g_deviceStateListMutex);
+    CALEState_t* state = CALEClientGetStateInfo(address);
+    ca_mutex_unlock(g_deviceStateListMutex);
+    if (!state)
+    {
+        OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
+        CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+            return ret;
+        }
+    }
+    else
+    {
+        if (STATE_CONNECTED == state->connectedState)
+        {
+            OIC_LOG(INFO, TAG, "GATT has already connected");
+            jobject gatt = CALEClientGetGattObjInList(env, address);
+            if (!gatt)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
+                (*env)->ReleaseStringUTFChars(env, jni_address, address);
+                return CA_STATUS_FAILED;
+            }
+
+            CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
+            if (CA_STATUS_OK != ret)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+                (*env)->ReleaseStringUTFChars(env, jni_address, address);
+                return ret;
+            }
+        }
+        else
+        {
+            OIC_LOG(DEBUG, TAG, "start to connect LE");
+            CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
+            if (CA_STATUS_OK != ret)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
+                (*env)->ReleaseStringUTFChars(env, jni_address, address);
+                return ret;
+            }
+        }
+    }
+
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    return CA_STATUS_OK;
+}
+
+jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
+{
+    VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
+    VERIFY_NON_NULL_RET(env, TAG, "env 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",
+                                                      "()Landroid/bluetooth/BluetoothDevice;");
+    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, "[BLE][Native] jni_obj_device is null");
+        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, "[BLE][Native] jni_address is null");
+        OIC_LOG(ERROR, TAG, "jni_address is null");
         return NULL;
     }
 
@@ -587,62 +920,105 @@ jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt)
 /**
  * BLE layer
  */
-void CANativeGattClose(JNIEnv *env, jobject bluetoothGatt)
+CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
 {
     // GATT CLOSE
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT CLOSE");
+    OIC_LOG(DEBUG, TAG, "Gatt Close");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
     // get BluetoothGatt class
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] 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, "[BLE][Native] jni_cid_BluetoothGatt is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
+        return CA_STATUS_FAILED;
     }
 
     jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
     if (!jni_mid_closeGatt)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_closeGatt is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
+        return CA_STATUS_OK;
     }
 
     // call disconnect gatt method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] request close Gatt");
+    OIC_LOG(DEBUG, TAG, "request to close GATT");
     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
+
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "closeGATT has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
 }
 
-void CANativeLEStartScan()
+CAResult_t CALEClientStartScan()
 {
-    if (!g_isStartServer)
+    if (!g_isStartedMulticastServer)
     {
-        OIC_LOG(DEBUG, TAG, "server is not started yet..scan will be passed");
-        return;
+        OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
+        return CA_STATUS_FAILED;
+    }
+
+    if (!g_isStartedLEClient)
+    {
+        OIC_LOG(ERROR, TAG, "LE client is not started");
+        return CA_STATUS_FAILED;
+    }
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    if (g_isStartedScan)
+    {
+        OIC_LOG(INFO, TAG, "scanning is already started");
+        return CA_STATUS_OK;
     }
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
 
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
-            return;
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStartScan");
+    OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
 
+    CAResult_t ret = CA_STATUS_OK;
     // scan gatt server with UUID
-    if (g_leScanCallback && g_UUIDList)
+    if (g_leScanCallback && g_uuidList)
     {
-        CANativeLEStartScanWithUUIDImpl(env, g_UUIDList, g_leScanCallback);
+#ifndef FULL_SCAN
+        ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
+        if(CA_STATUS_OK != ret)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
+        }
+#else
+        ret = CALEClientStartScanImpl(env, g_leScanCallback);
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
+        }
+#endif
     }
 
     if (isAttached)
@@ -650,22 +1026,26 @@ void CANativeLEStartScan()
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
+    return ret;
 }
 
-void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
+CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
 {
+    VERIFY_NON_NULL(callback, TAG, "callback is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
     // get default bt adapter class
-    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
     if (!jni_cid_BTAdapter)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
     // get remote bt adapter method
@@ -674,18 +1054,18 @@ void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
                                                                     METHODID_OBJECTNONPARAM);
     if (!jni_mid_getDefaultAdapter)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: getDefaultAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
     // get start le scan method
-    jmethodID jni_mid_startLeScan = (*env)->GetMethodID(
-            env, jni_cid_BTAdapter, "startLeScan",
-            "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
+    jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
+                                                        "(Landroid/bluetooth/BluetoothAdapter$"
+                                                        "LeScanCallback;)Z");
     if (!jni_mid_startLeScan)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
-        return;
+        OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
+        return CA_STATUS_FAILED;
     }
 
     // gat bt adapter object
@@ -693,8 +1073,8 @@ void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
                                                                jni_mid_getDefaultAdapter);
     if (!jni_obj_BTAdapter)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
     // call start le scan method
@@ -702,152 +1082,182 @@ void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
                                                              jni_mid_startLeScan, callback);
     if (!jni_obj_startLeScan)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] startLeScan is failed");
-        return;
+        OIC_LOG(ERROR, TAG, "startLeScan is failed");
+        return CA_STATUS_FAILED;
     }
     else
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan is started");
-    }
-}
-
-jobject CANativeGetUUIDObject(JNIEnv *env, const char* uuid)
-{
-    // setting UUID
-    jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
-    if (!jni_cid_uuid)
-    {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_uuid is null");
-        return NULL;
-    }
-
-    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
-            env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
-    if (!jni_mid_fromString)
-    {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_fromString is null");
-        return NULL;
-    }
-
-    jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
-    jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
-                                                          jni_uuid);
-    if (!jni_obj_uuid)
-    {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_uuid is null");
-        return NULL;
+        OIC_LOG(DEBUG, TAG, "startLeScan is started");
+        g_isStartedScan = true;
     }
 
-    return jni_obj_uuid;
+    return CA_STATUS_OK;
 }
 
-void CANativeLEStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
+CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
 {
-    // get default bt adapter class
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get default bt adapter class");
+    VERIFY_NON_NULL(callback, TAG, "callback is null");
+    VERIFY_NON_NULL(uuids, TAG, "uuids is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
-    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
     if (!jni_cid_BTAdapter)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
     // get remote bt adapter method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] 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, "[BLE][Native] getState From BTAdapter: getDefaultAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
     // get start le scan method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get start le scan method");
-    jmethodID jni_mid_startLeScan = (*env)->GetMethodID(
-            env, jni_cid_BTAdapter, "startLeScan",
-            "([Ljava/util/UUID;Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
+    jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
+                                                        "([Ljava/util/UUID;Landroid/bluetooth/"
+                                                        "BluetoothAdapter$LeScanCallback;)Z");
     if (!jni_mid_startLeScan)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
-        return;
+        OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
+        return CA_STATUS_FAILED;
     }
 
     // get bt adapter object
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get bt adapter object");
     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
                                                                jni_mid_getDefaultAdapter);
     if (!jni_obj_BTAdapter)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
     // call start le scan method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] call start le scan service method");
     jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
                                                              jni_mid_startLeScan, uuids, callback);
     if (!jni_obj_startLeScan)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] startLeScan With UUID is failed");
-        return;
+        OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
+        return CA_STATUS_FAILED;
     }
     else
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan With UUID is started");
+        OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
+        g_isStartedScan = true;
+    }
+
+    return CA_STATUS_OK;
+}
+
+jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
+{
+    VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+
+    // setting UUID
+    jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
+    if (!jni_cid_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
+                                                             "(Ljava/lang/String;)"
+                                                             "Ljava/util/UUID;");
+    if (!jni_mid_fromString)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
+        return NULL;
+    }
+
+    jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
+    jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
+                                                          jni_uuid);
+    if (!jni_obj_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
+        return NULL;
     }
+
+    return jni_obj_uuid;
 }
 
-void CANativeLEStopScan()
+CAResult_t CALEClientStopScan()
 {
-    jboolean isAttached = JNI_FALSE;
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    if (!g_isStartedScan)
+    {
+        OIC_LOG(INFO, TAG, "scanning is already stopped");
+        return CA_STATUS_OK;
+    }
+
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
-            return;
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    CANativeLEStopScanImpl(env, g_leScanCallback);
+    CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
+    }
+    else
+    {
+        g_isStartedScan = false;
+    }
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
+    return ret;
 }
 
-void CANativeLEStopScanImpl(JNIEnv *env, jobject callback)
+CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
 {
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStopScan");
+    OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
+    VERIFY_NON_NULL(callback, TAG, "callback is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
     // get default bt adapter class
-    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
     if (!jni_cid_BTAdapter)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
     // get remote bt adapter method
@@ -856,18 +1266,18 @@ void CANativeLEStopScanImpl(JNIEnv *env, jobject callback)
                                                                     METHODID_OBJECTNONPARAM);
     if (!jni_mid_getDefaultAdapter)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] getState From BTAdapter: getDefaultAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
     // get start le scan method
-    jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(
-            env, jni_cid_BTAdapter, "stopLeScan",
-            "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)V");
+    jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
+                                                       "(Landroid/bluetooth/"
+                                                       "BluetoothAdapter$LeScanCallback;)V");
     if (!jni_mid_stopLeScan)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] stopLeScan: jni_mid_stopLeScan is null");
-        return;
+        OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
+        return CA_STATUS_FAILED;
     }
 
     // gat bt adapter object
@@ -875,326 +1285,406 @@ void CANativeLEStopScanImpl(JNIEnv *env, jobject callback)
                                                                jni_mid_getDefaultAdapter);
     if (!jni_obj_BTAdapter)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to stop LE Scan");
+    OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
     // call start le scan method
     (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "stopLeScan has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
 }
 
-CAResult_t CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context,
-                             jboolean autoconnect, jobject callback)
+CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
+                             jobject callback)
 {
+    OIC_LOG(DEBUG, TAG, "GATT CONNECT");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
+    VERIFY_NON_NULL(callback, TAG, "callback is null");
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return CA_STATUS_FAILED;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
     jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
-    const char * addr = (*env)->GetStringUTFChars(env, jni_address, NULL);
-    OIC_LOG_V(DEBUG, TAG, "[BLE][Native] request connectGatt to %s", addr);
-
-    // GATT CONNECT
+    if (!jni_address)
+    {
+        OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
+        return CA_STATUS_FAILED;
+    }
 
     // get BluetoothDevice class
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothDevice class");
+    OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
     jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
     if (!jni_cid_BluetoothDevice)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] bleConnect: jni_cid_BluetoothDevice is null");
+        OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
         return CA_STATUS_FAILED;
     }
 
     // get connectGatt method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get connectGatt method");
-    jmethodID jni_mid_connectGatt = (*env)->GetMethodID(
-            env, jni_cid_BluetoothDevice, "connectGatt",
-            "(Landroid/content/Context;ZLandroid/bluetooth/BluetoothGattCallback;)"
-            "Landroid/bluetooth/BluetoothGatt;");
+    OIC_LOG(DEBUG, TAG, "get connectGatt method");
+    jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
+                                                        "(Landroid/content/Context;ZLandroid/"
+                                                        "bluetooth/BluetoothGattCallback;)"
+                                                        "Landroid/bluetooth/BluetoothGatt;");
     if (!jni_mid_connectGatt)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] bleConnect: jni_mid_connectGatt is null");
+        OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] Call object method - connectGatt");
+    OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
     jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
                                                            jni_mid_connectGatt,
                                                            NULL,
                                                            autoconnect, callback);
     if (!jni_obj_connectGatt)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] CALL API - connectGatt was failed.obj will be removed");
-        CANativeRemoveDevice(env, jni_address);
-        CANativeupdateSendCnt(env);
+        OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
+        CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
+        CALEClientUpdateSendCnt(env);
         return CA_STATUS_FAILED;
     }
     else
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - connecting..");
+        OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
     }
     return CA_STATUS_OK;
 }
 
-void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt)
+CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
 {
+    OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
-    // GATT DISCONNECT
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT DISCONNECT");
-
     // get BluetoothGatt class
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt classjobject bluetoothGatt");
     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
     if (!jni_cid_BluetoothGatt)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
+        return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt disconnect method");
-    jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "disconnect",
-                                                           "()V");
+    OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
+    jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
+                                                           "disconnect", "()V");
     if (!jni_mid_disconnectGatt)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_disconnectGatt is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
+        return CA_STATUS_FAILED;
     }
 
     // call disconnect gatt method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request disconnectGatt");
     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "disconnect has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return CA_STATUS_FAILED;
+    }
 
+    OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
+
+    return CA_STATUS_OK;
 }
 
-void CANativeLEDisconnectAll(JNIEnv *env)
+CAResult_t CALEClientDisconnectAll(JNIEnv *env)
 {
-    OIC_LOG(DEBUG, TAG, "CANativeLEDisconnectAll");
+    OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
     if (!g_gattObjectList)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] g_gattObjectList is null");
-        return;
+        OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
+        return CA_STATUS_FAILED;
     }
 
-    jint index;
-    for (index = 0; index < u_arraylist_length(g_gattObjectList); index++)
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            continue;
+        }
+        CAResult_t res = CALEClientDisconnect(env, jarrayObj);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
             continue;
         }
-        CANativeLEDisconnect(env, jarrayObj);
     }
 
     OICFree(g_gattObjectList);
     g_gattObjectList = NULL;
-    return;
+
+    return CA_STATUS_OK;
 }
 
-void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
+CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
 {
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
-    // GATT SERVICE DISCOVERY
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT SERVICE DISCOVERY");
-
     // get BluetoothGatt class
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] 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, "[BLE][Native] jni_cid_BluetoothGatt is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
+        return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] discovery gatt services method");
+    OIC_LOG(DEBUG, TAG, "discovery gatt services method");
     jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
                                                              "discoverServices", "()Z");
     if (!jni_mid_discoverServices)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_discoverServices is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
+        return CA_STATUS_FAILED;
     }
     // call disconnect gatt method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request discovery gatt services");
-    (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
+    OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
+    jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
+    if (!ret)
+    {
+        OIC_LOG(ERROR, TAG, "discoverServices has not been started");
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
 }
 
-CAResult_t CANativeWriteCharacteristic(JNIEnv *env, jobject bluetoothGatt,
-                                       jobject gattCharacteristic)
+CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
 {
-    if (!CALEIsEnableBTAdapter(env))
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(gatt, TAG, "gatt is null");
+
+    // send data
+    jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
+    if (!jni_obj_character)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        CALEClientSendFinish(env, gatt);
+        ca_cond_signal(g_threadSendCond);
         return CA_STATUS_FAILED;
     }
 
-    // WRITE GATT CHARACTERISTIC
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] WRITE GATT CHARACTERISTIC");
+    CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
+    if (CA_STATUS_OK != ret)
+    {
+        CALEClientSendFinish(env, gatt);
+        ca_cond_signal(g_threadSendCond);
+        return ret;
+    }
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
+                                           jobject gattCharacteristic)
+{
+    OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+    VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
+
+    if (!CALEIsEnableBTAdapter(env))
+    {
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_STATUS_FAILED;
+    }
 
     // get BluetoothGatt class
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] 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, "[BLE][Native] jni_cid_BluetoothGatt is null");
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] write characteristic method");
-    jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(
-            env, jni_cid_BluetoothGatt, "writeCharacteristic",
-            "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
+    OIC_LOG(DEBUG, TAG, "write characteristic method");
+    jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
+                                                                "writeCharacteristic",
+                                                                "(Landroid/bluetooth/"
+                                                                "BluetoothGattCharacteristic;)Z");
     if (!jni_mid_writeCharacteristic)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_writeCharacteristic is null");
+        OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
         return CA_STATUS_FAILED;
     }
 
     // call disconnect gatt method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to write gatt characteristic");
+    OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
     jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
                                                        jni_mid_writeCharacteristic,
                                                        gattCharacteristic);
     if (ret)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] writeCharacteristic is success");
+        OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
     }
     else
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] writeCharacteristic is failed");
+        OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
         return CA_STATUS_FAILED;
     }
+
     return CA_STATUS_OK;
 }
 
-void CANativeReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
+CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
 {
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_STATUS_FAILED;
     }
 
     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
     if (!jni_cid_BluetoothGatt)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
+        return CA_STATUS_FAILED;
     }
 
-    jstring jni_uuid = (*env)->NewStringUTF(env, IOTIVITY_GATT_RX_UUID);
-    jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
-    if (!jni_obj_GattCharacteristic)
+    jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
+    if (!jni_uuid)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_uuid is null");
+        return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] read characteristic method");
-    jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(
-            env, jni_cid_BluetoothGatt, "readCharacteristic",
-            "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
+    jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
+    if (!jni_obj_GattCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "read characteristic method");
+    jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
+                                                               "readCharacteristic",
+                                                               "(Landroid/bluetooth/"
+                                                               "BluetoothGattCharacteristic;)Z");
     if (!jni_mid_readCharacteristic)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_readCharacteristic is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
+        return CA_STATUS_FAILED;
     }
 
     // call disconnect gatt method
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - request to read gatt characteristic");
+    OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
     jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
                                              jni_obj_GattCharacteristic);
     if (ret)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] readCharacteristic is success");
+        OIC_LOG(DEBUG, TAG, "readCharacteristic success");
     }
     else
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] readCharacteristic is failed");
+        OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
+        return CA_STATUS_FAILED;
     }
+
+    return CA_STATUS_OK;
 }
 
-CAResult_t CANativeSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
-                                                 const char* uuid)
+CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
+                                                   jobject characteristic)
 {
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+    VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
     // get BluetoothGatt class
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeSetCharacteristicNotification");
+    OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
     if (!jni_cid_BluetoothGatt)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
-        return CA_STATUS_FAILED;
-    }
-
-    jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
-    jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
-    if (!jni_obj_GattCharacteristic)
-    {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
         return CA_STATUS_FAILED;
     }
 
     // set Characteristic Notification
-    jmethodID jni_mid_setNotification = (*env)->GetMethodID(
-            env, jni_cid_BluetoothGatt, "setCharacteristicNotification",
-            "(Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
+    jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
+                                                            "setCharacteristicNotification",
+                                                            "(Landroid/bluetooth/"
+                                                            "BluetoothGattCharacteristic;Z)Z");
     if (!jni_mid_setNotification)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getService is null");
+        OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
         return CA_STATUS_FAILED;
     }
 
-    jboolean enable = JNI_TRUE;
     jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
-                                             jni_obj_GattCharacteristic, enable);
-    if (1 == ret)
+                                             characteristic, JNI_TRUE);
+    if (JNI_TRUE == ret)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] CALL API - setCharacteristicNotification is success");
-        return CA_STATUS_OK;
+        OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
     }
     else
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] CALL API - setCharacteristicNotification is failed");
+        OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
         return CA_STATUS_FAILED;
     }
+
+    return CA_STATUS_OK;
 }
 
-jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
+jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
 {
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
+    VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
     // get BluetoothGatt class
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeGetGattService");
+    OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
     if (!jni_cid_BluetoothGatt)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
         return NULL;
     }
 
@@ -1203,188 +1693,381 @@ jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring chara
             "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
     if (!jni_mid_getService)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getService is null");
+        OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
         return NULL;
     }
 
-    jobject jni_obj_service_uuid = CANativeGetUUIDObject(env, IOTIVITY_GATT_SERVIE_UUID);
+    jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
     if (!jni_obj_service_uuid)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_service_uuid is null");
+        OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
         return NULL;
     }
 
     // get bluetooth gatt service
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get service");
+    OIC_LOG(DEBUG, TAG, "request to get service");
     jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
                                                            jni_obj_service_uuid);
+    if (!jni_obj_gattService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
+        return NULL;
+    }
 
     // get bluetooth gatt service class
     jclass jni_cid_BluetoothGattService = (*env)->FindClass(
             env, "android/bluetooth/BluetoothGattService");
     if (!jni_cid_BluetoothGattService)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BluetoothGattService is null");
+        OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
         return NULL;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt getCharacteristic method");
-    jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(
-            env, jni_cid_BluetoothGattService, "getCharacteristic",
-            "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
+    OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
+    jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
+                                                              "getCharacteristic",
+                                                              "(Ljava/util/UUID;)"
+                                                              "Landroid/bluetooth/"
+                                                              "BluetoothGattCharacteristic;");
     if (!jni_mid_getCharacteristic)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getCharacteristic is null");
+        OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
         return NULL;
     }
 
     const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
-    jobject jni_obj_tx_uuid = CANativeGetUUIDObject(env, uuid);
+    if (!uuid)
+    {
+        OIC_LOG(ERROR, TAG, "uuid is null");
+        return NULL;
+    }
+
+    jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
     if (!jni_obj_tx_uuid)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_tx_uuid is null");
+        OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
+        (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
         return NULL;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get Characteristic");
+    OIC_LOG(DEBUG, TAG, "request to get Characteristic");
     jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
                                                                   jni_mid_getCharacteristic,
                                                                   jni_obj_tx_uuid);
 
+    (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
     return jni_obj_GattCharacteristic;
 }
 
-jobject CANativeCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
+jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
 {
+    OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
+    VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return NULL;
+    }
+
+    jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
+    if (!jni_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_uuid is null");
         return NULL;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattCharacteristic");
-    jstring jni_uuid = (*env)->NewStringUTF(env, IOTIVITY_GATT_TX_UUID);
-    jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, jni_uuid);
+    jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
     if (!jni_obj_GattCharacteristic)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
+        OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
         return NULL;
     }
 
-    jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(
-            env, "android/bluetooth/BluetoothGattCharacteristic");
+    jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
+                                                            "/BluetoothGattCharacteristic");
     if (!jni_cid_BTGattCharacteristic)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
+        OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
         return NULL;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] set value in Characteristic");
+    OIC_LOG(DEBUG, TAG, "set value in Characteristic");
     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
                                                      "([B)Z");
     if (!jni_mid_setValue)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_setValue is null");
+        OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
         return NULL;
     }
 
     jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
                                              data);
-    if (1 == ret)
+    if (JNI_TRUE == ret)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value has been set");
-        return jni_obj_GattCharacteristic;
+        OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
     }
     else
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value hasn't been set");
+        OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
+        return NULL;
+    }
+
+    // set Write Type
+    jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
+                                                         "setWriteType", "(I)V");
+    if (!jni_mid_setWriteType)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
+        return NULL;
+    }
+
+    jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
+                                                            "WRITE_TYPE_NO_RESPONSE", "I");
+    if (!jni_fid_no_response)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
         return NULL;
     }
+
+    jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
+                                                 jni_fid_no_response);
+
+    (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
+
+    return jni_obj_GattCharacteristic;
 }
 
-jbyteArray CANativeGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
+jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
 {
+    VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
-    jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(
-            env, "android/bluetooth/BluetoothGattCharacteristic");
+    jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
+                                                            "BluetoothGattCharacteristic");
     if (!jni_cid_BTGattCharacteristic)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
+        OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
         return NULL;
     }
 
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] get value in Characteristic");
+    OIC_LOG(DEBUG, TAG, "get value in Characteristic");
     jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
                                                      "()[B");
     if (!jni_mid_getValue)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_mid_getValue is null");
+        OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
         return NULL;
     }
 
-    jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic, jni_mid_getValue);
+    jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
+                                                             jni_mid_getValue);
     return jni_obj_data_array;
 }
 
-void CANativeCreateUUIDList()
+CAResult_t CALEClientCreateUUIDList()
 {
-    jboolean isAttached = JNI_FALSE;
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
-            return;
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
     // create new object array
     jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
     if (!jni_cid_uuid_list)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_cid_uuid_list is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
+        goto error_exit;
     }
 
-    jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1, jni_cid_uuid_list,
-    NULL);
+    jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
+                                                                          jni_cid_uuid_list, NULL);
     if (!jni_obj_uuid_list)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_obj_uuid_list is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
+        goto error_exit;
     }
 
-    // remove previous list and create list again
-    CANativeRemoveAllDevices(env);
-    CANativeCreateScanDeviceList(env);
-
     // make uuid list
-    jobject jni_obj_uuid = CANativeGetUUIDObject(env, IOTIVITY_GATT_SERVIE_UUID);
+    jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
+    if (!jni_obj_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
+        goto error_exit;
+    }
     (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
 
-    g_UUIDList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
+    g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return CA_STATUS_OK;
+
+    // error label.
+error_exit:
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
+    return CA_STATUS_FAILED;
+}
+
+CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
+                                         jobject characteristic)
+{
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+    VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
+
+    if (!CALEIsEnableBTAdapter(env))
+    {
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
+    jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
+                                                            "BluetoothGattCharacteristic");
+    if (!jni_cid_BTGattCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "set value in Characteristic");
+    jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
+                                                          "getDescriptor",
+                                                          "(Ljava/util/UUID;)Landroid/bluetooth/"
+                                                          "BluetoothGattDescriptor;");
+    if (!jni_mid_getDescriptor)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
+    if (!jni_obj_cc_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "request to get descriptor");
+    jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
+                                                          jni_mid_getDescriptor, jni_obj_cc_uuid);
+    if (!jni_obj_descriptor)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_descriptor is null");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "set value in descriptor");
+    jclass jni_cid_descriptor = (*env)->FindClass(env,
+                                                  "android/bluetooth/BluetoothGattDescriptor");
+    if (!jni_cid_descriptor)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
+    if (!jni_mid_setValue)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
+                                                          "ENABLE_NOTIFICATION_VALUE", "[B");
+    if (!jni_fid_NotiValue)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
+
+    jboolean jni_setvalue = (*env)->CallBooleanMethod(
+            env, jni_obj_descriptor, jni_mid_setValue,
+            (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
+    if (jni_setvalue)
+    {
+        OIC_LOG(DEBUG, TAG, "setValue success");
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "setValue has failed");
+        return CA_STATUS_FAILED;
+    }
+
+    jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
+    if (!jni_cid_gatt)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
+    jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
+                                                            "(Landroid/bluetooth/"
+                                                            "BluetoothGattDescriptor;)Z");
+    if (!jni_mid_writeDescriptor)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "request to write descriptor");
+    jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
+                                                 jni_obj_descriptor);
+    if (jni_ret)
+    {
+        OIC_LOG(DEBUG, TAG, "writeDescriptor success");
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
 }
 
-void CANativeCreateScanDeviceList(JNIEnv *env)
+void CALEClientCreateScanDeviceList(JNIEnv *env)
 {
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateScanDeviceList");
+    OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
 
+    ca_mutex_lock(g_deviceListMutex);
     // create new object array
     if (g_deviceList == NULL)
     {
@@ -1392,90 +2075,127 @@ void CANativeCreateScanDeviceList(JNIEnv *env)
 
         g_deviceList = u_arraylist_create();
     }
+    ca_mutex_unlock(g_deviceListMutex);
 }
 
-void CANativeAddScanDeviceToList(JNIEnv *env, jobject device)
+CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
 {
-    if (!device)
-    {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] device is null");
-        return;
-    }
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientAddScanDeviceToList");
+    VERIFY_NON_NULL(device, TAG, "device is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    ca_mutex_lock(g_deviceListMutex);
 
     if (!g_deviceList)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] gdevice_list is null");
-        return;
+        OIC_LOG(ERROR, TAG, "gdevice_list is null");
+        ca_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
     }
 
     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
     if (!jni_remoteAddress)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_remoteAddress is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
+        ca_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
     }
 
     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+    if (!remoteAddress)
+    {
+        OIC_LOG(ERROR, TAG, "remoteAddress is null");
+        ca_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
+    }
 
-    if (!CANativeIsDeviceInList(env, remoteAddress))
+    if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
     {
         jobject gdevice = (*env)->NewGlobalRef(env, device);
         u_arraylist_add(g_deviceList, gdevice);
         OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
     }
+    (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
+
+    ca_mutex_unlock(g_deviceListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientAddScanDeviceToList");
+    return CA_STATUS_OK;
 }
 
-jboolean CANativeIsDeviceInList(JNIEnv *env, const char* remoteAddress)
+bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
 {
-    // get address value from device list
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientIsDeviceInScanDeviceList");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
+
+    if (!g_deviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "g_deviceList is null");
+        return true;
+    }
 
-    jint index;
-    for (index = 0; index < u_arraylist_length(g_deviceList); index++)
+    uint32_t length = u_arraylist_length(g_deviceList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
-            return JNI_TRUE;
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            return true;
         }
 
         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
         if (!jni_setAddress)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
-            return JNI_TRUE;
+            OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+            return true;
         }
 
         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return true;
+        }
 
         if (!strcmp(remoteAddress, setAddress))
         {
             OIC_LOG(DEBUG, TAG, "the device is already set");
-            return JNI_TRUE;
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            return true;
         }
+
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientIsDeviceInScanDeviceList");
     OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
-    return JNI_FALSE;
+
+    return false;
 }
 
-void CANativeRemoveAllDevices(JNIEnv *env)
+CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
 {
-    OIC_LOG(DEBUG, TAG, "CANativeRemoveAllDevices");
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    ca_mutex_lock(g_deviceListMutex);
 
     if (!g_deviceList)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] g_deviceList is null");
-        return;
+        OIC_LOG(ERROR, TAG, "g_deviceList is null");
+        ca_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
     }
 
-    jint index;
-    for (index = 0; index < u_arraylist_length(g_deviceList); index++)
+    uint32_t length = u_arraylist_length(g_deviceList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
             continue;
         }
         (*env)->DeleteGlobalRef(env, jarrayObj);
@@ -1483,172 +2203,240 @@ void CANativeRemoveAllDevices(JNIEnv *env)
 
     OICFree(g_deviceList);
     g_deviceList = NULL;
-    return;
+
+    ca_mutex_unlock(g_deviceListMutex);
+    return CA_STATUS_OK;
 }
 
-void CANativeRemoveDevice(JNIEnv *env, jstring address)
+CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
 {
-    OIC_LOG(DEBUG, TAG, "CANativeRemoveDevice");
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    ca_mutex_lock(g_deviceListMutex);
 
     if (!g_deviceList)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] g_deviceList is null");
-        return;
+        OIC_LOG(ERROR, TAG, "g_deviceList is null");
+        ca_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
     }
 
-    jint index;
-    for (index = 0; index < u_arraylist_length(g_deviceList); index++)
+    uint32_t length = u_arraylist_length(g_deviceList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
-            return;
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            ca_mutex_unlock(g_deviceListMutex);
+            return CA_STATUS_FAILED;
         }
 
         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
         if (!jni_setAddress)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
-            return;
+            OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+            ca_mutex_unlock(g_deviceListMutex);
+            return CA_STATUS_FAILED;
         }
+
         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            ca_mutex_unlock(g_deviceListMutex);
+            return CA_STATUS_FAILED;
+        }
+
         const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
+        if (!remoteAddress)
+        {
+            OIC_LOG(ERROR, TAG, "remoteAddress is null");
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            ca_mutex_unlock(g_deviceListMutex);
+            return CA_STATUS_FAILED;
+        }
 
         if (!strcmp(setAddress, remoteAddress))
         {
-            OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
+            OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
             (*env)->DeleteGlobalRef(env, jarrayObj);
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
 
-            CAReorderingDeviceList(index);
-            return;
+            CALEClientReorderingList(index, g_deviceList);
+            ca_mutex_unlock(g_deviceListMutex);
+            return CA_STATUS_OK;
         }
-    }OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
-    return;
-}
-
-void CAReorderingDeviceList(uint32_t index)
-{
-    if (index >= g_deviceList->length)
-    {
-        return;
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+        (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
     }
 
-    if (index < g_deviceList->length - 1)
-    {
-        memmove(&g_deviceList->data[index], &g_deviceList->data[index + 1],
-                (g_deviceList->length - index - 1) * sizeof(void *));
-    }
+    ca_mutex_unlock(g_deviceListMutex);
+    OIC_LOG(DEBUG, TAG, "There are no object in the device list");
 
-    g_deviceList->size--;
-    g_deviceList->length--;
+    return CA_STATUS_OK;
 }
 
 /**
  * Gatt Object List
  */
-void CANativeCreateGattObjList(JNIEnv *env)
-{
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattObjList");
-
-    // create new object array
-    if (g_gattObjectList == NULL)
-    {
-        OIC_LOG(DEBUG, TAG, "Create Gatt object list");
-
-        g_gattObjectList = u_arraylist_create();
-    }
-}
 
-void CANativeAddGattobjToList(JNIEnv *env, jobject gatt)
+CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
 {
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeAddGattobjToList");
-
-    if (!gatt)
-    {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] gatt is null");
-        return;
-    }
+    OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(gatt, TAG, "gatt is null");
 
-    if (!g_gattObjectList)
-    {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] g_gattObjectList is null");
-        return;
-    }
+    ca_mutex_lock(g_gattObjectMutex);
 
-    jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
+    jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
     if (!jni_remoteAddress)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] jni_remoteAddress is null");
-        return;
+        OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
+        ca_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_FAILED;
     }
 
     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+    if (!remoteAddress)
+    {
+        OIC_LOG(ERROR, TAG, "remoteAddress is null");
+        ca_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_FAILED;
+    }
 
-    if (!CANativeIsGattObjInList(env, remoteAddress))
+    if (!CALEClientIsGattObjInList(env, remoteAddress))
     {
-        jobject gGatt = (*env)->NewGlobalRef(env, gatt);
-        u_arraylist_add(g_gattObjectList, gGatt);
-        OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
+        jobject newGatt = (*env)->NewGlobalRef(env, gatt);
+        u_arraylist_add(g_gattObjectList, newGatt);
+        OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
     }
+
+    (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
+    ca_mutex_unlock(g_gattObjectMutex);
+    return CA_STATUS_OK;
 }
 
-jboolean CANativeIsGattObjInList(JNIEnv *env, const char* remoteAddress)
+bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
 {
-    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsGattObjInList");
+    OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
 
-    jint index;
-    for (index = 0; index < u_arraylist_length(g_gattObjectList); index++)
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
     {
 
         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
-            return JNI_TRUE;
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            return true;
         }
 
-        jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
+        jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
         if (!jni_setAddress)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
-            return JNI_TRUE;
+            OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+            return true;
         }
 
         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return true;
+        }
 
         if (!strcmp(remoteAddress, setAddress))
         {
             OIC_LOG(DEBUG, TAG, "the device is already set");
-            return JNI_TRUE;
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            return true;
         }
         else
         {
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
             continue;
         }
     }
 
-    OIC_LOG(DEBUG, TAG, "there are no the gatt obejct in list. we can add");
-    return JNI_FALSE;
+    OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
+    return false;
+}
+
+jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
+
+    ca_mutex_lock(g_gattObjectMutex);
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
+        if (!jarrayObj)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return NULL;
+        }
+
+        jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
+        if (!jni_setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return NULL;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return NULL;
+        }
+
+        if (!strcmp(remoteAddress, setAddress))
+        {
+            OIC_LOG(DEBUG, TAG, "the device is already set");
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            ca_mutex_unlock(g_gattObjectMutex);
+            return jarrayObj;
+        }
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+    }
+
+    ca_mutex_unlock(g_gattObjectMutex);
+    OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
+    return NULL;
 }
 
-void CANativeRemoveAllGattObjsList(JNIEnv *env)
+CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
 {
-    OIC_LOG(DEBUG, TAG, "CANativeRemoveAllGattObjsList");
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
+    ca_mutex_lock(g_gattObjectMutex);
     if (!g_gattObjectList)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] g_gattObjectList is null");
-        return;
+        OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
+        ca_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_FAILED;
     }
 
-    jint index;
-    for (index = 0; index < u_arraylist_length(g_gattObjectList); index++)
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
             continue;
         }
         (*env)->DeleteGlobalRef(env, jarrayObj);
@@ -1656,79 +2444,512 @@ void CANativeRemoveAllGattObjsList(JNIEnv *env)
 
     OICFree(g_gattObjectList);
     g_gattObjectList = NULL;
-    return;
+    ca_mutex_unlock(g_gattObjectMutex);
+    return CA_STATUS_OK;
 }
 
-void CANativeRemoveGattObj(JNIEnv *env, jobject gatt)
+CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
 {
-    OIC_LOG(DEBUG, TAG, "CANativeRemoveGattObj");
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
+    VERIFY_NON_NULL(gatt, TAG, "gatt is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
+    ca_mutex_lock(g_gattObjectMutex);
     if (!g_gattObjectList)
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] g_gattObjectList is null");
-        return;
+        OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
+        ca_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_FAILED;
     }
 
-    jint index;
-    for (index = 0; index < u_arraylist_length(g_gattObjectList); index++)
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
         if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
-            return;
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
         }
 
-        jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
+        jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
         if (!jni_setAddress)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
-            return;
+            OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
         }
+
         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
 
-        jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
+        jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
         if (!jni_remoteAddress)
         {
-            OIC_LOG(ERROR, TAG, "[BLE][Native] jni_remoteAddress is null");
-            return;
+            OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
         }
+
         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+        if (!remoteAddress)
+        {
+            OIC_LOG(ERROR, TAG, "remoteAddress is null");
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
 
         if (!strcmp(setAddress, remoteAddress))
         {
-            OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
+            OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
             (*env)->DeleteGlobalRef(env, jarrayObj);
-
-            CAReorderingGattList(index);
-            return;
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CALEClientReorderingList(index, g_gattObjectList);
         }
-    }OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
-    return;
-}
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+        (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
+    }
+
+    ca_mutex_unlock(g_gattObjectMutex);
+    OIC_LOG(DEBUG, TAG, "there are no target object");
+    return CA_STATUS_OK;
+}
 
-void CAReorderingGattList(uint32_t index)
+CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
 {
-    if (index >= g_gattObjectList->length)
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
+    VERIFY_NON_NULL(addr, TAG, "addr is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    ca_mutex_lock(g_gattObjectMutex);
+    if (!g_gattObjectList)
     {
-        return;
+        OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
+        ca_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
+        if (!jarrayObj)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
+        if (!jni_setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
+        if (!remoteAddress)
+        {
+            OIC_LOG(ERROR, TAG, "remoteAddress is null");
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (!strcmp(setAddress, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
+            (*env)->DeleteGlobalRef(env, jarrayObj);
+
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
+            ca_mutex_unlock(g_gattObjectMutex);
+            return CALEClientReorderingList(index, g_gattObjectList);
+        }
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+        (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
+    }
+
+    ca_mutex_unlock(g_gattObjectMutex);
+    OIC_LOG(DEBUG, TAG, "there are no target object");
+    return CA_STATUS_FAILED;
+}
+
+/**
+ * BT State List
+ */
+
+CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
+                                       uint16_t notificationState, uint16_t sendState)
+{
+    VERIFY_NON_NULL(address, TAG, "address is null");
+
+    CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
+    if (!newstate)
+    {
+        OIC_LOG(ERROR, TAG, "out of memory");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    if (strlen(address) > CA_MACADDR_SIZE)
+    {
+        OIC_LOG(ERROR, TAG, "address is not proper");
+        OICFree(newstate);
+        return CA_STATUS_FAILED;
+    }
+
+    strcpy(newstate->address, address);
+    newstate->connectedState = connectedState;
+    newstate->notificationState = notificationState;
+    newstate->sendState = sendState;
+    return CALEClientAddDeviceStateToList(newstate);
+}
+
+CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
+{
+    VERIFY_NON_NULL(state, TAG, "state is null");
+
+    ca_mutex_lock(g_deviceStateListMutex);
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "gdevice_list is null");
+        ca_mutex_unlock(g_deviceStateListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if (CALEClientIsDeviceInList(state->address))
+    {
+        CALEState_t* curState = CALEClientGetStateInfo(state->address);
+        if(!curState)
+        {
+            OIC_LOG(ERROR, TAG, "curState is null");
+            ca_mutex_unlock(g_deviceStateListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
+        {
+            state->notificationState = curState->notificationState;
+        }
+
+        // delete previous state for update new state
+        CAResult_t res = CALEClientRemoveDeviceState(state->address);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
+            ca_mutex_unlock(g_deviceStateListMutex);
+            return res;
+        }
+    }
+    u_arraylist_add(g_deviceStateList, state); // update new state
+    OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
+              state->connectedState, state->notificationState);
+
+    ca_mutex_unlock(g_deviceStateListMutex);
+    return CA_STATUS_OK;
+}
+
+bool CALEClientIsDeviceInList(const char* remoteAddress)
+{
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        return false;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            return false;
+        }
+
+        if (!strcmp(remoteAddress, state->address))
+        {
+            OIC_LOG(DEBUG, TAG, "the device is already set");
+            return true;
+        }
+        else
+        {
+            continue;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "there are no the device in list.");
+    return false;
+}
+
+CAResult_t CALEClientRemoveAllDeviceState()
+{
+    OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
+
+    ca_mutex_lock(g_deviceStateListMutex);
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        ca_mutex_unlock(g_deviceStateListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            continue;
+        }
+        OICFree(state);
+    }
+
+    OICFree(g_deviceStateList);
+    g_deviceStateList = NULL;
+    ca_mutex_unlock(g_deviceStateListMutex);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
+    VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcmp(state->address, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
+            OICFree(state);
+
+            CAResult_t res = CALEClientReorderingList(index, g_deviceStateList);
+            if(CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientReorderingList has failed");
+                return res;
+            }
+            return CA_STATUS_OK;
+        }
+    }
+
+    return CA_STATUS_FAILED;
+}
+
+CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        return NULL;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcmp(state->address, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
+            return state;
+        }
+    }
+    return NULL;
+}
+
+bool CALEClientIsConnectedDevice(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+
+    ca_mutex_lock(g_deviceStateListMutex);
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        ca_mutex_unlock(g_deviceStateListMutex);
+        return false;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcmp(state->address, remoteAddress))
+        {
+            OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
+
+            if (STATE_CONNECTED == state->connectedState)
+            {
+                ca_mutex_unlock(g_deviceStateListMutex);
+                return true;
+            }
+            else
+            {
+                ca_mutex_unlock(g_deviceStateListMutex);
+                return false;
+            }
+        }
+    }
+    ca_mutex_unlock(g_deviceStateListMutex);
+    return false;
+}
+
+bool CALEClientIsSetCharacteristic(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+
+    ca_mutex_lock(g_deviceStateListMutex);
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        ca_mutex_unlock(g_deviceStateListMutex);
+        return false;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcmp(state->address, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
+
+            if (STATE_CHARACTER_SET == state->notificationState)
+            {
+                ca_mutex_unlock(g_deviceStateListMutex);
+                return true;
+            }
+            else
+            {
+                ca_mutex_unlock(g_deviceStateListMutex);
+                return false;
+            }
+        }
+    }
+
+    ca_mutex_unlock(g_deviceStateListMutex);
+    return false;
+}
+
+void CALEClientCreateDeviceList()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
+
+    // create new object array
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
+
+        g_gattObjectList = u_arraylist_create();
+    }
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
+
+        g_deviceStateList = u_arraylist_create();
+    }
+
+    if (!g_deviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "Create g_deviceList");
+
+        g_deviceList = u_arraylist_create();
+    }
+}
+
+CAResult_t CALEClientReorderingList(uint32_t index, u_arraylist_t *list)
+{
+    if (!list)
+    {
+        OIC_LOG(ERROR, TAG, "list is null");
+        return CA_STATUS_FAILED;
+    }
+
+    if (index >= list->length)
+    {
+        OIC_LOG(ERROR, TAG, "index is not available");
+        return CA_STATUS_FAILED;
     }
 
-    if (index < g_gattObjectList->length - 1)
+    if (index < list->length - 1)
     {
-        memmove(&g_gattObjectList->data[index], &g_gattObjectList->data[index + 1],
-                (g_gattObjectList->length - index - 1) * sizeof(void *));
+        memmove(&list->data[index], &list->data[index + 1],
+                (list->length - index - 1) * sizeof(void *));
     }
 
-    g_gattObjectList->size--;
-    g_gattObjectList->length--;
+    list->size--;
+    list->length--;
+
+    return CA_STATUS_OK;
 }
 
 /**
  * Check Sent Count for remove g_sendBuffer
  */
-void CANativeupdateSendCnt(JNIEnv *env)
+void CALEClientUpdateSendCnt(JNIEnv *env)
 {
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     // mutex lock
     ca_mutex_lock(g_threadMutex);
 
@@ -1746,170 +2967,687 @@ void CANativeupdateSendCnt(JNIEnv *env)
         }
         // notity the thread
         ca_cond_signal(g_threadCond);
-        g_isFinishSendData = JNI_TRUE;
+        CALEClientSetSendFinishFlag(true);
         OIC_LOG(DEBUG, TAG, "set signal for send data");
     }
     // mutex unlock
     ca_mutex_unlock(g_threadMutex);
 }
 
+CAResult_t CALEClientInitGattMutexVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if (NULL == g_bleReqRespClientCbMutex)
+    {
+        g_bleReqRespClientCbMutex = ca_mutex_new();
+        if (NULL == g_bleReqRespClientCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_bleServerBDAddressMutex)
+    {
+        g_bleServerBDAddressMutex = ca_mutex_new();
+        if (NULL == g_bleServerBDAddressMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_threadMutex)
+    {
+        g_threadMutex = ca_mutex_new();
+        if (NULL == g_threadMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_threadSendMutex)
+    {
+        g_threadSendMutex = ca_mutex_new();
+        if (NULL == g_threadSendMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_threadSendCBMutex)
+    {
+        g_threadSendCBMutex = ca_mutex_new();
+        if (NULL == g_threadSendCBMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_deviceListMutex)
+    {
+        g_deviceListMutex = ca_mutex_new();
+        if (NULL == g_deviceListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_gattObjectMutex)
+    {
+        g_gattObjectMutex = ca_mutex_new();
+        if (NULL == g_gattObjectMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_deviceStateListMutex)
+    {
+        g_deviceStateListMutex = ca_mutex_new();
+        if (NULL == g_deviceStateListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_SendFinishMutex)
+    {
+        g_SendFinishMutex = ca_mutex_new();
+        if (NULL == g_SendFinishMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_writeCharacteristicCBMutex)
+    {
+        g_writeCharacteristicCBMutex = ca_mutex_new();
+        if (NULL == g_writeCharacteristicCBMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_theSendRequestMutex)
+    {
+        g_theSendRequestMutex = ca_mutex_new();
+        if (NULL == g_theSendRequestMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALEClientTerminateGattMutexVariables()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    ca_mutex_free(g_bleReqRespClientCbMutex);
+    g_bleReqRespClientCbMutex = NULL;
+
+    ca_mutex_free(g_bleServerBDAddressMutex);
+    g_bleServerBDAddressMutex = NULL;
+
+    ca_mutex_free(g_threadMutex);
+    g_threadMutex = NULL;
+
+    ca_mutex_free(g_threadSendMutex);
+    g_threadSendMutex = NULL;
+
+    ca_mutex_free(g_threadSendCBMutex);
+    g_threadSendCBMutex = NULL;
+
+    ca_mutex_free(g_deviceListMutex);
+    g_deviceListMutex = NULL;
+
+    ca_mutex_free(g_SendFinishMutex);
+    g_SendFinishMutex = NULL;
+
+    ca_mutex_free(g_writeCharacteristicCBMutex);
+    g_writeCharacteristicCBMutex = NULL;
+
+    ca_mutex_free(g_theSendRequestMutex);
+    g_theSendRequestMutex = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CALEClientSetSendFinishFlag(bool flag)
+{
+    OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
+
+    ca_mutex_lock(g_SendFinishMutex);
+    g_isFinishedSendData = flag;
+    ca_mutex_unlock(g_SendFinishMutex);
+}
+
+void CALEClientSetWriteCharacteristicCBFlag(bool flag)
+{
+    OIC_LOG_V(DEBUG, TAG, "g_isReceivedWriteCB is %d", flag);
+
+    ca_mutex_lock(g_writeCharacteristicCBMutex);
+    g_isReceivedWriteCB = flag;
+    ca_mutex_unlock(g_writeCharacteristicCBMutex);
+}
+
+void CALEClientSetTheSendRequestFlag(bool flag)
+{
+    OIC_LOG_V(DEBUG, TAG, "g_isRequestedSend is %d", flag);
+
+    ca_mutex_lock(g_theSendRequestMutex);
+    g_isRequestedSend = flag;
+    ca_mutex_unlock(g_theSendRequestMutex);
+}
+
+/**
+ * adapter common
+ */
+
+CAResult_t CAStartBLEGattClient()
+{
+    CAResult_t res = CALEClientStartMulticastServer();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
+    }
+    else
+    {
+        g_isStartedLEClient = true;
+    }
+
+    return res;
+}
+
+void CAStopBLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return;
+    }
+
+    bool isAttached = false;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return;
+        }
+        isAttached = true;
+    }
+
+    CAResult_t ret = CALEClientDisconnectAll(env);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
+    }
+
+    ret = CALEClientStopScan();
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
+    }
+
+    ca_cond_signal(g_threadCond);
+    ca_cond_signal(g_threadSendCond);
+    g_isStartedLEClient = false;
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+}
+
+void CATerminateBLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
+    CALEClientTerminate();
+}
+
+CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char  *data,
+                                                const uint32_t dataLen, CALETransferType_t type,
+                                                const int32_t position)
+{
+    OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+    VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
+
+    return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
+}
+
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, uint32_t dataLen)
+{
+    OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    return CALEClientSendMulticastMessage(data, dataLen);
+}
+
+void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    ca_mutex_lock(g_bleReqRespClientCbMutex);
+    g_CABLEClientDataReceivedCallback = callback;
+    ca_mutex_unlock(g_bleReqRespClientCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CALEClientInitialize(handle);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAGetLEAddress(char **local_address)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(local_address, TAG, "local_address is null");
+    CAResult_t res = CALEClientGetInterfaceInfo(local_address);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(INFO, TAG, "it didn't get local address");
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CARegisterLeScanCallback(JNIEnv *env, jobject obj,
-                                                             jobject callback)
+Java_org_iotivity_jar_caleclientinterface_CARegisterLeScanCallback(JNIEnv *env, jobject obj,
+                                                                   jobject callback)
 {
     OIC_LOG(DEBUG, TAG, "CARegisterLeScanCallback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
 
     g_leScanCallback = (*env)->NewGlobalRef(env, callback);
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CARegisterLeGattCallback(JNIEnv *env, jobject obj,
-                                                             jobject callback)
+Java_org_iotivity_jar_caleclientinterface_CARegisterLeGattCallback(JNIEnv *env, jobject obj,
+                                                                   jobject callback)
 {
     OIC_LOG(DEBUG, TAG, "CARegisterLeGattCallback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
 
     g_leGattCallback = (*env)->NewGlobalRef(env, callback);
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeScanCallback(JNIEnv *env, jobject obj, jobject device,
-                                                     jint rssi, jbyteArray scanRecord)
+Java_org_iotivity_jar_caleclientinterface_CALeScanCallback(JNIEnv *env, jobject obj,
+                                                           jobject device, jint rssi,
+                                                           jbyteArray scanRecord)
 {
-    CANativeAddScanDeviceToList(env, device);
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(device, TAG, "device is null");
+
+    CAResult_t res = CALEClientAddScanDeviceToList(env, device);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
+    }
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattConnectionStateChangeCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattConnectionStateChangeCallback(JNIEnv *env, jobject obj,
-                                                                          jobject gatt, jint status,
-                                                                          jint newstate)
+Java_org_iotivity_jar_caleclientinterface_CALeGattConnectionStateChangeCallback(JNIEnv *env,
+                                                                                jobject obj,
+                                                                                jobject gatt,
+                                                                                jint status,
+                                                                                jint newstate)
 {
     OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
             newstate);
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
 
     if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
     {
-        if (gatt)
+        jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+        if (!jni_address)
+        {
+            goto error_exit;
+        }
+
+        const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+        if (address)
         {
-            CANativeAddGattobjToList(env, gatt);
-            CANativeLEDiscoverServices(env, gatt);
+            CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
+                                                         STATE_CHARACTER_NO_CHANGE,
+                                                         STATE_SEND_NONE);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+                (*env)->ReleaseStringUTFChars(env, jni_address, address);
+                goto error_exit;
+            }
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+        }
+
+        CAResult_t res = CALEClientAddGattobjToList(env, gatt);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
+            goto error_exit;
+        }
+
+        res = CALEClientDiscoverServices(env, gatt);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
+            goto error_exit;
         }
     }
     else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
     {
+        CAResult_t res = CALEClientStartScan();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        }
+
+        jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+        if (!jni_address)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
+        }
 
+        const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+        if (address)
+        {
+            res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
+                                              STATE_CHARACTER_NO_CHANGE,
+                                              STATE_SEND_NONE);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+            }
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+        }
+
+        res = CALEClientGattClose(env, gatt);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
+        }
+
+        ca_cond_signal(g_threadSendCond);
     }
-    else // other error
+    else // error
     {
-        CANativeSendFinish(env, gatt);
+        // update state
+        jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+        if (!jni_address)
+        {
+            OIC_LOG(ERROR, TAG, "jni_address is null");
+            goto error_exit;
+
+        }
+
+        const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+        if (address)
+        {
+            CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
+                                                         STATE_CHARACTER_NO_CHANGE,
+                                                         STATE_SEND_FAILED);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+            }
+        }
+        (*env)->ReleaseStringUTFChars(env, jni_address, address);
+
+        goto error_exit;
     }
+    return;
+
+    // error label.
+error_exit:
+
+    CALEClientSendFinish(env, gatt);
+    ca_cond_signal(g_threadSendCond);
+    return;
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattServicesDiscoveredCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServicesDiscoveredCallback(JNIEnv *env, jobject obj,
-                                                                       jobject gatt, jint status)
+Java_org_iotivity_jar_caleclientinterface_CALeGattServicesDiscoveredCallback(JNIEnv *env,
+                                                                             jobject obj,
+                                                                             jobject gatt,
+                                                                             jint status)
 {
     OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
 
     if (0 != status) // discovery error
     {
-        CANativeSendFinish(env, gatt);
+        CALEClientSendFinish(env, gatt);
+        ca_cond_signal(g_threadSendCond);
         return;
     }
 
-    // read Characteristic
-//    CANativeReadCharacteristic(env, gatt);
-
-    CAResult_t ret = CANativeSetCharacteristicNotification(env, gatt, IOTIVITY_GATT_RX_UUID);
-    if (CA_STATUS_OK != ret) // SetCharacteristicNoti is failed
+    jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+    if (!jni_address)
     {
-        CANativeSendFinish(env, gatt);
+        CALEClientSendFinish(env, gatt);
+        ca_cond_signal(g_threadSendCond);
         return;
     }
 
-//        jstring data = (*env)->NewStringUTF(env, "HelloWorld");
-    jobject jni_obj_character = CANativeCreateGattCharacteristic(env, gatt, g_sendBuffer);
-    if (!jni_obj_character)
+    const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
     {
-        CANativeSendFinish(env, gatt);
+        CALEClientSendFinish(env, gatt);
+        ca_cond_signal(g_threadSendCond);
         return;
     }
 
-    sleep(1);
-    ret = CANativeWriteCharacteristic(env, gatt, jni_obj_character);
-    if (CA_STATUS_FAILED == ret)
+    if (!CALEClientIsSetCharacteristic(address))
     {
-        CANativeSendFinish(env, gatt);
-        return;
+        jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
+        if (!jni_uuid)
+        {
+            OIC_LOG(ERROR, TAG, "jni_uuid is null");
+            goto error_exit;
+        }
+
+        jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
+        if (!jni_obj_GattCharacteristic)
+        {
+            OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
+            goto error_exit;
+        }
+
+        CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
+                                                                 jni_obj_GattCharacteristic);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
+            goto error_exit;
+        }
+
+        res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientSetUUIDToDescriptor has failed");
+            goto error_exit;
+        }
+
+        res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
+                                          STATE_SEND_NONE);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+            goto error_exit;
+        }
+    }
+    else
+    {
+        CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+            goto error_exit;
+        }
     }
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    return;
+
+    // error label.
+error_exit:
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    CALEClientSendFinish(env, gatt);
+    ca_cond_signal(g_threadSendCond);
+    return;
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattCharacteristicReadCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicReadCallback(JNIEnv *env, jobject obj,
-                                                                       jobject gatt,
-                                                                       jobject characteristic,
-                                                                       jbyteArray data, jint status)
+Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicReadCallback(JNIEnv *env,
+                                                                             jobject obj,
+                                                                             jobject gatt,
+                                                                             jobject characteristic,
+                                                                             jbyteArray data,
+                                                                             jint status)
 {
     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicReadCallback - status : %d", status);
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattCharacteristicWritjclasseCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicWriteCallback(JNIEnv *env, jobject obj,
-                                                                        jobject gatt,
-                                                                        jobject characteristic,
-                                                                        jbyteArray data,
-                                                                        jint status)
+Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicWriteCallback(
+        JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data,
+        jint status)
 {
     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
 
-    jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
-    const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    ca_mutex_lock(g_threadSendCBMutex);
+    if (!g_isRequestedSend)
+    {
+        OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - waiting");
+        ca_cond_wait(g_threadSendCBCond, g_threadSendCBMutex);
+    }
+    ca_mutex_unlock(g_threadSendCBMutex);
 
     jboolean isCopy;
-    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s",
-            (char*)(*env)->GetByteArrayElements(env, data, &isCopy));
+    char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
 
-#ifdef DEBUG_MODE
-    CANativeSendFinish(env, gatt);
-#endif
+    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
+
+    // send success & signal
+    jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+    if (!jni_address)
+    {
+        goto error_exit;
+    }
 
-    if (0 != status) // error case
+    const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
+    {
+        goto error_exit;
+    }
+
+    if (GATT_SUCCESS != status) // error case
+    {
+        OIC_LOG(ERROR, TAG, "send failure");
+        CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
+                                                     STATE_SEND_FAILED);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+        }
+        CALEClientSendFinish(env, gatt);
+    }
+    else
     {
-        CANativeSendFinish(env, gatt);
+        OIC_LOG(DEBUG, TAG, "send success");
+        CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
+                                                     STATE_SEND_SUCCESS);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+        }
+        CALEClientUpdateSendCnt(env);
     }
+
+    CALEClientSetWriteCharacteristicCBFlag(true);
+    CALEClientSetTheSendRequestFlag(false);
+    ca_cond_signal(g_threadSendCond);
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    return;
+
+    // error label.
+error_exit:
+
+    CALEClientSetWriteCharacteristicCBFlag(true);
+    CALEClientSetTheSendRequestFlag(false);
+    CALEClientSendFinish(env, gatt);
+    ca_cond_signal(g_threadSendCond);
+    return;
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattCharacteristicChangedCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicChangedCallback(JNIEnv *env, jobject obj,
-                                                                          jobject gatt,
-                                                                          jobject characteristic,
-                                                                          jbyteArray data)
+Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicChangedCallback(
+        JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data)
 {
     OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
+    VERIFY_NON_NULL_VOID(data, TAG, "data is null");
 
     // get Byte Array and covert to char*
     jint length = (*env)->GetArrayLength(env, data);
@@ -1917,81 +3655,116 @@ Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicChangedCallback(JNIEnv
     jboolean isCopy;
     jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
 
-    char* recevicedData = (char*) OICMalloc(sizeof(char) * length);
-    if (NULL == recevicedData)
+    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %s",
+            jni_byte_responseData);
+
+    char* receivedData = (char*) OICMalloc(sizeof(char) * length + 1);
+    if (!receivedData)
     {
         OIC_LOG(ERROR, TAG, "recevicedData is null");
-        CANativeSendFinish(env, gatt);
-
         return;
     }
 
-    memcpy(recevicedData, (const char*) jni_byte_responseData, length);
-    recevicedData[length] = '\0';
+    memcpy(receivedData, (const char*) jni_byte_responseData, length);
+    receivedData[length] = '\0';
     (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
 
-    jstring jni_address = CANativeGetAddressFromGattObj(env, gatt);
+    jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+    if (!jni_address)
+    {
+        OIC_LOG(ERROR, TAG, "jni_address is null");
+        OICFree(receivedData);
+        return;
+    }
+
     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is null");
+        OICFree(receivedData);
+        return;
+    }
 
     OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %s, %d",
-            recevicedData, length);
+              receivedData, length);
 
-    // callback
-    g_packetReceiveCallback(address, recevicedData);
-    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    ca_mutex_lock(g_bleServerBDAddressMutex);
+    uint32_t sentLength = 0;
+    g_CABLEClientDataReceivedCallback(address, OIC_GATT_SERVICE_UUID, receivedData, length,
+                                      &sentLength);
+    ca_mutex_unlock(g_bleServerBDAddressMutex);
 
-    // LE disconnect and finish BLE write routine
-    CANativeSendFinish(env, gatt);
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattDescriptorReadCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattDescriptorReadCallback(JNIEnv *env, jobject obj,
-                                                                   jobject gatt, jobject descriptor,
-                                                                   jint status)
+Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorReadCallback(JNIEnv *env, jobject obj,
+                                                                         jobject gatt,
+                                                                         jobject descriptor,
+                                                                         jint status)
 {
     OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorReadCallback - status %d: ", status);
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattDescriptorWriteCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
-                                                                    jobject gatt,
-                                                                    jobject descriptor, jint status)
+Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
+                                                                          jobject gatt,
+                                                                          jobject descriptor,
+                                                                          jint status)
 {
     OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
+
+    CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+        goto error_exit;
+    }
+    return;
+
+// error label.
+error_exit:
+
+    CALEClientSendFinish(env, gatt);
+    ca_cond_signal(g_threadSendCond);
+    return;
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattReliableWriteCompletedCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattReliableWriteCompletedCallback(JNIEnv *env, jobject obj,
-                                                                           jobject gatt,
-                                                                           jint status)
+Java_org_iotivity_jar_caleclientinterface_CALeGattReliableWriteCompletedCallback(JNIEnv *env,
+                                                                                 jobject obj,
+                                                                                 jobject gatt,
+                                                                                 jint status)
 {
     OIC_LOG_V(DEBUG, TAG, "CALeGattReliableWriteCompletedCallback - status %d: ", status);
 }
 
 /*
- * Class:     com_iotivity_jar_caleinterface
+ * Class:     org_iotivity_jar_caleinterface
  * Method:    CALeGattReadRemoteRssiCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
  */
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattReadRemoteRssiCallback(JNIEnv *env, jobject obj,
-                                                                   jobject gatt, jint rssi,
-                                                                   jint status)
+Java_org_iotivity_jar_caleclientinterface_CALeGattReadRemoteRssiCallback(JNIEnv *env, jobject obj,
+                                                                         jobject gatt, jint rssi,
+                                                                         jint status)
 {
     OIC_LOG_V(DEBUG, TAG, "CALeGattReadRemoteRssiCallback - rssi %d,  status %d: ", rssi, status);
 }
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h
new file mode 100644 (file)
index 0000000..17152be
--- /dev/null
@@ -0,0 +1,597 @@
+/******************************************************************
+ *
+ * Copyright 2014 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.
+ *
+ ******************************************************************/
+
+/**
+ * @file caleclient.h
+ * @brief This file contains the APIs for BT LE communications.
+ */
+#ifndef CA_LECLIENT_H_
+#define CA_LECLIENT_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+#include "jni.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static const uint16_t STATE_CHARACTER_SET = 2;
+static const uint16_t STATE_CHARACTER_UNSET = 1;
+static const uint16_t STATE_CHARACTER_NO_CHANGE = 0;
+
+static const uint16_t STATE_SEND_NONE = 0;
+static const uint16_t STATE_SEND_SUCCESS = 1;
+static const uint16_t STATE_SEND_FAILED = 2;
+
+static const uint32_t STATE_CONNECTED = 2;
+static const uint32_t STATE_DISCONNECTED = 0;
+
+typedef struct le_state_info
+{
+    char address[CA_MACADDR_SIZE];
+    uint32_t connectedState;
+    uint16_t notificationState;
+    uint16_t sendState;
+} CALEState_t;
+
+/**
+ * @brief Callback to be notified on reception of any data from remote devices.
+ * @param  address                [IN] MAC address of remote device.
+ * @param  data                   [IN] Data received from remote device.
+ * @return None
+ * @pre  Callback must be registered using CALESetCallback(CAPacketReceiveCallback callback)
+ */
+typedef void (*CAPacketReceiveCallback)(const char *address, const char *data);
+
+/**
+ * @brief   initialize JNI object
+ * @return  None
+ */
+void CALEClientJniInit();
+
+/**
+ * @brief   set context of application
+ * @return  None
+ */
+void CALEClientJNISetContext();
+
+/**
+ * @brief   create interface object and initialize the object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientCreateJniInterfaceObject();
+
+/**
+ * @brief   initialize client for BLE
+ * @param   handle                [IN] thread pool handle object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientInitialize(ca_thread_pool_t handle);
+
+/**
+ * @brief   terminate client for BLE
+ * @return  None
+ */
+void CALEClientTerminate();
+
+/**
+ * @brief   for destroy sending routine
+ * @param   env                   [IN] JNI interface pointer
+ * @param   gatt                  [IN] Gatt profile object
+ * @return  None
+ */
+void CALEClientSendFinish(JNIEnv *env, jobject gatt);
+
+/**
+ * @brief   send data for unicast (interface)
+ * @param   address               [IN] remote address
+ * @param   data                  [IN] data for transmission
+ * @param   dataLen               [IN] data length
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientSendUnicastMessage(const char *address, const char *data,
+                                        const uint32_t dataLen);
+
+/**
+ * @brief   send data for multicast (interface)
+ * @param   data                  [IN] data for transmission
+ * @param   dataLen               [IN] data length
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientSendMulticastMessage(const char *data, const uint32_t dataLen);
+
+/**
+ * @brief   start unicast server
+ * @param   address               [IN] remote address
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientStartUnicastServer(const char *address);
+
+/**
+ * @brief   start multicast server (start discovery)
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientStartMulticastServer();
+
+/**
+ * @brief   stop unicast server
+ * @return  None
+ */
+void CALEClientStopUnicastServer();
+
+/**
+ * @brief   stop multicast server (stop discovery)
+ * @return  None
+ */
+void CALEClientStopMulticastServer();
+
+/**
+ * @brief   set this callback for receiving data packets from peer devices.
+ * @param   callback              [IN] callback to be notified on reception of
+ *                                unicast/multicast data packets.
+ * @return  None
+ */
+void CALEClientSetCallback(CAPacketReceiveCallback callback);
+
+/**
+ * @brief   get local address (interface)
+ * @param   address               [OUT] local address
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientGetInterfaceInfo(char **address);
+
+/**
+ * @brief   get local address (implement)
+ * @param   address               [OUT] local address
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientGetLocalAddress(char** address);
+
+/**
+ * @brief   send data for unicast (implement)
+ * @param   address               [IN] remote address
+ * @param   data                  [IN] data for transmission
+ * @param   dataLen               [IN] data length
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientSendUnicastMessageImpl(const char *address, const char *data,
+                                            const uint32_t dataLen);
+
+/**
+ * @brief   send data for multicast (implement)
+ * @param   env                   [IN] JNI interface pointer
+ * @param   data                  [IN] data for transmission
+ * @param   dataLen               [IN] data length
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const char *data,
+                                              const uint32_t dataLen);
+
+/**
+ * @brief   check whether it is connected or not with remote address.
+ * @param   address               [IN] remote address
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALECheckSendState(const char* address);
+
+/**
+ * @brief   send data to remote device.
+ *          if it isn't connected yet. connect LE before try to send data
+ * @param   env                   [IN] JNI interface pointer
+ * @param   device                [IN] bluetooth device object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientSendData(JNIEnv *env, jobject device);
+
+/**
+ * @brief   get address from bluetooth gatt object
+ * @param   env                   [IN] JNI interface pointer
+ * @param   gatt                  [IN] Gatt profile object
+ * @return  bluetooth address
+ */
+jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt);
+
+/**
+ * @brief   get remote address from bluetooth socket object
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothSocketObj    [IN] bluetooth socket
+ * @return  bluetooth address
+ */
+jstring CALEClientGetRemoteAddress(JNIEnv *env, jobject bluetoothSocketObj);
+
+/**
+ * @brief   close gatt
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] gatt profile object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt);
+
+/**
+ * @brief   start to scan whole bluetooth devices (interface)
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientStartScan();
+
+/**
+ * @brief   start to scan whole bluetooth devices (implement)
+ * @param   env                   [IN] JNI interface pointer
+ * @param   callback              [IN] callback to receive device object by scanning
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback);
+
+/**
+ * @brief   start to scan target bluetooth devices for service uuid (implement)
+ * @param   env                   [IN] JNI interface pointer
+ * @param   uuids                 [IN] target UUID
+ * @param   callback              [IN] callback to receive device object by scanning
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids,
+                                           jobject callback);
+
+/**
+ * @brief   get uuid object
+ * @param   env                   [IN] JNI interface pointer
+ * @param   uuid                  [IN] uuid
+ * @return  uuid object
+ */
+jobject CALEClientGetUUIDObject(JNIEnv *env, const char *uuid);
+
+/**
+ * @brief   stop scan (interface)
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientStopScan();
+
+/**
+ * @brief   stop scan (implement)
+ * @param   env                   [IN] JNI interface pointer
+ * @param   callback              [IN] callback to receive device object by scanning
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback);
+
+/**
+ * @brief   connect to gatt server hosted
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothDevice       [IN] bluetooth Device object
+ * @param   autoconnect           [IN] whether to directly connect to the remote device(false) or
+ *                                     to automatically connect as soon as the remote device
+ *                                     becomes available
+ * @param   callback              [IN] callback for connection state change
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
+                             jobject callback);
+
+/**
+ * @brief   disconnect to gatt server by a target device
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] Gatt profile object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt);
+
+/**
+ * @brief   disconnect to gatt server by whole devices
+ * @param   env                   [IN] JNI interface pointer
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientDisconnectAll(JNIEnv *env);
+
+/**
+ * @brief   start discovery server
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] Gatt profile object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt);
+
+/**
+ * @brief   create GattCharacteristic and call CALEClientWriteCharacteristicImpl
+ *          for request to write gatt characteristic
+ * @param   env                   [IN] JNI interface pointer
+ * @param   gatt                  [IN] Gatt profile object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt);
+
+/**
+ * @brief   request to write gatt characteristic
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] Gatt profile object
+ * @param   gattCharacteristic    [IN] characteristic object that contain data to send
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
+                                             jobject gattCharacteristic);
+
+/**
+ * @brief   request to read gatt characteristic
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] Gatt profile object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt);
+
+/**
+ * @brief   enable notification for a target device
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] Gatt profile object
+ * @param   characteristic        [IN] Characteristic object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
+                                                  jobject characteristic);
+
+/**
+ * @brief   create gatt characteristic object
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] Gatt profile object
+ * @param   data                  [IN] for make Characteristic with data
+ * @return  Gatt Characteristic object
+ */
+jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data);
+
+/**
+ * @brief   get gatt service
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] Gatt profile object
+ * @param   characterUUID         [IN] for make BluetoothGattCharacteristic object
+ * @return  Gatt Service
+ */
+jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID);
+
+/**
+ * @brief   get value from characteristic
+ * @param   env                   [IN] JNI interface pointer
+ * @param   characteristic        [IN] Characteristic object
+ * @return  value in characteristic
+ */
+jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic);
+
+/**
+ * @brief   create UUID List
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientCreateUUIDList();
+
+/**
+ * @brief   set UUID to descriptor
+ * @param   env                   [IN] JNI interface pointer
+ * @param   bluetoothGatt         [IN] Gatt profile object
+ * @param   characteristic        [IN] Characteristic object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
+                                         jobject characteristic);
+
+/**
+ * BluetoothDevice List
+ */
+/**
+ * @brief   add device object to scan device list
+ * @param   env                   [IN] JNI interface pointer
+ * @param   device                [IN] bluetooth device object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device);
+
+/**
+ * @brief   check whether the device exist in list or not
+ * @param   env                   [IN] JNI interface pointer
+ * @param   remoteAddress         [IN] remote address
+ * @return  true or false
+ */
+bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char *remoteAddress);
+
+/**
+ * @brief   remove all devices in scan device list
+ * @param   env                   [IN] JNI interface pointer
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env);
+
+/**
+ * @brief   remove target device in scan device list
+ * @param   env                   [IN] JNI interface pointer
+ * @param   remoteAddress         [IN] remote address
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring remoteAddress);
+
+/**
+ * BluetoothGatt List
+ */
+
+/**
+ * @brief   add gatt object to gatt object list
+ * @param   env                   [IN] JNI interface pointer
+ * @param   gatt                  [IN] Gatt profile object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt);
+
+/**
+ * @brief   check whether the gatt object exist in list or not
+ * @param   env                   [IN] JNI interface pointer
+ * @param   remoteAddress         [IN] remote address
+ * @return  true or false
+ */
+bool CALEClientIsGattObjInList(JNIEnv *env, const char *remoteAddress);
+
+/**
+ * @brief   get the gatt object
+ * @param   env                   [IN] JNI interface pointer
+ * @param   remoteAddress         [IN] remote address
+ * @return  gatt object
+ */
+jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress);
+
+/**
+ * @brief   remove all gatt objects in gatt object list
+ * @param   env                   [IN] JNI interface pointer
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env);
+
+/**
+ * @brief   remove target device in gatt object list
+ * @param   env                   [IN] JNI interface pointer
+ * @param   gatt                  [IN] Gatt profile object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt);
+
+/**
+ * @brief   remove gatt object of target device for address in gatt object list
+ * @param   env                   [IN] JNI interface pointer
+ * @param   gatt                  [IN] Gatt profile object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr);
+
+/**
+ * BT State Info List
+ */
+
+/**
+ * @brief   update new state information
+ * @param   address               [IN] remote address
+ * @param   connectedState        [IN] connection state
+ * @param   notificationState     [IN] whether characteristic notification already set or not
+ * @param   sendState             [IN] whether sending was success or not
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
+                                       uint16_t notificationState, uint16_t sendState);
+
+/**
+ * @brief   add new state to state list
+ * @param   state                 [IN] new state
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state);
+
+/**
+ * @brief   check whether the remote address is existed or not.
+ * @param   address               [IN] remote address
+ * @return  true or false
+ */
+bool CALEClientIsDeviceInList(const char *remoteAddress);
+
+/**
+ * @brief   remove all device states
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientRemoveAllDeviceState();
+
+/**
+ * @brief   remove the device state for a remote device
+ * @param   remoteAddress         [IN] remote address
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress);
+
+/**
+ * @brief   get state information for a remote device
+ * @param   remoteAddress         [IN] remote address
+ * @return  CALEState_t
+ */
+CALEState_t* CALEClientGetStateInfo(const char* remoteAddress);
+
+/**
+ * @brief   check whether the remote address is connected or not.
+ * @param   remoteAddress         [IN] remote address
+ * @return  true or false
+ */
+bool CALEClientIsConnectedDevice(const char* remoteAddress);
+
+/**
+ * @brief   check whether the remote address set CharacteristicNotification or not
+ * @param   remoteAddress         [IN] remote address
+ * @return  true or false
+ */
+bool CALEClientIsSetCharacteristic(const char* remoteAddress);
+
+/**
+ * @brief   create scan device list
+ * @return  None
+ */
+void CALEClientCreateDeviceList();
+
+/**
+ * @brief   Reordering for device state list
+ * @param   index                 [IN] index of device list that want to reordering
+ * @param   list                  [IN] the list to reorder
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientReorderingList(uint32_t index, u_arraylist_t *list);
+
+/**
+ * @brief   update the counter which data is sent to remote device
+ * @param   env                   [IN] JNI interface pointer
+ * @return  None
+ */
+void CALEClientUpdateSendCnt(JNIEnv *env);
+
+/**
+ * @brief   initialize mutex
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEClientInitGattMutexVaraibles();
+
+/**
+ * @brief   terminate mutex
+ * @return  None
+ */
+void CALEClientTerminateGattMutexVariables();
+
+/**
+ * @brief   set send finish flag
+ * @param   flag                  [IN] flag
+ * @return  None
+ */
+void CALEClientSetSendFinishFlag(bool flag);
+
+/**
+ * @brief   set the flag whether WriteCharacteristicCB is called
+ * @param   flag                  [IN] flag
+ * @return  None
+ */
+void CALEClientSetWriteCharacteristicCBFlag(bool flag);
+
+/**
+ * @brief   set the flag whether Send Request is called
+ * @param   flag                  [IN] flag
+ * @return  None
+ */
+void CALEClientSetTheSendRequestFlag(bool flag);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
index e626192..d6874fa 100644 (file)
 #include <android/log.h>
 #include "logger.h"
 #include "calenwmonitor.h"
+#include "caleclient.h"
+#include "caleserver.h"
 #include "caleutils.h"
-#include "com_iotivity_jar_caleinterface.h"
+#include "caleinterface.h"
+#include "caadapterutils.h"
+
+#include "camutex.h"
+
+#include "org_iotivity_jar_caleclientinterface.h"
 
 #define TAG PCF("CA_LE_MONITOR")
 
+#define BT_STATE_ON (12)
+#define BT_STATE_OFF (10)
+
 static JavaVM *g_jvm;
-static jobject g_context;
-static CALENetStateChantedCallback g_networkChangeCb = NULL;
+
+/**
+ * @var gCALEDeviceStateChangedCallback
+ * @brief Maintains the callback to be notified on device state changed.
+ */
+static CALEDeviceStateChangedCallback gCALEDeviceStateChangedCallback = NULL;
+
+/**
+ * @var gCALEDeviceStateChangedCbMutex
+ * @brief Mutex to synchronize access to the deviceStateChanged Callback when the state
+ *           of the LE adapter gets change.
+ */
+static ca_mutex gCALEDeviceStateChangedCbMutex = NULL;
 
 //getting context
-void CALENetworkMonitorJNISetContext(JNIEnv *env, jobject context)
+void CALENetworkMonitorJNISetContext()
 {
-    OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJNISetContext");
+    OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJNISetContext - it is not supported");
+}
 
-    if (context == NULL)
+//getting jvm
+void CALENetworkMonitorJniInit()
+{
+    OIC_LOG(DEBUG, TAG, "CALENetworkMonitorJniInit");
+    g_jvm = CANativeJNIGetJavaVM();
+}
+
+void CALESetNetStateCallback(CALEDeviceStateChangedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "CALESetNetStateCallback");
+    gCALEDeviceStateChangedCallback = callback;
+}
+
+CAResult_t CAInitializeLEAdapter()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CALENetworkMonitorJNISetContext();
+    CALENetworkMonitorJniInit();
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAInitLENwkMonitorMutexVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (NULL == gCALEDeviceStateChangedCbMutex)
     {
-        OIC_LOG(DEBUG, TAG, "context is null");
+        gCALEDeviceStateChangedCbMutex = ca_mutex_new();
+        if (NULL == gCALEDeviceStateChangedCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
     }
 
-    g_context = (*env)->NewGlobalRef(env, context);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+
 }
 
-//getting jvm
-void CALeNetworkMonitorJniInit(JNIEnv *env, JavaVM *jvm)
+void CATerminateLENwkMonitorMutexVaraibles()
 {
-    OIC_LOG(DEBUG, TAG, "CALeNetworkMonitorJniInit");
-    g_jvm = jvm;
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    ca_mutex_free(gCALEDeviceStateChangedCbMutex);
+    gCALEDeviceStateChangedCbMutex = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-void CALESetNetStateCallback(CALENetStateChantedCallback callback)
+CAResult_t CAGetLEAdapterState()
 {
-    OIC_LOG(DEBUG, TAG, "CALESetNetStateCallback");
-    g_networkChangeCb = callback;
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    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, "Could not get 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;
+    }
+
+    if (!CALEIsEnableBTAdapter(env))
+    {
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAInitializeLENetworkMonitor()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CAResult_t res = CAInitLENwkMonitorMutexVaraibles();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CAInitLENwkMonitorMutexVaraibles has failed");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+
+    return CA_STATUS_OK;
+
+}
+
+void CATerminateLENetworkMonitor()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CATerminateLENwkMonitorMutexVaraibles();
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    OIC_LOG(DEBUG, TAG, "Setting CALEDeviceStateChangedCallback");
+
+    ca_mutex_lock(gCALEDeviceStateChangedCbMutex);
+    CALESetNetStateCallback(callback);
+    ca_mutex_unlock(gCALEDeviceStateChangedCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUnSetLEAdapterStateChangedCb()
+{
+    OIC_LOG(DEBUG, TAG, "it is not required in this platform");
+    return CA_STATUS_OK;
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeStateChangedCallback(JNIEnv *env, jobject obj, jint status)
+Java_org_iotivity_jar_caleclientinterface_CALeStateChangedCallback(JNIEnv *env, jobject obj,
+                                                                   jint status)
 {
-    // STATE_ON:12, STATE_OFF:10
-    OIC_LOG(DEBUG, TAG, "CALeInterface - Network State Changed");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+
 
-    if (g_networkChangeCb == NULL)
+    OIC_LOG(DEBUG, TAG, "caleclientinterface - Network State Changed");
+
+    if (!gCALEDeviceStateChangedCallback)
     {
-        OIC_LOG(DEBUG, TAG, "g_networkChangeCb is null", status);
+        OIC_LOG_V(ERROR, TAG, "gNetworkChangeCb is null", status);
     }
 
-    jstring jni_address = CALEGetLocalDeviceAddress(env);
-    const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (BT_STATE_ON == status) // STATE_ON:12
+    {
+        CANetworkStatus_t newStatus = CA_INTERFACE_UP;
+        gCALEDeviceStateChangedCallback(newStatus);
+    }
+    else if (BT_STATE_OFF == status) // STATE_OFF:10
+    {
+        // remove obj for client
+        CAResult_t res = CALEClientRemoveAllGattObjs(env);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
+        }
+
+        res = CALEClientRemoveAllScanDevices(env);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
+        }
 
-    g_networkChangeCb(localAddress, status);
+        // remove obej for server
+        res = CALEServerRemoveAllDevices(env);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
+        }
+
+        CANetworkStatus_t newStatus = CA_INTERFACE_DOWN;
+        gCALEDeviceStateChangedCallback(newStatus);
+    }
 }
 
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeBondStateChangedCallback(JNIEnv *env, jobject obj,
+                                                                       jstring addr)
+{
+    OIC_LOG(DEBUG, TAG, "caleclientinterface - Bond State Changed");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(addr, TAG, "addr is null");
+
+    // remove obj for client
+    CAResult_t res = CALEClientRemoveGattObjForAddr(env, addr);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CANativeRemoveGattObjForAddr has failed");
+    }
+
+    res = CALEClientRemoveDeviceInScanDeviceList(env, addr);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceInScanDeviceList has failed");
+    }
+
+    // remove obej for server
+    res = CALEServerRemoveDevice(env, addr);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
+    }
+
+}
@@ -1,4 +1,4 @@
-/* ****************************************************************
+/******************************************************************
 *
 * Copyright 2014 Samsung Electronics All Rights Reserved.
 *
 ******************************************************************/
 
 /**
- * @file
- *
- * This file contains the APIs for BT LE communications.
- */
-
-#ifndef __CA_LENWMONITOR_H_
-#define __CA_LENWMONITOR_H_
+* @file calenwmonitor.h
+* @brief This file contains the APIs for BT LE communications.
+*/
+#ifndef CA_LENWMONITOR_H_
+#define CA_LENWMONITOR_H_
 
 #include "cacommon.h"
 #include "cathreadpool.h"
 #include "uarraylist.h"
+#include "caleinterface.h"
 #include "jni.h"
 
 #ifdef __cplusplus
@@ -38,33 +37,23 @@ extern "C"
 #endif
 
 /**
- * @var CALENetStateChantedCallback
- * @brief  Maintains network connection state change callback.
- */
-typedef void (*CALENetStateChantedCallback)(const char* address, const uint32_t status);
-
-/**
  * @brief   set context of application
- * @param   env              [IN] JNI interface pointer
- * @param   context          [IN] context of application
  * @return  None
  */
-void CALENetworkMonitorJNISetContext(JNIEnv *env, jobject context);
+void CALENetworkMonitorJNISetContext();
 
 /**
  * @brief   initialize JNI object
- * @param   env              [IN] JNI interface pointer
- * @param   jvm              [IN] java virtual machine pointer
  * @return  None
  */
-void CALeNetworkMonitorJniInit(JNIEnv *env, JavaVM *jvm);
+void CALENetworkMonitorJniInit();
 
 /**
  * @brief  Set this callback for receiving network information from BT stack.
  * @param  callback   [IN] Callback to be notified on reception of BT state information
  * @return  NONE
  */
-void CALESetNetStateCallback(CALENetStateChantedCallback callback);
+void CALESetNetStateCallback(CALEDeviceStateChangedCallback callback);
 
 #ifdef __cplusplus
 } /* extern "C" */
@@ -72,5 +61,3 @@ void CALESetNetStateCallback(CALENetStateChantedCallback callback);
 
 #endif
 
-
-
index e20103c..dec1409 100644 (file)
 #include <unistd.h>
 #include "caleserver.h"
 #include "caleutils.h"
+#include "caleinterface.h"
+#include "caadapterutils.h"
+
 #include "logger.h"
 #include "oic_malloc.h"
 #include "cathreadpool.h"
+#include "camutex.h"
 #include "uarraylist.h"
-#include "com_iotivity_jar_caleinterface.h"
+#include "org_iotivity_jar_caleserverinterface.h"
 
 #define TAG PCF("CA_LE_SERVER")
 
-/* Service UUID */
-static const char OIC_GATT_SERVICE_UUID[] = "713d0000-503e-4c75-ba94-3148f18d941e";
-/* Read */
-static const char OIC_GATT_CHARACTERISTIC_RESPONSE_UUID[] = "713d0002-503e-4c75-ba94-3148f18d941e";
-/* Write */
-static const char OIC_GATT_CHARACTERISTIC_REQUEST_UUID[] = "713d0003-503e-4c75-ba94-3148f18d941e";
-
-static JavaVM *g_jvm;
-static jobject g_context;
-static jobject g_bluetoothGattServer;
-static jobject g_bluetoothGattServerCallback;
-static jobject g_leAdvertiseCallback;
+static JavaVM *g_jvm = NULL;
+static jobject g_context = NULL;
+static jobject g_bluetoothGattServer = NULL;
+static jobject g_bluetoothGattServerCallback = NULL;
+static jobject g_leAdvertiseCallback = NULL;
 
 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
 static u_arraylist_t *g_connectedDeviceList = NULL;
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
-static jboolean g_isStartServer;
-static jboolean g_isSendingMulticastData;
+static bool g_isStartServer = false;
+static bool g_isInitializedServer = false;
+
+static CABLEServerDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
+static ca_mutex g_bleReqRespCbMutex = NULL;
+static ca_mutex g_bleClientBDAddressMutex = NULL;
+static ca_mutex g_connectedDeviceListMutex = NULL;
 
-//getting context
-void CALEServerJNISetContext(JNIEnv *env, jobject context)
+void CALEServerJNISetContext()
 {
     OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
+    g_context = (jobject) CANativeJNIGetContext();
+}
+
+void CALeServerJniInit()
+{
+    OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
+    g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
+}
+
+CAResult_t CALEServerCreateJniInterfaceObject()
+{
+    OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
+
+    if (!g_context)
+    {
+        OIC_LOG(ERROR, TAG, "g_context is null");
+        return CA_STATUS_FAILED;
+    }
 
-    if (context == NULL)
+    if (!g_jvm)
     {
-        OIC_LOG(ERROR, TAG, "context is null");
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
     }
 
-    g_context = (*env)->NewGlobalRef(env, context);
-}
+    bool isAttached = false;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-//getting jvm
-void CALeServerJniInit(JNIEnv *env, JavaVM *jvm)
-{
-    OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
-    g_jvm = jvm;
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
+        }
+        isAttached = true;
+    }
+
+    jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/jar/caleserverinterface");
+    if (!jni_LEInterface)
+    {
+        OIC_LOG(ERROR, TAG, "Could not get caleserverinterface class");
+        goto exit;
+    }
+
+    jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
+                                                                 "()V");
+    if (!LeInterfaceConstructorMethod)
+    {
+        OIC_LOG(ERROR, TAG, "Could not get caleserverinterface constructor method");
+        goto exit;
+    }
+
+    (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
+    OIC_LOG(DEBUG, TAG, "Create instance for caleserverinterface");
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return CA_STATUS_OK;
+
+    exit:
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return CA_STATUS_FAILED;
 }
 
-jobject CANativeLEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
+jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
 {
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
+
+    if (!g_bluetoothGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
+        return NULL;
+    }
+
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
@@ -85,270 +156,559 @@ jobject CANativeLEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
 
     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
                                                            "android/bluetooth/BluetoothGattServer");
+    if (!jni_cid_bluetoothGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
+        return NULL;
+    }
 
-    jclass jni_cid_bluetoothGattService = (*env)->FindClass(
-            env, "android/bluetooth/BluetoothGattService");
+    jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
+                                                            "BluetoothGattService");
+    if (!jni_cid_bluetoothGattService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
+        return NULL;
+    }
 
-    jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(
-            env, "android/bluetooth/BluetoothGattCharacteristic");
+    jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
+                                                                   "BluetoothGattCharacteristic");
+    if (!jni_cid_bluetoothGattService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
+        return NULL;
+    }
 
-    jmethodID jni_mid_getService = (*env)->GetMethodID(
-            env, jni_cid_bluetoothGattServer, "getService",
-            "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
+    jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
+                                                       "getService",
+                                                       "(Ljava/util/UUID;)Landroid/bluetooth/"
+                                                       "BluetoothGattService;");
+    if (!jni_cid_bluetoothGattService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
+        return NULL;
+    }
 
     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
-
-    if (!g_bluetoothGattServer)
+    if (!jni_obj_serviceUUID)
     {
-        OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
+        OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
         return NULL;
     }
+
     jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
                                                                     jni_mid_getService,
                                                                     jni_obj_serviceUUID);
+    if (!jni_obj_bluetoothGattService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
+        return NULL;
+    }
 
-    jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(
-            env, jni_cid_bluetoothGattService, "getCharacteristic",
-            "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
+    jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
+                                                              "getCharacteristic",
+                                                              "(Ljava/util/UUID;)"
+                                                              "Landroid/bluetooth/"
+                                                              "BluetoothGattCharacteristic;");
+    if (!jni_mid_getCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
+        return NULL;
+    }
 
     jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
                                                          OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
+    if (!jni_obj_responseUUID)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
+        return NULL;
+    }
 
     jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
             env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
+    if (!jni_obj_bluetoothGattCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
+        return NULL;
+    }
 
     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_bluetoothGattCharacteristic,
                                                      "setValue", "([B)Z");
+    if (!jni_mid_setValue)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
+        return NULL;
+    }
 
     jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
                                                               jni_obj_bluetoothGattCharacteristic,
                                                               jni_mid_setValue, responseData);
-
-    if (jni_boolean_setValue == JNI_FALSE)
+    if (JNI_FALSE == jni_boolean_setValue)
     {
         OIC_LOG(ERROR, TAG, "Fail to set response data");
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
     return jni_obj_bluetoothGattCharacteristic;
 }
 
-CAResult_t CANativeLEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
+CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
 {
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponseData");
+    VERIFY_NON_NULL(responseData, TAG, "responseData is null");
+    VERIFY_NON_NULL(device, TAG, "device is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
-    OIC_LOG(DEBUG, TAG, "CALEServerSendResponseData");
-
     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
                                                            "android/bluetooth/BluetoothGattServer");
+    if (!jni_cid_bluetoothGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
+        return CA_STATUS_FAILED;
+    }
 
     jmethodID jni_mid_notifyCharacteristicChanged = (*env)->GetMethodID(
             env, jni_cid_bluetoothGattServer, "notifyCharacteristicChanged",
             "(Landroid/bluetooth/BluetoothDevice;"
             "Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
+    if (!jni_mid_notifyCharacteristicChanged)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
+        return CA_STATUS_FAILED;
+    }
 
     jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
             env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
             JNI_FALSE);
-
-    if (jni_boolean_notifyCharacteristicChanged == JNI_FALSE)
+    if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
     {
         OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
         return CA_SEND_FAILED;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponseData");
     return CA_STATUS_OK;
 }
 
-CAResult_t CANativeLEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
+CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
                                         jint offset, jbyteArray value)
 {
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(device, TAG, "device is null");
+    VERIFY_NON_NULL(value, TAG, "value is null");
+
+    OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
-    OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
-
     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
                                                            "android/bluetooth/BluetoothGattServer");
+    if (!jni_cid_bluetoothGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jmethodID jni_mid_sendResponse = (*env)->GetMethodID(
-            env, jni_cid_bluetoothGattServer, "sendResponse",
-            "(Landroid/bluetooth/BluetoothDevice;III[B)Z");
+    jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
+                                                         "sendResponse",
+                                                         "(Landroid/bluetooth/BluetoothDevice;"
+                                                         "III[B)Z");
+    if (!jni_mid_sendResponse)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
+        return CA_STATUS_FAILED;
+    }
 
     jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
                                                                   jni_mid_sendResponse, device,
-                                                                  requestId, status, offset, value);
-
-    if (jni_boolean_sendResponse == JNI_FALSE)
+                                                                  requestId, status, offset,
+                                                                  value);
+    if (JNI_FALSE == jni_boolean_sendResponse)
     {
         OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
         return CA_SEND_FAILED;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
     return CA_STATUS_OK;
 }
 
-void CANativeLEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
+CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
 {
-
-    OIC_LOG(DEBUG, TAG, "LEServerStartAdvertise");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
-    jclass jni_cid_AdvertiseSettings = (*env)->FindClass(
-            env, "android/bluetooth/le/AdvertiseSettings$Builder");
-
-    jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(
-            env, "android/bluetooth/le/AdvertiseData$Builder");
-
-    jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
-
-    jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
-                                                    "android/bluetooth/le/BluetoothLeAdvertiser");
+    jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
+                                                         "android/bluetooth/le/"
+                                                         "AdvertiseSettings$Builder");
+    if (!jni_cid_AdvertiseSettings)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
+        return CA_STATUS_FAILED;
+    }
 
     jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
                                                               "<init>", "()V");
-
-    jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(
-            env, jni_cid_AdvertiseSettings, "setAdvertiseMode",
-            "(I)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
-
-    jmethodID jni_mid_setConnectable = (*env)->GetMethodID(
-            env, jni_cid_AdvertiseSettings, "setConnectable",
-            "(Z)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
-
-    jmethodID jni_mid_setTimeout = (*env)->GetMethodID(
-            env, jni_cid_AdvertiseSettings, "setTimeout",
-            "(I)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
-
-    jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
-                                                                 "<init>", "()V");
-
-    jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(
-            env, jni_cid_AdvertiseDataBuilder, "addServiceUuid",
-            "(Landroid/os/ParcelUuid;)Landroid/bluetooth/le/AdvertiseData$Builder;");
-
-    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(
-            env, jni_cid_BTAdapter, "getDefaultAdapter", "()Landroid/bluetooth/BluetoothAdapter;");
-
-    jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(
-            env, jni_cid_BTAdapter, "getBluetoothLeAdvertiser",
-            "()Landroid/bluetooth/le/BluetoothLeAdvertiser;");
-
-    jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(
-            env, jni_cid_AdvertiseSettings, "build", "()Landroid/bluetooth/le/AdvertiseSettings;");
-
-    jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(
-            env, jni_cid_AdvertiseDataBuilder, "build", "()Landroid/bluetooth/le/AdvertiseData;");
-
-    jmethodID jni_mid_startAdvertising = (*env)->GetMethodID(
-            env, jni_cid_leAdvertiser, "startAdvertising",
-            "(Landroid/bluetooth/le/AdvertiseSettings;Landroid/bluetooth/le/AdvertiseData;"
-            "Landroid/bluetooth/le/AdvertiseCallback;)V");
+    if (!jni_mid_AdvertiseSettings)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
                                                       jni_mid_AdvertiseSettings);
+    if (!jni_AdvertiseSettings)
+    {
+        OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
+                                                             "setAdvertiseMode",
+                                                             "(I)Landroid/bluetooth/le/"
+                                                             "AdvertiseSettings$Builder;");
+    if (!jni_mid_setAdvertiseMode)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
+        return CA_STATUS_FAILED;
+    }
 
     // 0: Low power, 1: Balanced
     jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
                                                                 jni_mid_setAdvertiseMode, 0);
+    if (!jni_obj_setAdvertiseMode)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
+                                                           "setConnectable",
+                                                           "(Z)Landroid/bluetooth/le/"
+                                                           "AdvertiseSettings$Builder;");
+    if (!jni_mid_setConnectable)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
                                                               jni_mid_setConnectable, JNI_TRUE);
+    if (!jni_obj_setConnectable)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
+                                                       "(I)Landroid/bluetooth/le/"
+                                                       "AdvertiseSettings$Builder;");
+    if (!jni_mid_setTimeout)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
+        return CA_STATUS_FAILED;
+    }
 
     //A value of 0 will disable the time limit
     jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
                                                           jni_mid_setTimeout, 0);
+    if (!jni_obj_setTimeout)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
+                                                            "android/bluetooth/le/"
+                                                            "AdvertiseData$Builder");
+    if (!jni_cid_AdvertiseDataBuilder)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
+                                                                 "<init>", "()V");
+    if (!jni_mid_AdvertiseDataBuilder)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
                                                          jni_mid_AdvertiseDataBuilder);
+    if (!jni_AdvertiseDataBuilder)
+    {
+        OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
+    if (!jni_obj_serviceUUID)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
+    if (!jni_ParcelUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
+                                                           "addServiceUuid",
+                                                           "(Landroid/os/ParcelUuid;)Landroid/"
+                                                           "bluetooth/le/AdvertiseData$Builder;");
+    if (!jni_mid_addServiceUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
                                                               jni_mid_addServiceUuid,
                                                               jni_ParcelUuid);
+    if (!jni_obj_addServiceUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                                                    "getDefaultAdapter",
+                                                                    "()Landroid/bluetooth/"
+                                                                    "BluetoothAdapter;");
+    if (!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        return CA_STATUS_FAILED;
+    }
 
     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 CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+                                                                     "getBluetoothLeAdvertiser",
+                                                                     "()Landroid/bluetooth/le/"
+                                                                     "BluetoothLeAdvertiser;");
+    if (!jni_mid_getBluetoothLeAdvertiser)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
             env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
+    if (!jni_obj_getBluetoothLeAdvertiser)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
+                                                                      jni_cid_AdvertiseSettings,
+                                                                      "build",
+                                                                      "()Landroid/bluetooth/le/"
+                                                                      "AdvertiseSettings;");
+    if (!jni_mid_build_LeAdvertiseSettings)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
             env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
+    if (!jni_obj_build_LeAdvertiseSettings)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
+                                                                  "build",
+                                                                  "()Landroid/bluetooth/le/"
+                                                                  "AdvertiseData;");
+    if (!jni_mid_build_LeAdvertiseData)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
+        return CA_STATUS_FAILED;
+    }
 
     jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
                                                                      jni_mid_build_LeAdvertiseData);
+    if (!jni_obj_build_LeAdvertiseData)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
+                                                    "android/bluetooth/le/BluetoothLeAdvertiser");
+    if (!jni_cid_leAdvertiser)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_startAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
+                                                             "startAdvertising",
+                                                             "(Landroid/bluetooth/le/"
+                                                             "AdvertiseSettings;Landroid/bluetooth/"
+                                                             "le/AdvertiseData;Landroid/bluetooth/"
+                                                             "le/AdvertiseCallback;)V");
+    if (!jni_mid_startAdvertising)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
+        return CA_STATUS_FAILED;
+    }
 
     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
                            jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
                            advertiseCallback);
 
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return CA_STATUS_FAILED;
+    }
+
     OIC_LOG(DEBUG, TAG, "Advertising started!!");
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
+    return CA_STATUS_OK;
 }
 
-void CANativeLEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
+CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
 {
-
-    OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
+    OIC_LOG(DEBUG, TAG, "IN - LEServerStopAdvertise");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
     jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
+        return CA_STATUS_FAILED;
+    }
 
     jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
                                                     "android/bluetooth/le/BluetoothLeAdvertiser");
+    if (!jni_cid_leAdvertiser)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(
-            env, jni_cid_BTAdapter, "getDefaultAdapter", "()Landroid/bluetooth/BluetoothAdapter;");
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                                                    "getDefaultAdapter",
+                                                                    "()Landroid/bluetooth/"
+                                                                    "BluetoothAdapter;");
+    if (!jni_cid_leAdvertiser)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(
-            env, jni_cid_BTAdapter, "getBluetoothLeAdvertiser",
-            "()Landroid/bluetooth/le/BluetoothLeAdvertiser;");
+    jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+                                                                     "getBluetoothLeAdvertiser",
+                                                                     "()Landroid/bluetooth/le/"
+                                                                     "BluetoothLeAdvertiser;");
+    if (!jni_mid_getBTLeAdvertiser)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jmethodID jni_mid_stopAdvertising = (*env)->GetMethodID(
-            env, jni_cid_leAdvertiser, "stopAdvertising",
-            "(Landroid/bluetooth/le/AdvertiseCallback;)V");
+    jmethodID jni_mid_stopAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
+                                                            "stopAdvertising",
+                                                            "(Landroid/bluetooth/le/"
+                                                            "AdvertiseCallback;)V");
+    if (!jni_mid_stopAdvertising)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
+        return CA_STATUS_FAILED;
+    }
 
     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 CA_STATUS_FAILED;
+    }
 
-    jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
-            env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
+    jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+                                                                        jni_mid_getBTLeAdvertiser);
+    if (!jni_obj_getBluetoothLeAdvertiser)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
+        return CA_STATUS_FAILED;
+    }
 
     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
                            advertiseCallback);
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return CA_STATUS_FAILED;
+    }
 
     OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
+
+    OIC_LOG(DEBUG, TAG, "OUT - LEServerStopAdvertise");
+    return CA_STATUS_OK;
 }
 
-CAResult_t CALEStartGattServer(JNIEnv *env, jobject gattServerCallback)
+CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
 {
-
-    OIC_LOG(DEBUG, TAG, "CALEStartGattServer");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
@@ -360,7 +720,7 @@ CAResult_t CALEStartGattServer(JNIEnv *env, jobject gattServerCallback)
     g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
 
     // open gatt server
-    jobject bluetoothGattServer = CANativeLEServerOpenGattServer(env);
+    jobject bluetoothGattServer = CALEServerOpenGattServer(env);
     if (!bluetoothGattServer)
     {
         OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
@@ -368,47 +728,93 @@ CAResult_t CALEStartGattServer(JNIEnv *env, jobject gattServerCallback)
     }
 
     g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
+    if (!g_bluetoothGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
+        return CA_STATUS_FAILED;
+    }
 
     // create gatt service
-    jobject bluetoothGattService = CANativeLEServerCreateGattService(env);
+    jobject bluetoothGattService = CALEServerCreateGattService(env);
+    if (!bluetoothGattService)
+    {
+        OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
+        return CA_STATUS_FAILED;
+    }
 
     // add gatt service
-    return CANativeLEServerAddGattService(env, g_bluetoothGattServer, bluetoothGattService);
+    CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
+                                              bluetoothGattService);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
+    }
+    return res;
 }
 
-jobject CANativeLEServerOpenGattServer(JNIEnv *env)
+jobject CALEServerOpenGattServer(JNIEnv *env)
 {
-
-    OIC_LOG(DEBUG, TAG, "CALEServerOpenGattServer");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
     jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
+    if (!jni_cid_context)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_context is null");
+        return NULL;
+    }
 
     jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
+    if (!jni_cid_bluetoothManager)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
+        return NULL;
+    }
 
     jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
                                                                  "BLUETOOTH_SERVICE",
                                                                  "Ljava/lang/String;");
+    if (!jni_fid_bluetoothService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
+        return NULL;
+    }
 
-    jmethodID jni_mid_getSystemService = (*env)->GetMethodID(
-            env, jni_cid_context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
+    jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
+                                                             "getSystemService",
+                                                             "(Ljava/lang/String;)"
+                                                             "Ljava/lang/Object;");
+    if (!jni_mid_getSystemService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
+        return NULL;
+    }
 
-    jmethodID jni_mid_openGattServer = (*env)->GetMethodID(
-            env, jni_cid_bluetoothManager, "openGattServer",
-            "(Landroid/content/Context;Landroid/bluetooth/BluetoothGattServerCallback;)"
-            "Landroid/bluetooth/BluetoothGattServer;");
+    jmethodID jni_mid_openGattServer = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
+                                                           "openGattServer",
+                                                           "(Landroid/content/Context;"
+                                                           "Landroid/bluetooth/"
+                                                           "BluetoothGattServerCallback;)"
+                                                           "Landroid/bluetooth/"
+                                                           "BluetoothGattServer;");
+    if (!jni_mid_openGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
+        return NULL;
+    }
 
     jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
                                                                     jni_fid_bluetoothService);
     if (!jni_obj_bluetoothService)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
-        return JNI_FALSE;
+        return NULL;
     }
 
     jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
@@ -417,7 +823,7 @@ jobject CANativeLEServerOpenGattServer(JNIEnv *env)
     if (!jni_obj_bluetoothManager)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
-        return JNI_FALSE;
+        return NULL;
     }
 
     jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
@@ -427,67 +833,140 @@ jobject CANativeLEServerOpenGattServer(JNIEnv *env)
     if (!jni_obj_bluetoothGattServer)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
-        return JNI_FALSE;
+        return NULL;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
     return jni_obj_bluetoothGattServer;
 }
 
-jobject CANativeLEServerCreateGattService(JNIEnv *env)
+jobject CALEServerCreateGattService(JNIEnv *env)
 {
-
-    OIC_LOG(DEBUG, TAG, "CALEServerCreateGattService");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
-    jclass jni_cid_bluetoothGattService = (*env)->FindClass(
-            env, "android/bluetooth/BluetoothGattService");
+    jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
+                                                            "BluetoothGattService");
+    if (!jni_cid_bluetoothGattService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
+        return NULL;
+    }
 
-    jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(
-            env, "android/bluetooth/BluetoothGattCharacteristic");
+    jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
+                                                                   "BluetoothGattCharacteristic");
+    if (!jni_cid_bluetoothGattCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
+        return NULL;
+    }
 
     jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
                                                             "SERVICE_TYPE_PRIMARY", "I");
+    if (!jni_fid_serviceType)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
+        return NULL;
+    }
 
     jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
                                                                jni_cid_bluetoothGattCharacteristic,
                                                                "PROPERTY_READ", "I");
+    if (!jni_fid_readProperties)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
+        return NULL;
+    }
 
+#ifdef USE_PROPERTY_WRITE_RESPONSE
     jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
                                                                 jni_cid_bluetoothGattCharacteristic,
                                                                 "PROPERTY_WRITE", "I");
+#else
+    jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
+                                                                jni_cid_bluetoothGattCharacteristic,
+                                                                "PROPERTY_WRITE_NO_RESPONSE", "I");
+#endif
+
+    if (!jni_fid_writeProperties)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
+        return NULL;
+    }
 
     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
                                                                 jni_cid_bluetoothGattCharacteristic,
                                                                 "PERMISSION_READ", "I");
+    if (!jni_fid_readPermissions)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
+        return NULL;
+    }
 
     jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
             env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
+    if (!jni_fid_writePermissions)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
+        return NULL;
+    }
 
     jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
                                                                  "<init>", "(Ljava/util/UUID;I)V");
+    if (!jni_mid_bluetoothGattService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
+        return NULL;
+    }
 
-    jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(
-            env, jni_cid_bluetoothGattService, "addCharacteristic",
-            "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
+    jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
+                                                              "addCharacteristic",
+                                                              "(Landroid/bluetooth/"
+                                                              "BluetoothGattCharacteristic;)Z");
+    if (!jni_mid_addCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
+        return NULL;
+    }
 
     jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
             env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
+    if (!jni_mid_bluetoothGattCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
+        return NULL;
+    }
 
     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
+    if (!jni_obj_serviceUUID)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
+        return NULL;
+    }
 
-    jobject jni_obj_serviceType = (*env)->GetStaticObjectField(env, jni_cid_bluetoothGattService,
-                                                               jni_fid_serviceType);
-
+    jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
+                                                         jni_fid_serviceType);
     jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
                                                          jni_mid_bluetoothGattService,
-                                                         jni_obj_serviceUUID, jni_obj_serviceType);
+                                                         jni_obj_serviceUUID, jni_int_serviceType);
+    if (!jni_bluetoothGattService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
+        return NULL;
+    }
 
     jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
+    if (!jni_obj_readUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
+        return NULL;
+    }
 
     jint jni_int_readProperties = (*env)->GetStaticIntField(env,
                                                             jni_cid_bluetoothGattCharacteristic,
@@ -501,11 +980,33 @@ jobject CANativeLEServerCreateGattService(JNIEnv *env)
                                                        jni_mid_bluetoothGattCharacteristic,
                                                        jni_obj_readUuid, jni_int_readProperties,
                                                        jni_int_readPermissions);
+    if (!jni_readCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
+        return NULL;
+    }
+
+    CAResult_t res = CALEServerAddDescriptor(env, jni_readCharacteristic);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerAddDescriptor has failed");
+        return NULL;
+    }
 
     jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
             env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
+    if (!jni_boolean_addReadCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
+        return NULL;
+    }
 
     jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
+    if (!jni_obj_writeUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
+        return NULL;
+    }
 
     jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
                                                              jni_cid_bluetoothGattCharacteristic,
@@ -519,188 +1020,435 @@ jobject CANativeLEServerCreateGattService(JNIEnv *env)
                                                         jni_mid_bluetoothGattCharacteristic,
                                                         jni_obj_writeUuid, jni_int_writeProperties,
                                                         jni_int_writePermissions);
+    if (!jni_writeCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
+        return NULL;
+    }
 
     jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
             env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
-
-    if (jni_boolean_addWriteCharacteristic == JNI_FALSE)
+    if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
         return NULL;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
     return jni_bluetoothGattService;
 }
 
-CAResult_t CANativeLEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
-                                          jobject bluetoothGattService)
+CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
 {
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDescriptor");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
+
+    jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
+                                                               "BluetoothGattDescriptor");
+    if (!jni_cid_bluetoothGattDescriptor)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
+                                                                    jni_cid_bluetoothGattDescriptor,
+                                                                    "<init>",
+                                                                    "(Ljava/util/UUID;I)V");
+    if (!jni_mid_bluetoothGattDescriptor)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
+                                                                jni_cid_bluetoothGattDescriptor,
+                                                                "PERMISSION_READ", "I");
+    if (!jni_fid_readPermissions)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
+    if (!jni_obj_readUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
+                                                             jni_fid_readPermissions);
+
+    OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
+
+    jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
+                                                   jni_mid_bluetoothGattDescriptor,
+                                                   jni_obj_readUuid, jni_int_readPermissions);
+    if (!jni_readDescriptor)
+    {
+        OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
+                                                          "BluetoothGattCharacteristic");
+    if (!jni_cid_GattCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
+                                                          "addDescriptor",
+                                                          "(Landroid/bluetooth/"
+                                                          "BluetoothGattDescriptor;)Z");
+    if (!jni_mid_addDescriptor)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
+                                                                   jni_mid_addDescriptor,
+                                                                   jni_readDescriptor);
+
+    if (JNI_FALSE == jni_boolean_addDescriptor)
+    {
+        OIC_LOG(ERROR, TAG, "addDescriptor has failed");
+        return CA_STATUS_FAILED;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "addDescriptor success");
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDescriptor");
+    return CA_STATUS_OK;
+}
 
-    OIC_LOG(DEBUG, TAG, "CALEServerAddGattService");
+CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
+                                          jobject bluetoothGattService)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
+    VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
                                                            "android/bluetooth/BluetoothGattServer");
+    if (!jni_cid_bluetoothGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jmethodID jni_mid_addService = (*env)->GetMethodID(
-            env, jni_cid_bluetoothGattServer, "addService",
-            "(Landroid/bluetooth/BluetoothGattService;)Z");
+    jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
+                                                       "addService",
+                                                       "(Landroid/bluetooth/BluetoothGattService;)"
+                                                       "Z");
+    if (!jni_mid_addService)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
+        return CA_STATUS_FAILED;
+    }
 
     jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
                                                                 jni_mid_addService,
                                                                 bluetoothGattService);
 
-    if (jni_boolean_addService == JNI_FALSE)
+    if (JNI_FALSE == jni_boolean_addService)
     {
-        OIC_LOG(ERROR, TAG, "Fail to add gatt service");
+        OIC_LOG(ERROR, TAG, "Fail to add GATT service");
         return CA_STATUS_FAILED;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
     return CA_STATUS_OK;
 }
 
-CAResult_t CANativeLEServerConnect(JNIEnv *env, jobject bluetoothDevice)
+CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
 {
-
-    OIC_LOG(DEBUG, TAG, "CALEConnect");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
                                                            "android/bluetooth/BluetoothGattServer");
+    if (!jni_cid_bluetoothGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
+        return CA_STATUS_FAILED;
+    }
 
     jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
                                                     "(Landroid/bluetooth/BluetoothDevice;Z)Z");
+    if (!jni_mid_connect)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
+        return CA_STATUS_FAILED;
+    }
 
     jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
                                                              jni_mid_connect, bluetoothDevice,
                                                              JNI_FALSE);
-
-    if (jni_boolean_connect == JNI_FALSE)
+    if (JNI_FALSE == jni_boolean_connect)
     {
         OIC_LOG(ERROR, TAG, "Fail to connect");
         return CA_STATUS_FAILED;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
     return CA_STATUS_OK;
 }
 
-void CANativeLEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
+CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
 {
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    ca_mutex_lock(g_connectedDeviceListMutex);
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
+        ca_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
+        if (!jarrayObj)
+        {
+            OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
+            continue;
+        }
+
+        // disconnect for device obj
+        CAResult_t res = CALEServerDisconnect(env, jarrayObj);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
+            continue;
+        }
+    }
+
+    ca_mutex_unlock(g_connectedDeviceListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
+    return CA_STATUS_OK;
+}
 
-    OIC_LOG(DEBUG, TAG, "CALEDisconnect");
+CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
-        return;
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
                                                            "android/bluetooth/BluetoothGattServer");
+    if (!jni_cid_bluetoothGattServer)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(
-            env, jni_cid_bluetoothGattServer, "cancelConnection",
-            "(Landroid/bluetooth/BluetoothDevice;)V");
+    jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
+                                                             "cancelConnection",
+                                                             "(Landroid/bluetooth/BluetoothDevice;)"
+                                                             "V");
+    if (!jni_mid_cancelConnection)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
+        return CA_STATUS_FAILED;
+    }
 
     (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
+
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "cancelConnection has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
+    return CA_STATUS_OK;
 }
 
 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
 {
-
-    OIC_LOG(DEBUG, TAG, "CALESend");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
+    VERIFY_NON_NULL(responseData, TAG, "responseData is null");
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "[BLE][Native] BT adpater is not enable");
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
-    jobject responseChar = CANativeLEServerSetResponseData(env, responseData);
-
-    CAResult_t result = CANativeLEServerSendResponseData(env, bluetoothDevice, responseChar);
+    jobject responseChar = CALEServerSetResponseData(env, responseData);
+    if (!responseChar)
+    {
+        OIC_LOG(ERROR, TAG, "responseChar is null");
+        return CA_STATUS_FAILED;
+    }
 
-    if (result != CA_STATUS_OK)
+    CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
+    if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, TAG, "Fail to send response data");
         return result;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
     return result;
 }
 
-void CALeServerCreateJniInterfaceObject()
+CAResult_t CALEServerInitialize(ca_thread_pool_t handle)
 {
-    OIC_LOG(DEBUG, TAG, "CALeServerCreateJniInterfaceObject");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
+
+    CALeServerJniInit();
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
-        OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
-            return;
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    // initialize le server
-
-    if (isAttached)
+    CAResult_t ret = CALECheckPlatformVersion(env, 21);
+    if (CA_STATUS_OK != ret)
     {
-        (*g_jvm)->DetachCurrentThread(g_jvm);
-    }
-}
+        OIC_LOG(ERROR, TAG, "it is not supported");
 
-void CALEServerInitialize(ca_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, TAG, "CALEServerInitialize");
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+        return ret;
+    }
 
     g_threadPoolHandle = handle;
 
-    g_isSendingMulticastData = JNI_FALSE;
+    ret = CALEServerInitMutexVaraibles();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
+
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+        return CA_STATUS_FAILED;
+    }
 
+    CALEServerJNISetContext();
     CALEServerCreateCachedDeviceList();
+
+    ret = CALEServerCreateJniInterfaceObject();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
+
+        if (isAttached)
+        {
+            (*g_jvm)->DetachCurrentThread(g_jvm);
+        }
+        return CA_STATUS_FAILED;
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    g_isInitializedServer = true;
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
+    return CA_STATUS_OK;
 }
 
 void CALEServerTerminate()
 {
-    OIC_LOG(DEBUG, TAG, "CALEServerTerminate");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return;
+    }
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
+    }
+
+    CAResult_t ret = CALEServerStopMulticastServer(0);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
     }
 
-    CALEServerStopMulticastServer(0);
+    ret = CALEServerDisconnectAllDevices(env);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
+    }
 
-    CALEServerRemoveAllDevices(env);
+    ret = CALEServerRemoveAllDevices(env);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
+    }
 
     if (g_leAdvertiseCallback)
     {
@@ -717,116 +1465,147 @@ void CALEServerTerminate()
         (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
     }
 
-    if (g_context)
-    {
-        (*env)->DeleteGlobalRef(env, g_context);
-    }
+    CALEServerTerminateMutexVaraibles();
+    CALEServerTerminateConditionVaraibles();
 
-    g_isStartServer = JNI_FALSE;
+    g_isStartServer = false;
+    g_isInitializedServer = false;
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
 }
 
 CAResult_t CALEServerSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %s)", address, data);
+    OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendUnicastMessage(%s, %s)", address, data);
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
+    CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
+    }
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendUnicastMessage");
+    return ret;
 }
 
 CAResult_t CALEServerSendMulticastMessage(const char* data, uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%s)", data);
+    OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendMulticastMessage(%s)", data);
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    CALEServerSendMulticastMessageImpl(env, data, dataLen);
+    CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
+    }
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
-    return CA_STATUS_OK;
-}
-
-CAResult_t CALEServerStartUnicastServer(const char* address)
-{
-    OIC_LOG_V(DEBUG, TAG, "CALEServerStartUnicastServer(%s)", address);
-
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendMulticastMessage");
+    return ret;
 }
 
 CAResult_t CALEServerStartMulticastServer()
 {
-    OIC_LOG(DEBUG, TAG, "CALEServerStartMulticastServer");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
+
+    if (!g_isInitializedServer)
+    {
+        OIC_LOG(INFO, TAG, "server is not initialized");
+        return CA_STATUS_FAILED;
+    }
 
     if (g_isStartServer)
     {
-        OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
+        OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
+        return CA_STATUS_FAILED;
+    }
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
         return CA_STATUS_FAILED;
     }
 
-    jboolean isAttached = JNI_FALSE;
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    g_isStartServer = JNI_TRUE;
+    g_isStartServer = true;
 
     // start gatt server
-    CAResult_t ret = CALEStartGattServer(env, g_bluetoothGattServerCallback);
+    CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, TAG, "Fail to start gatt server");
@@ -834,59 +1613,68 @@ CAResult_t CALEServerStartMulticastServer()
     }
 
     // start advertise
-    CANativeLEServerStartAdvertise(env, g_leAdvertiseCallback);
+    ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
+    }
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
-    return CA_STATUS_OK;
-}
-
-CAResult_t CALEServerStopUnicastServer()
-{
-    OIC_LOG(DEBUG, TAG, "CALEServerStopUnicastServer");
-
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
+    return ret;
 }
 
 CAResult_t CALEServerStopMulticastServer()
 {
-    OIC_LOG(DEBUG, TAG, "CALEServerStopMulticastServer");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
 
-    if (g_isStartServer == JNI_FALSE)
+    if (false == g_isStartServer)
     {
-        OIC_LOG(ERROR, TAG, "server is already stopped..it will be skipped");
+        OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
         return CA_STATUS_FAILED;
     }
 
-    jboolean isAttached = JNI_FALSE;
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    bool isAttached = false;
     JNIEnv* env;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
+    if (JNI_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
-        if (res != JNI_OK)
+        if (JNI_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
             return CA_STATUS_FAILED;
         }
-        isAttached = JNI_TRUE;
+        isAttached = true;
     }
 
-    CANativeLEServerStopAdvertise(env, g_leAdvertiseCallback);
+    CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
+    }
 
-    g_isStartServer = JNI_FALSE;
+    g_isStartServer = false;
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
+    return ret;
 }
 
 void CALEServerSetCallback(CAPacketReceiveCallback callback)
@@ -895,115 +1683,86 @@ void CALEServerSetCallback(CAPacketReceiveCallback callback)
     g_packetReceiveCallback = callback;
 }
 
-void CALEServerGetInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size)
-{
-    OIC_LOG(DEBUG, TAG, "CALEServerGetInterfaceInfo");
-    return;
-}
-
-void CALEServerGetLocalAddress(char* address)
-{
-    OIC_LOG(DEBUG, TAG, "CALEServerGetLocalAddress");
-
-    jboolean isAttached = JNI_FALSE;
-    JNIEnv* env;
-    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (res != JNI_OK)
-    {
-        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
-        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
-        if (res != JNI_OK)
-        {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
-            return;
-        }
-        isAttached = JNI_TRUE;
-    }
-
-    jstring jni_address = CALEGetLocalDeviceAddress(env);
-    const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
-    if (NULL == localAddress)
-    {
-        OIC_LOG(ERROR, TAG, "there are no local address");
-        return;
-    }
-
-    memcpy(address, localAddress, strlen(localAddress));
-
-    OIC_LOG_V(DEBUG, TAG, "Local Address : %s", address);
-    if (isAttached)
-    {
-        (*g_jvm)->DetachCurrentThread(g_jvm);
-    }
-}
-
 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const char* data,
                                             uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %s", address, data);
-
-    // 1. get device object with address from cache
-    // 2. connect to the gatt client device
-    // 3. write a characteristic for response
-    // 4. notify it
-    // 5. disconnect
-
-    jobject jni_obj_bluetoothDevice = NULL;
+    OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendUnicastMessageImpl, address: %s, data: %s",
+            address, data);
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
 
-    if (g_connectedDeviceList == NULL)
+    if (!g_connectedDeviceList)
     {
         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
+        return CA_STATUS_FAILED;
     }
 
-    if (g_connectedDeviceList)
+    jobject jni_obj_bluetoothDevice = NULL;
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
     {
-        jint index;
-        for (index = 0; index < u_arraylist_length(g_connectedDeviceList); index++)
+        OIC_LOG(DEBUG, TAG, "check device address");
+        jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
+        if (!jarrayObj)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            return CA_STATUS_FAILED;
+        }
+
+        jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
+        if (!jni_setAddress)
         {
-            OIC_LOG(DEBUG, TAG, "check device address");
-            jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
-            if (!jarrayObj)
-            {
-                OIC_LOG(ERROR, TAG, "jarrayObj is null");
-                return CA_STATUS_FAILED;
-            }
+            OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+            return CA_STATUS_FAILED;
+        }
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return CA_STATUS_FAILED;
+        }
 
-            jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
-            if (!jni_setAddress)
-            {
-                OIC_LOG(ERROR, TAG, "jni_setAddress is null");
-                return CA_STATUS_FAILED;
-            }
-            const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
+        OIC_LOG_V(DEBUG, TAG, "address : %s", address);
 
-            if (!strcmp(setAddress, address))
-            {
-                OIC_LOG(DEBUG, TAG, "device address matched");
-                jni_obj_bluetoothDevice = jarrayObj;
-                break;
-            }
+        if (!strcmp(setAddress, address))
+        {
+            OIC_LOG(DEBUG, TAG, "found the device");
             jni_obj_bluetoothDevice = jarrayObj;
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            break;
         }
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+    }
 
-        if (jni_obj_bluetoothDevice)
-        {
-            jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
-            (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
-
-            CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
+    if (jni_obj_bluetoothDevice)
+    {
+        jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
+        (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
 
-        }
-        else
+        CAResult_t res = CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
+        if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "jni_obj_bluetoothDevice is null");
+            OIC_LOG(ERROR, TAG, "send has failed");
+            return CA_SEND_FAILED;
         }
     }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "There are no device to send in the list");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendUnicastMessageImpl");
     return CA_STATUS_OK;
 }
 
-CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const chardata, uint32_t dataLen)
+CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
+    OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendMulticastMessageImpl, send to, data: %s", data);
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
 
     if (!g_connectedDeviceList)
     {
@@ -1011,14 +1770,8 @@ CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char* data, uin
         return CA_STATUS_FAILED;
     }
 
-    // 1. get all the device objects from cache
-    // 2. connect to the gatt client devices
-    // 3. write a characteristic for response
-    // 4. notify it to every devices
-    // 5. disconnect
-
-    jint index;
-    for (index = 0; index < u_arraylist_length(g_connectedDeviceList); index++)
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
         if (!jarrayObj)
@@ -1027,119 +1780,153 @@ CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char* data, uin
             return CA_STATUS_FAILED;
         }
 
-        g_isSendingMulticastData = JNI_TRUE;
-        CANativeLEServerConnect(env, jarrayObj);
-
-        sleep(1);
+        // send data for all device
+        jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
+        (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
+        CAResult_t res = CALEServerSend(env, jarrayObj, jni_bytearr_data);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "send has failed");
+            return CA_SEND_FAILED;
+        }
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendMulticastMessageImpl");
     return CA_STATUS_OK;
 }
 
 void CALEServerCreateCachedDeviceList()
 {
-    OIC_LOG(DEBUG, TAG, "CALEServerCreateCachedDeviceList");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateCachedDeviceList");
 
+    ca_mutex_lock(g_connectedDeviceListMutex);
     // create new object array
-    if (g_connectedDeviceList == NULL)
+    if (!g_connectedDeviceList)
     {
         OIC_LOG(DEBUG, TAG, "Create device list");
-
         g_connectedDeviceList = u_arraylist_create();
     }
+    ca_mutex_unlock(g_connectedDeviceListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateCachedDeviceList");
 }
 
-jboolean CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
+bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
 {
-    OIC_LOG(DEBUG, TAG, "CALEServerIsDeviceInList");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerIsDeviceInList");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
 
-    if (g_connectedDeviceList == NULL)
+    if (!g_connectedDeviceList)
+    {
         OIC_LOG(ERROR, TAG, "list is null");
+        return false;
+    }
 
-    uint32_t len = u_arraylist_length(g_connectedDeviceList);
-
-    uint32_t index;
-    for (index = 0; index < u_arraylist_length(g_connectedDeviceList); index++)
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
 
         if (!jarrayObj)
         {
             OIC_LOG(ERROR, TAG, "jarrayObj is null");
-            return JNI_FALSE;
+            return false;
         }
 
         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
         if (!jni_setAddress)
         {
             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
-            return JNI_FALSE;
+            return false;
         }
 
-        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress,
-        NULL);
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return false;
+        }
 
         if (!strcmp(remoteAddress, setAddress))
         {
-            OIC_LOG(DEBUG, TAG, "the device is already set");
-            return JNI_TRUE;
+            OIC_LOG(ERROR, TAG, "the device is already set");
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            return true;
         }
         else
         {
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
             continue;
         }
     }
 
-    OIC_LOG(DEBUG, TAG, "no device in list");
-    return JNI_FALSE;
+    OIC_LOG(DEBUG, TAG, "there are no device in the list");
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateCachedDeviceList");
+    return false;
 }
 
-void CALEServerAddDeviceToList(JNIEnv *env, jobject device)
+CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
 {
-    if (device == NULL)
-    {
-        OIC_LOG(ERROR, TAG, "device is null");
-        return;
-    }
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
+    VERIFY_NON_NULL(device, TAG, "device is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    ca_mutex_lock(g_connectedDeviceListMutex);
 
-    if (g_connectedDeviceList == NULL)
+    if (!g_connectedDeviceList)
     {
         OIC_LOG(ERROR, TAG, "list is null");
-        return;
+        ca_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
     }
 
     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
     if (!jni_remoteAddress)
     {
         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
-        return;
+        ca_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
     }
 
     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+    if (!remoteAddress)
+    {
+        OIC_LOG(ERROR, TAG, "remoteAddress is null");
+        ca_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
+    }
 
-    if (CALEServerIsDeviceInList(env, remoteAddress) == JNI_FALSE)
+    if (false == CALEServerIsDeviceInList(env, remoteAddress))
     {
-        jobject gdevice = (*env)->NewGlobalRef(env, device);
-        u_arraylist_add(g_connectedDeviceList, gdevice);
-        OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
+        jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
+        u_arraylist_add(g_connectedDeviceList, jni_obj_device);
+        OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
     }
+
+    (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
+    ca_mutex_unlock(g_connectedDeviceListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
+    return CA_STATUS_OK;
 }
 
-void CALEServerRemoveAllDevices(JNIEnv *env)
+CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
 {
-    OIC_LOG(DEBUG, TAG, "CALEServerRemoveAllDevices");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
+    ca_mutex_lock(g_connectedDeviceListMutex);
     if (!g_connectedDeviceList)
     {
-        OIC_LOG(ERROR, TAG, "no deviceList");
-        return;
+        OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
+        ca_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
     }
 
-    uint32_t index;
-    for (index = 0; index < u_arraylist_length(g_connectedDeviceList); index++)
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
-
         if (jarrayObj)
         {
             (*env)->DeleteGlobalRef(env, jarrayObj);
@@ -1148,21 +1935,28 @@ void CALEServerRemoveAllDevices(JNIEnv *env)
 
     OICFree(g_connectedDeviceList);
     g_connectedDeviceList = NULL;
-    return;
+    ca_mutex_unlock(g_connectedDeviceListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
+    return CA_STATUS_OK;
 }
 
-void CALEServerRemoveDevice(JNIEnv *env, jstring address)
+CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
 {
-    OIC_LOG(DEBUG, TAG, "CALEServerRemoveDevice");
+    OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(address, TAG, "address is null");
 
+    ca_mutex_lock(g_connectedDeviceListMutex);
     if (!g_connectedDeviceList)
     {
         OIC_LOG(ERROR, TAG, "no deviceList");
-        return;
+        ca_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
     }
 
-    uint32_t index;
-    for (index = 0; index < u_arraylist_length(g_connectedDeviceList); index++)
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
     {
         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
 
@@ -1174,28 +1968,65 @@ void CALEServerRemoveDevice(JNIEnv *env, jstring address)
                 OIC_LOG(ERROR, TAG, "wrong device address");
                 continue;
             }
-            const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress,
-            NULL);
-            const char* remoteAddress = (*env)->GetStringUTFChars(env, address,
-            NULL);
+            const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+            if (!setAddress)
+            {
+                OIC_LOG(ERROR, TAG, "setAddress is null");
+                continue;
+            }
+
+            const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
+            if (!remoteAddress)
+            {
+                OIC_LOG(ERROR, TAG, "remoteAddress is null");
+                (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+                continue;
+            }
 
             if (!strcmp(setAddress, remoteAddress))
             {
                 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
+
+                (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+                (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
                 (*env)->DeleteGlobalRef(env, jarrayObj);
 
-                CALEServerReorderinglist(index);
-                return;
+                CAResult_t res = CALEServerReorderinglist(index);
+                if (CA_STATUS_OK != res)
+                {
+                    OIC_LOG(ERROR, TAG, "CALEServerReorderinglist has failed");
+                    ca_mutex_unlock(g_connectedDeviceListMutex);
+                    return res;
+                }
+                ca_mutex_unlock(g_connectedDeviceListMutex);
+                return CA_STATUS_OK;
             }
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
         }
-    }OIC_LOG(DEBUG, TAG, "no target object");
-    return;
+    }
+
+    ca_mutex_unlock(g_connectedDeviceListMutex);
+
+    OIC_LOG(DEBUG, TAG, "there are no device in the device list");
+
+    OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
+    return CA_STATUS_FAILED;
 }
 
-void CALEServerReorderinglist(uint32_t index)
+CAResult_t CALEServerReorderinglist(uint32_t index)
 {
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
+        return CA_STATUS_FAILED;
+    }
+
     if (index >= g_connectedDeviceList->length)
-        return;
+    {
+        OIC_LOG(ERROR, TAG, "index is not available");
+        return CA_STATUS_FAILED;
+    }
 
     if (index < g_connectedDeviceList->length - 1)
     {
@@ -1205,41 +2036,150 @@ void CALEServerReorderinglist(uint32_t index)
 
     g_connectedDeviceList->size--;
     g_connectedDeviceList->length--;
+
+    return CA_STATUS_OK;
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CARegisterLeGattServerCallback(JNIEnv *env, jobject obj,
+                                                                         jobject callback)
+{
+    OIC_LOG(DEBUG, TAG, "caleserverinterface - Register Le Gatt Server Callback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
+
+    g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CARegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
+                                                                                 jobject obj,
+                                                                                 jobject callback)
+{
+    OIC_LOG(DEBUG, TAG, "caleserverinterface - Register Le Advertise Callback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
+
+    g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerConnectionStateChangeCallback(
+        JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
+{
+    OIC_LOG(DEBUG, TAG, "caleserverinterface - Gatt Server ConnectionStateChange Callback");
+    OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
+
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(device, TAG, "device is null");
+
+    jclass jni_cid_bluetoothProfile = (*env)->FindClass(env, "android/bluetooth/BluetoothProfile");
+    if (!jni_cid_bluetoothProfile)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothProfile is null");
+        return;
+    }
+
+    jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
+                                                                "STATE_CONNECTED", "I");
+    if(!jni_fid_state_connected)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_state_connected is null");
+        return;
+    }
+
+    jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
+                                                                   "STATE_DISCONNECTED", "I");
+    if(!jni_fid_state_disconnected)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_state_disconnected is null");
+        return;
+    }
+
+    // STATE_CONNECTED
+    jint jni_int_state_connected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
+                                                             jni_fid_state_connected);
+
+    // STATE_DISCONNECTED
+    jint jni_int_state_disconnected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
+                                                                jni_fid_state_disconnected);
+
+    if (newState == jni_int_state_connected)
+    {
+
+        OIC_LOG(DEBUG, TAG, "LE CONNECTED");
+
+        jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
+        if (!jni_remoteAddress)
+        {
+            OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
+            return;
+        }
+
+        const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+        if (!remoteAddress)
+        {
+            OIC_LOG(ERROR, TAG, "remoteAddress is null");
+            return;
+        }
+
+        if (false == CALEServerIsDeviceInList(env, remoteAddress))
+        {
+            OIC_LOG(DEBUG, TAG, "add connected device to cache");
+            CALEServerAddDeviceToList(env, device);
+        }
+        (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
+    }
+    else if (newState == jni_int_state_disconnected)
+    {
+        OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
+    }
+    else
+    {
+        OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
+                status);
+    }
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerServiceAddedCallback(JNIEnv *env, jobject obj,
-                                                                       jint status,
-                                                                       jobject gattService)
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerServiceAddedCallback(JNIEnv *env,
+                                                                             jobject obj,
+                                                                             jint status,
+                                                                             jobject gattService)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Service Added Callback(%d)", status);
+    OIC_LOG_V(DEBUG, TAG, "caleserverinterface - Gatt Service Added Callback(%d)", status);
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerCharacteristicReadRequestCallback(
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicReadRequestCallback(
         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset,
         jobject characteristic, jbyteArray data)
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Read Request Callback");
+    OIC_LOG(DEBUG, TAG, "caleserverinterface - Gatt Server Characteristic Read Request Callback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(device, TAG, "device is null");
+
+#ifdef USE_PROPERTY_WRITE_RESPONSE
+    CALEServerSendResponse(env, device, requestId, 0, offset, NULL);
+#endif
 
-    CANativeLEServerSendResponse(env, device, requestId, 0, offset, NULL);
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerCharacteristicWriteRequestCallback(
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicWriteRequestCallback(
         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject characteristic,
         jbyteArray data, jboolean preparedWrite, jboolean responseNeeded, jint offset,
         jbyteArray value)
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Write Request Callback");
-
-    CANativeLEServerSendResponse(env, device, requestId, 0, offset, value);
+    OIC_LOG(DEBUG, TAG, "caleserverinterface - Gatt Server Characteristic Write Request Callback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(device, TAG, "device is null");
+    VERIFY_NON_NULL_VOID(value, TAG, "value is null");
+    VERIFY_NON_NULL_VOID(data, TAG, "data is null");
 
-    if (data == NULL)
-    {
-        OIC_LOG(ERROR, TAG, "Reqeust data is null");
-        return;
-    }
+#ifdef USE_PROPERTY_WRITE_RESPONSE
+    CALEServerSendResponse(env, device, requestId, 0, offset, value);
+#endif
 
     // get Byte Array and covert to char*
     jint length = (*env)->GetArrayLength(env, data);
@@ -1248,155 +2188,258 @@ Java_com_iotivity_jar_caleinterface_CALeGattServerCharacteristicWriteRequestCall
     jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
 
     char* requestData = NULL;
-    requestData = (char*) OICCalloc(1, length + 1);
-    if (NULL == requestData)
+    requestData = (char*) OICMalloc(sizeof(char) * length + 1);
+    if (!requestData)
     {
         OIC_LOG(ERROR, TAG, "requestData is null");
         return;
     }
 
-    strncpy(requestData, (char*) jni_byte_requestData, length);
+    memcpy(requestData, (const char*) jni_byte_requestData, length);
     requestData[length] = '\0';
     (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
 
     jstring jni_address = CALEGetAddressFromBTDevice(env, device);
+    if (!jni_address)
+    {
+        OIC_LOG(ERROR, TAG, "jni_address is null");
+        OICFree(requestData);
+        return;
+    }
+
     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
-    OIC_LOG_V(DEBUG, TAG, "remote device address : %s", address);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is null");
+        OICFree(requestData);
+        return;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %s, %d", address, requestData, length);
+
+    ca_mutex_lock(g_bleClientBDAddressMutex);
+    uint32_t sentLength = 0;
+    g_CABLEServerDataReceivedCallback(address, OIC_GATT_SERVICE_UUID, requestData, length,
+                                      &sentLength);
+    ca_mutex_unlock(g_bleClientBDAddressMutex);
 
-    g_packetReceiveCallback(address, requestData);
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerDescriptorReadRequestCallback(JNIEnv *env,
-                                                                                jobject obj,
-                                                                                jobject device,
-                                                                                jint requestId,
-                                                                                jint offset,
-                                                                                jobject descriptor)
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerDescriptorReadRequestCallback(
+        JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject descriptor)
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface_CALeGattServerDescriptorReadRequestCallback");
+    OIC_LOG(DEBUG, TAG, "caleserverinterface_CALeGattServerDescriptorReadRequestCallback");
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerDescriptorWriteRequestCallback(
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerDescriptorWriteRequestCallback(
         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject descriptor,
         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface_CALeGattServerDescriptorWriteRequestCallback");
+    OIC_LOG(DEBUG, TAG, "caleserverinterface_CALeGattServerDescriptorWriteRequestCallback");
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerExecuteWriteCallback(JNIEnv *env, jobject obj,
-                                                                       jobject device,
-                                                                       jint requestId,
-                                                                       jboolean execute)
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerExecuteWriteCallback(JNIEnv *env,
+                                                                             jobject obj,
+                                                                             jobject device,
+                                                                             jint requestId,
+                                                                             jboolean execute)
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface_CALeGattServerExecuteWriteCallback");
+    OIC_LOG(DEBUG, TAG, "caleserverinterface_CALeGattServerExecuteWriteCallback");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(device, TAG, "device is null");
 
-    CANativeLEServerSendResponse(env, device, requestId, 0, 0, NULL);
+//    CALEServerSendResponse(env, device, requestId, 0, 0, NULL);
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerNotificationSentCallback(JNIEnv *env, jobject obj,
-                                                                           jobject device,
-                                                                           jint status)
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerNotificationSentCallback(JNIEnv *env,
+                                                                                 jobject obj,
+                                                                                 jobject device,
+                                                                                 jint status)
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface - Gatt Server Notification Sent Callback");
+    OIC_LOG(DEBUG, TAG, "caleserverinterface - Gatt Server Notification Sent Callback");
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeAdvertiseStartSuccessCallback(JNIEnv *env, jobject obj,
-                                                                      jobject settingsInEffect)
+Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartSuccessCallback(
+        JNIEnv *env, jobject obj, jobject settingsInEffect)
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface - LE Advertise Start Success Callback");
+    OIC_LOG(DEBUG, TAG, "caleserverinterface - LE Advertise Start Success Callback");
 }
 
 JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeAdvertiseStartFailureCallback(JNIEnv *env, jobject obj,
-                                                                      jint errorCode)
+Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartFailureCallback(JNIEnv *env,
+                                                                            jobject obj,
+                                                                            jint errorCode)
 {
-    OIC_LOG_V(ERROR, TAG, "CALeInterface - LE Advertise Start Failure Callback(%)", errorCode);
+    OIC_LOG_V(ERROR, TAG, "caleserverinterface - LE Advertise Start Failure Callback(%)",
+              errorCode);
 }
 
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CARegisterLeGattServerCallback(JNIEnv *env, jobject obj,
-                                                                   jobject callback)
+/**
+ * adapter common
+ */
+
+CAResult_t CAStartBleGattServer()
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface - Register Le Gatt Server Callback");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
+    CAResult_t ret = CALEServerInitMutexVaraibles();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed!");
+        CALEServerTerminateMutexVaraibles();
+        return CA_SERVER_NOT_STARTED;
+    }
+
+    ret = CALEServerInitConditionVaraibles();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerInitConditionVaraibles has failed!");
+        CALEServerTerminateConditionVaraibles();
+        return CA_SERVER_NOT_STARTED;
+    }
+
+    // start gatt service
+    CALEServerStartMulticastServer();
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CARegisterBluetoothLeAdvertiseCallback(JNIEnv *env, jobject obj,
-                                                                           jobject callback)
+CAResult_t CAStopBleGattServer()
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface - Register Le Advertise Callback");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerConnectionStateChangeCallback(JNIEnv *env,
-                                                                                jobject obj,
-                                                                                jobject device,
-                                                                                jint status,
-                                                                                jint newState)
+void CATerminateBleGattServer()
 {
-    OIC_LOG(DEBUG, TAG, "CALeInterface - Gatt Server ConnectionStateChange Callback");
+    OIC_LOG(DEBUG, TAG, "IN");
 
-    OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
+    OIC_LOG(DEBUG, TAG, "Terminat Gatt Server");
+    CALEServerTerminate();
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
 
-    if (!device)
+void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    ca_mutex_lock(g_bleReqRespCbMutex);
+    g_CABLEServerDataReceivedCallback = callback;
+    ca_mutex_unlock(g_bleReqRespCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *charValue,
+                                               const uint32_t charValueLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL(address, TAG, "env is null");
+    VERIFY_NON_NULL(charValue, TAG, "device is null");
+
+    if (address)
     {
-        OIC_LOG(ERROR, TAG, "device is null");
-        return;
+        OIC_LOG(DEBUG, TAG, "CALEServerSendUnicastData");
+        CALEServerSendUnicastMessage(address, charValue, charValueLen);
     }
 
-    jclass jni_cid_bluetoothProfile = (*env)->FindClass(env, "android/bluetooth/BluetoothProfile");
-
-    jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
-                                                                "STATE_CONNECTED", "I");
+    OIC_LOG(DEBUG, TAG, "OUT");
 
-    jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
-                                                                   "STATE_DISCONNECTED", "I");
+    return CA_STATUS_OK;
+}
 
-// STATE_CONNECTED
-    jint jni_int_state_connected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
-                                                             jni_fid_state_connected);
+CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
+                                                   const uint32_t charValueLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL(charValue, TAG, "device is null");
 
-// STATE_DISCONNECTED
-    jint jni_int_state_disconnected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
-                                                                jni_fid_state_disconnected);
+    OIC_LOG(DEBUG, TAG, "CALEServerSendMulticastMessage");
+    CALEServerSendMulticastMessage(charValue, charValueLen);
 
-    if (newState == jni_int_state_connected)
-    {
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
 
-        OIC_LOG(DEBUG, TAG, "LE CONNECTED");
+void CASetBleServerThreadPoolHandle(ca_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
 
-        jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
-        if (!jni_remoteAddress)
-        {
-            OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
-            return;
-        }
+    CALEServerInitialize(handle);
 
-        const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
 
-        if (g_connectedDeviceList == NULL)
+CAResult_t CALEServerInitMutexVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (NULL == g_bleReqRespCbMutex)
+    {
+        g_bleReqRespCbMutex = ca_mutex_new();
+        if (NULL == g_bleReqRespCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
         }
+    }
 
-        if (CALEServerIsDeviceInList(env, remoteAddress) == JNI_FALSE)
+    if (NULL == g_bleClientBDAddressMutex)
+    {
+        g_bleClientBDAddressMutex = ca_mutex_new();
+        if (NULL == g_bleClientBDAddressMutex)
         {
-            OIC_LOG(DEBUG, TAG, "add connected device to cache");
-            CALEServerAddDeviceToList(env, device);
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
         }
     }
-    else if (newState == jni_int_state_disconnected)
+
+    if (NULL == g_connectedDeviceListMutex)
     {
-        OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
+        g_connectedDeviceListMutex = ca_mutex_new();
+        if (NULL == g_connectedDeviceListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
     }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEServerInitConditionVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "this method is not supported");
+    return CA_STATUS_OK;
+}
+
+void CALEServerTerminateMutexVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    ca_mutex_free(g_bleReqRespCbMutex);
+    g_bleReqRespCbMutex = NULL;
+
+    ca_mutex_free(g_bleClientBDAddressMutex);
+    g_bleClientBDAddressMutex = NULL;
+
+    ca_mutex_free(g_connectedDeviceListMutex);
+    g_connectedDeviceListMutex = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
+void CALEServerTerminateConditionVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "this method is not supported");
+}
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.h b/resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.h
new file mode 100644 (file)
index 0000000..99230ed
--- /dev/null
@@ -0,0 +1,330 @@
+/******************************************************************
+ *
+ * Copyright 2014 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.
+ *
+ ******************************************************************/
+
+/**
+ * @file caleserver.h
+ * @brief This file contains the APIs for BT LE communications.
+ */
+#ifndef CA_LESERVER_H_
+#define CA_LESERVER_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+#include "jni.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @brief Callback to be notified on reception of any data from remote devices.
+ * @param  address           [IN] MAC address of remote device.
+ * @param  data              [IN] Data received from remote device.
+ * @return None
+ * @pre  Callback must be registered using CALEServerSetCallback(CAPacketReceiveCallback callback)
+ */
+typedef void (*CAPacketReceiveCallback)(const char *address, const char *data);
+
+/**
+ * @brief   initialize server for BLE
+ * @param   handle           [IN] thread pool handle object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerInitialize(ca_thread_pool_t handle);
+
+/**
+ * @brief   terminate client for BLE
+ * @return  None
+ */
+void CALEServerTerminate();
+
+/**
+ * @brief   send data for unicast (interface)
+ * @param   address          [IN] remote address
+ * @param   data             [IN] data for transmission
+ * @param   dataLen          [IN] data length
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerSendUnicastMessage(const char *address, const char *data, uint32_t dataLen);
+
+/**
+ * @brief   send data for multicast (interface)
+ * @param   data             [IN] data for transmission
+ * @param   dataLen          [IN] data length
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerSendMulticastMessage(const char *data, uint32_t dataLen);
+
+/**
+ * @brief   start multicast server (start advertise)
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerStartMulticastServer();
+
+/**
+ * @brief   stop multicast server (stop discovery)
+ * @return  None
+ */
+CAResult_t CALEServerStopMulticastServer();
+
+/**
+ * @brief   set this callback for receiving data packets from peer devices.
+ * @param   callback         [IN] callback to be notified on reception of
+ *                                unicast/multicast data packets.
+ * @return  None
+ */
+void CALEServerSetCallback(CAPacketReceiveCallback callback);
+
+/**
+ * @brief   send data for unicast (implement)
+ * @param   env              [IN] JNI interface pointer
+ * @param   address          [IN] remote address
+ * @param   data             [IN] data for transmission
+ * @param   dataLen          [IN] data length
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char *address, const char *data,
+                                            uint32_t dataLen);
+
+/**
+ * @brief   send data for multicast (implement)
+ * @param   env              [IN] JNI interface pointer
+ * @param   data             [IN] data for transmission
+ * @param   dataLen          [IN] data length
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen);
+
+/* Android BLE Server Functions */
+/**
+ * @brief   set context of application
+ * @return  None
+ */
+void CALEServerJNISetContext();
+
+/**
+ * @brief   initialize JNI object
+ * @return  None
+ */
+void CALeServerJniInit();
+
+/**
+ * @brief   create interface object and initialize the object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerCreateJniInterfaceObject();
+
+/**
+ * @brief   start advertise in gatt server
+ * @param   env                [IN] JNI interface pointer
+ * @param   advertiseCallback  [IN] callback to be notified on reception of
+ *                                advertisement result
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback);
+
+/**
+ * @brief   stop advertise in gatt server
+ * @param   env                [IN] JNI interface pointer
+ * @param   advertiseCallback  [IN] callback to be notified on reception of
+ *                                advertisement result
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback);
+
+/**
+ * @brief   open a gatt server
+ * @param   env                [IN] JNI interface pointer
+ * @return  gatt server object
+ */
+jobject CALEServerOpenGattServer(JNIEnv *env);
+
+/**
+ * @brief   create gatt service
+ * @param   env                [IN] JNI interface pointer
+ * @return  gatt service object
+ */
+jobject CALEServerCreateGattService(JNIEnv *env);
+
+/**
+ * @brief   add a descriptor to the characteristic
+ * @param   env                [IN] JNI interface pointer
+ * @param   characteristic     [IN] Characteristic object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic);
+
+/**
+ * @brief   create gatt service
+ * @param   env                  [IN] JNI interface pointer
+ * @param   bluetoothGattServer  [IN] Bluetooth Gatt Server object
+ * @param   bluetoothGattService [IN] Bluetooth Gatt Service object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
+                                    jobject bluetoothGattService);
+
+/**
+ * @brief   start gatt server
+ * @param   env                  [IN] JNI interface pointer
+ * @param   gattServerCallback   [IN] callback to be notified on reception of
+ *                                state change of gatt server
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback);
+
+/**
+ * @brief   send data
+ * @param   env                  [IN] JNI interface pointer
+ * @param   bluetoothDevice      [IN] bluetooth device object
+ * @param   data                 [IN] data which send
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jstring data);
+
+/**
+ * @brief   set data in BluetoothGattCharacteristic
+ * @param   env                  [IN] JNI interface pointer
+ * @param   responseData         [IN] data to set in characteristic object
+ * @return  BluetoothGattCharacteristic object
+ */
+jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData);
+
+/**
+ * @brief   send data through notifyCharacteristicChanged api of android
+ * @param   env                  [IN] JNI interface pointer
+ * @param   device               [IN] bluetooth device object
+ * @param   responseData         [IN] data which send
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData);
+
+/**
+ * @brief   send a response to a write request to a remote device
+ * @param   env                  [IN] JNI interface pointer
+ * @param   device               [IN] bluetooth device object
+ * @param   requestId            [IN] the id of request
+ * @param   status               [IN] the status of the request to be sent to the remote devices
+ * @param   offset               [IN] value offset for partial write response
+ * @param   value                [IN] the value of the attribute that written (optional)
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
+                                  jint offset, jbyteArray value);
+
+/**
+ * @brief   connect BLE to remote device form gatt server
+ * @param   env                  [IN] JNI interface pointer
+ * @param   bluetoothDevice      [IN] bluetooth device object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice);
+
+/**
+ * @brief   disconnect LE for all devices
+ * @param   env                  [IN] JNI interface pointer
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env);
+
+/**
+ * @brief   disconnect LE to remote device form gatt server
+ * @param   env                  [IN] JNI interface pointer
+ * @param   bluetoothDevice      [IN] bluetooth device object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice);
+
+/* BLE Server Utils */
+/**
+ * @brief   create connected device list
+ * @return  None
+ */
+void CALEServerCreateCachedDeviceList();
+
+/**
+ * @brief   check whether the device exist in the list or not
+ * @param   env                   [IN] JNI interface pointer
+ * @param   remoteAddress         [IN] remote address
+ * @return  true or false
+ */
+bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress);
+
+/**
+ * @brief   add device object to the list (connected device list)
+ * @param   env                   [IN] JNI interface pointer
+ * @param   device                [IN] bluetooth device object
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device);
+
+/**
+ * @brief   remove all devices objects in the list (connected device list)
+ * @param   env                   [IN] JNI interface pointer
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerRemoveAllDevices(JNIEnv *env);
+
+/**
+ * @brief   remove target device in the list (connected device list)
+ * @param   env                   [IN] JNI interface pointer
+ * @param   address               [IN] target address to remove
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address);
+
+/**
+ * @brief   Reordering for the list (connected device list)
+ * @param   index                 [IN] index of device list that want to reordering
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerReorderinglist(uint32_t index);
+
+/**
+ * @brief   initialize mutex
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerInitMutexVaraibles();
+
+/**
+ * @brief   terminate mutex
+ * @return  None
+ */
+void CALEServerTerminateMutexVaraibles();
+
+/**
+ * @brief   initialize condition
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALEServerInitConditionVaraibles();
+
+/**
+ * @brief   terminate condition
+ * @return  None
+ */
+void CALEServerTerminateConditionVaraibles();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_LESERVER_H_ */
index b6d90d0..c7f597f 100644 (file)
 #include <jni.h>
 #include <stdio.h>
 #include <android/log.h>
+
 #include "caleutils.h"
 #include "logger.h"
 #include "oic_malloc.h"
 #include "cathreadpool.h"
 #include "uarraylist.h"
+#include "caadapterutils.h"
 
 #define TAG PCF("CA_LE_UTILS")
 
 
 jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
 {
+    VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
 
     OIC_LOG(DEBUG, TAG, "CALEGetUuidFromString");
 
     jclass jni_cid_UUID = (*env)->FindClass(env, "java/util/UUID");
+    if (!jni_cid_UUID)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_UUID is not available");
+        return NULL;
+    }
 
-    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
-            env, jni_cid_UUID, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
+    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_UUID, "fromString",
+                                                             "(Ljava/lang/String;)"
+                                                             "Ljava/util/UUID;");
+    if (!jni_mid_fromString)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_fromString is not available");
+        return NULL;
+    }
 
     jstring str_uuid = (*env)->NewStringUTF(env, uuid);
+    if (!str_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "str_uuid is not available");
+        return NULL;
+    }
 
     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_UUID, jni_mid_fromString,
                                                           str_uuid);
     if (!jni_obj_uuid)
     {
-        OIC_LOG(DEBUG, TAG, "Fail to get jni uuid object");
+        OIC_LOG(ERROR, TAG, "Fail to get jni uuid object");
         return NULL;
     }
 
@@ -59,73 +79,80 @@ jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
 jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid)
 {
     OIC_LOG(DEBUG, TAG, "CALEGetParcelUuid");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
 
     jclass jni_cid_ParcelUuid = (*env)->FindClass(env, "android/os/ParcelUuid");
+    if (!jni_cid_ParcelUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_ParcelUuid is not available");
+        return NULL;
+    }
 
     jmethodID jni_mid_ParcelUuid = (*env)->GetMethodID(env, jni_cid_ParcelUuid, "<init>",
                                                        "(Ljava/util/UUID;)V");
+    if (!jni_mid_ParcelUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_ParcelUuid is not available");
+        return NULL;
+    }
 
     jobject jni_ParcelUuid = (*env)->NewObject(env, jni_cid_ParcelUuid, jni_mid_ParcelUuid, uuid);
     if (!jni_ParcelUuid)
     {
-        OIC_LOG(DEBUG, TAG, "Fail to get jni ParcelUuid");
+        OIC_LOG(ERROR, TAG, "Fail to get jni ParcelUuid");
         return NULL;
     }
 
     return jni_ParcelUuid;
 }
 
-jstring CALEGetLocalDeviceAddress(JNIEnv* env)
+bool CALEIsBondedDevice(JNIEnv *env, jobject bluetoothDevice)
 {
-    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
-    if (!jni_cid_BTAdapter)
-    {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_cid_BTAdapter is null");
-        return NULL;
-    }
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
+    VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", false);
 
-    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
-                                                                    "getDefaultAdapter",
-                                                                    METHODID_OBJECTNONPARAM);
-    if (!jni_mid_getDefaultAdapter)
+    jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
+    if (!jni_cid_device_list)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_mid_getDefaultAdapter is null");
-        return NULL;
+        OIC_LOG(ERROR, TAG, "jni_cid_device_list is null");
+        return false;
     }
 
-    jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTAdapter, "getAddress",
-    METHODID_STRINGNONPARAM);
-    if (!jni_mid_getAddress)
+    jmethodID jni_mid_getBondState = (*env)->GetMethodID(env, jni_cid_device_list, "getBondState",
+                                                         "()I");
+    if (!jni_mid_getBondState)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_mid_getAddress is null");
-        return NULL;
+        OIC_LOG(ERROR, TAG, "jni_mid_getBondState is null");
+        return false;
     }
 
-    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
-                                                               jni_mid_getDefaultAdapter);
-    if (!jni_obj_BTAdapter)
+    jint jni_bondState = (jint)(*env)->CallIntMethod(env, bluetoothDevice, jni_mid_getBondState);
+
+    OIC_LOG_V(DEBUG, TAG, "bond state is %d", jni_bondState);
+
+    if (BOND_BONDED == jni_bondState)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_obj_BTAdapter is null");
-        return NULL;
+        OIC_LOG(DEBUG, TAG, "remote device is bonded");
+        return true;
     }
-
-    jstring jni_str_address = (jstring)(*env)->CallObjectMethod(env, jni_obj_BTAdapter,
-                                                                jni_mid_getAddress);
-    if (!jni_str_address)
+    else
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_str_address is null");
-        return NULL;
+        OIC_LOG(DEBUG, TAG, "remote device is not bonded");
+        return false;
     }
 
-    return jni_str_address;
+    return false;
 }
 
-jobjectArray CALEBondedDevices(JNIEnv *env)
+jobjectArray CALEGetBondedDevices(JNIEnv *env)
 {
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+
     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
     if (!jni_cid_BTAdapter)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_cid_BTAdapter is null");
+        OIC_LOG(ERROR, TAG, "getBondedDevices: jni_cid_BTAdapter is null");
         return NULL;
     }
 
@@ -137,7 +164,7 @@ jobjectArray CALEBondedDevices(JNIEnv *env)
                                                                jni_mid_getDefaultAdapter);
     if (!jni_obj_BTAdapter)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: bluetooth adapter is null");
+        OIC_LOG(ERROR, TAG, "getBondedDevices: bluetooth adapter is null");
         return NULL;
     }
 
@@ -147,7 +174,7 @@ jobjectArray CALEBondedDevices(JNIEnv *env)
                                                              "()Ljava/util/Set;");
     if (!jni_mid_getBondedDevices)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_mid_getBondedDevicesr is null");
+        OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_getBondedDevicesr is null");
         return NULL;
     }
 
@@ -155,19 +182,22 @@ jobjectArray CALEBondedDevices(JNIEnv *env)
                                                                 jni_mid_getBondedDevices);
     if (!jni_obj_setPairedDevices)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_obj_setPairedDevices is null");
+        OIC_LOG(ERROR, TAG, "getBondedDevices: jni_obj_setPairedDevices is null");
         return NULL;
     }
 
-    // Convert the set to an object array
-    // object[] array = Set<BluetoothDevice>.toArray();
     jclass jni_cid_Set = (*env)->FindClass(env, "java/util/Set");
+    if (!jni_cid_Set)
+    {
+        OIC_LOG(ERROR, TAG, "getBondedDevices : jni_cid_Set is null");
+        return NULL;
+    }
+
     jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray",
                                                     "()[Ljava/lang/Object;");
-
     if (!jni_mid_toArray)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_mid_toArray is null");
+        OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_toArray is null");
         return NULL;
     }
 
@@ -175,7 +205,7 @@ jobjectArray CALEBondedDevices(JNIEnv *env)
             (*env)->CallObjectMethod(env, jni_obj_setPairedDevices, jni_mid_toArray));
     if (!jni_arrayPairedDevices)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_arrayPairedDevices is null");
+        OIC_LOG(ERROR, TAG, "getBondedDevices: jni_arrayPairedDevices is null");
         return NULL;
     }
 
@@ -184,33 +214,100 @@ jobjectArray CALEBondedDevices(JNIEnv *env)
 
 jint CALEGetBTStateOnInfo(JNIEnv *env)
 {
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
+
     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
     if (!jni_cid_BTAdapter)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBTStateOnInfo: jni_cid_BTAdapter is null");
+        OIC_LOG(ERROR, TAG, "getBTStateOnInfo: jni_cid_BTAdapter is null");
         return -1;
     }
 
     jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
-    if (jni_fid_stateon == 0)
+    if (!jni_fid_stateon)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] get_field_state is 0");
+        OIC_LOG(ERROR, TAG, "get_field_state is not available");
         return -1;
     }
-    jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
 
-    OIC_LOG_V(DEBUG, TAG, "[BLE][Native] bluetooth STATE_ON state integer value : %d", jni_int_val);
+    jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
+    OIC_LOG_V(DEBUG, TAG, "bluetooth.STATE_ON state integer value : %d", jni_int_val);
 
     return jni_int_val;
 }
 
+CAResult_t CALECheckPlatformVersion(JNIEnv *env, uint16_t level)
+{
+    jint jni_int_sdk = CALEGetBuildVersion(env);
+    if (jni_int_sdk < level)
+    {
+        OIC_LOG(ERROR, TAG, "it is not supported");
+        return CA_NOT_SUPPORTED;
+    }
+
+    return CA_STATUS_OK;
+}
+
+jint CALEGetBuildVersion(JNIEnv *env)
+{
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
+
+    // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
+    jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION");
+    if (!jni_cls_version)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_version is null");
+        return -1;
+    }
+
+    jfieldID jni_fid_sdk = (*env)->GetStaticFieldID(env, jni_cls_version, "SDK_INT", "I");
+    if (!jni_fid_sdk)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_sdk is null");
+        return -1;
+    }
+
+    jint jni_int_sdk = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_sdk);
+    OIC_LOG_V(DEBUG, TAG, "sdk version is %d", jni_int_sdk);
+
+    return jni_int_sdk;
+}
+
+jint CALEGetBuildVersionCodeForName(JNIEnv *env, const char* versionName)
+{
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
+    VERIFY_NON_NULL_RET(versionName, TAG, "versionName is null", -1);
+
+    // VERSION is a nested class within android.os.Build (hence "$" rather than "/")
+    jclass jni_cls_version = (*env)->FindClass(env, "android/os/Build$VERSION_CODES");
+    if (!jni_cls_version)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cls_version is null");
+        return -1;
+    }
+
+    jfieldID jni_fid_version = (*env)->GetStaticFieldID(env, jni_cls_version, versionName, "I");
+    if (!jni_fid_version)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fid_version is null");
+        return -1;
+    }
+
+    jint jni_int_version = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_version);
+    OIC_LOG_V(DEBUG, TAG, "version [%s] is %d",versionName, jni_int_version);
+
+    return jni_int_version;
+}
+
 jboolean CALEIsEnableBTAdapter(JNIEnv *env)
 {
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", JNI_FALSE);
+
     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
     if (!jni_cid_BTAdapter)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTAdapter: jni_cid_BTAdapter is null");
-        return FALSE;
+        OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
+        return JNI_FALSE;
     }
 
     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
@@ -218,38 +315,42 @@ jboolean CALEIsEnableBTAdapter(JNIEnv *env)
                                                                     METHODID_OBJECTNONPARAM);
     if (!jni_mid_getDefaultAdapter)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getDefaultAdapter is null");
-        return FALSE;
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        return JNI_FALSE;
     }
 
     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
                                                                jni_mid_getDefaultAdapter);
     if (!jni_obj_BTAdapter)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
-        return FALSE;
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        return JNI_FALSE;
     }
 
     // isEnable()
     jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled", "()Z");
     if (!jni_mid_isEnable)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_isEnable is null");
-        return FALSE;
+        OIC_LOG(ERROR, TAG, "jni_mid_isEnable is null");
+        return JNI_FALSE;
     }
 
     jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
-    OIC_LOG_V(DEBUG, TAG, "[BLE][Native] adapter state is %d", jni_isEnable);
+    OIC_LOG_V(DEBUG, TAG, "adapter state is %d", jni_isEnable);
 
     return jni_isEnable;
 }
 
 jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
 {
+    OIC_LOG(DEBUG, TAG, "IN - CALEGetAddressFromBTDevice");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
+
     jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
     if (!jni_cid_device_list)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_device_list is null");
+        OIC_LOG(ERROR, TAG, "jni_cid_device_list is null");
         return NULL;
     }
 
@@ -257,7 +358,7 @@ jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
                                                        "()Ljava/lang/String;");
     if (!jni_mid_getAddress)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getAddress is null");
+        OIC_LOG(ERROR, TAG, "jni_mid_getAddress is null");
         return NULL;
     }
 
@@ -265,9 +366,10 @@ jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
                                                             jni_mid_getAddress);
     if (!jni_address)
     {
-        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
+        OIC_LOG(ERROR, TAG, "jni_address is null");
         return NULL;
     }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEGetAddressFromBTDevice");
     return jni_address;
 }
-
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.h b/resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.h
new file mode 100644 (file)
index 0000000..2757b91
--- /dev/null
@@ -0,0 +1,129 @@
+/******************************************************************
+ *
+ * Copyright 2014 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.
+ *
+ ******************************************************************/
+
+/**
+ * @file caleutils.h
+ * @brief This file contains the APIs for BT LE communications.
+ */
+#ifndef CA_LEUTILES_H_
+#define CA_LEUTILES_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+#include "jni.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Service UUID */
+static const char OIC_GATT_SERVICE_UUID[] = "713d0000-503e-4c75-ba94-3148f18d941e";
+static const char OIC_GATT_CHARACTERISTIC_RESPONSE_UUID[] = "713d0002-503e-4c75-ba94-3148f18d941e";
+static const char OIC_GATT_CHARACTERISTIC_REQUEST_UUID[] = "713d0003-503e-4c75-ba94-3148f18d941e";
+static const char OIC_GATT_CHARACTERISTIC_CONFIG_UUID[] = "00002902-0000-1000-8000-00805f9b34fb";
+
+static const uint32_t GATT_SUCCESS = 0;
+
+static const uint32_t BOND_BONDED = 12;
+static const uint32_t BOND_BONDING = 11;
+static const uint32_t BOND_NONE = 10;
+
+/**
+ * @brief   get uuid(jni object) from uuid(character)
+ * @param   env              [IN] JNI interface pointer
+ * @param   uuid             [IN] uuid(character)
+ * @return  uuid(jni object)
+ */
+jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid);
+
+/**
+ * @brief   get parcel uuid object
+ * @param   env              [IN] JNI interface pointer
+ * @param   uuid             [IN] uuid (jni object)
+ * @return  parcel uuid object
+ */
+jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid);
+
+/**
+ * @brief   get address from a local device
+ * @param   env              [IN] JNI interface pointer
+ * @return  local address
+ */
+jstring CALEGetLocalDeviceAddress(JNIEnv *env);
+
+/**
+ * @brief   get bonded list
+ * @param   env              [IN] JNI interface pointer
+ * @return  bonded list
+ */
+jobjectArray CALEGetBondedDevices(JNIEnv *env);
+
+/**
+ * @brief   get constants information of bluetooth state-on
+ * @param   env              [IN] JNI interface pointer
+ * @return  constants information of bluetooth state-on
+ */
+jint CALEGetBTStateOnInfo(JNIEnv *env);
+
+/**
+ * @brief   check this device can be supported as BLE client or server
+ * @param   env              [IN] JNI interface pointer
+ * @param   level            [IN] Android API Level to support
+ * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CALECheckPlatformVersion(JNIEnv *env, uint16_t level);
+
+/**
+ * @brief   get constants information of android.os.Build.VERSION.SDK_INT
+ * @param   env              [IN] JNI interface pointer
+ * @return  constants information of android.os.Build.VERSION.SDK_INT
+ */
+jint CALEGetBuildVersion(JNIEnv *env);
+
+/**
+ * @brief   get constants information of android.os.Build.VERSION_CODES.[VersionName]
+ * @param   env              [IN] JNI interface pointer
+ * @param   versionName      [IN] version name (.., KITKAT, LOLLIPOP, ..)
+ * @return  constants information of android.os.Build.VERSION_CODES.[VersionName]
+ */
+jint CALEGetBuildVersionCodeForName(JNIEnv *env, const char* versionName);
+
+/**
+ * @brief   get bluetooth adapter state information
+ * @param   env              [IN] JNI interface pointer
+ * @return  JNI_TRUE if the local adapter is turned on
+ */
+jboolean CALEIsEnableBTAdapter(JNIEnv *env);
+
+/**
+ * @brief   get address from remote device
+ * @param   env              [IN] JNI interface pointer
+ * @param   bluetoothDevice  [IN] bluetooth device object
+ * @return  remote address
+ */
+jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/com_iotivity_jar_caleinterface.h b/resource/csdk/connectivity/src/bt_le_adapter/android/com_iotivity_jar_caleinterface.h
deleted file mode 100644 (file)
index 1bbcb65..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-#include <jni.h>
-/* Header for class com_iotivity_jar_caleinterface */
-
-#ifndef _Included_com_iotivity_jar_caleinterface
-#define _Included_com_iotivity_jar_caleinterface
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CARegisterLeScanCallback
- * Signature: (Landroid/bluetooth/BluetoothAdapter/LeScanCallback;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CARegisterLeScanCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CARegisterLeGattCallback
- * Signature: (Landroid/bluetooth/BluetoothGattCallback;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CARegisterLeGattCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CARegisterLeGattServerCallback
- * Signature: (Landroid/bluetooth/BluetoothGattServerCallback;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CARegisterLeGattServerCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CARegisterBluetoothLeAdvertiseCallback
- * Signature: (Landroid/bluetooth/le/AdvertiseCallback;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CARegisterBluetoothLeAdvertiseCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeScanCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;I[B)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeScanCallback
-(JNIEnv *, jobject, jobject, jint, jbyteArray);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattConnectionStateChangeCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattConnectionStateChangeCallback
-(JNIEnv *, jobject, jobject, jint, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServicesDiscoveredCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServicesDiscoveredCallback
-(JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattCharacteristicReadCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicReadCallback
-(JNIEnv *, jobject, jobject, jobject, jbyteArray, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattCharacteristicWritjclasseCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicWriteCallback
-(JNIEnv *, jobject, jobject, jobject, jbyteArray, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattCharacteristicChangedCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattCharacteristicChangedCallback
-(JNIEnv *, jobject, jobject, jobject, jbyteArray);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattDescriptorReadCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattDescriptorReadCallback
-(JNIEnv *, jobject, jobject, jobject, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattDescriptorWriteCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattDescriptorWriteCallback
-(JNIEnv *, jobject, jobject, jobject, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattReliableWriteCompletedCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattReliableWriteCompletedCallback
-(JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattReadRemoteRssiCallback
- * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattReadRemoteRssiCallback
-(JNIEnv *, jobject, jobject, jint, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServerConnectionStateChangeCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;II)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerConnectionStateChangeCallback
-(JNIEnv *, jobject, jobject, jint, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServerServiceAddedCallback
- * Signature: (ILandroid/bluetooth/BluetoothGattService;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerServiceAddedCallback
-(JNIEnv *, jobject, jint, jobject);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServerCharacteristicReadRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;IILandroid/
- * bluetooth/BluetoothGattCharacteristic;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerCharacteristicReadRequestCallback
-(JNIEnv *, jobject, jobject, jint, jint, jobject, jbyteArray);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServerCharacteristicWriteRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/
- * BluetoothGattCharacteristic;ZZI[B)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerCharacteristicWriteRequestCallback
-(JNIEnv *, jobject, jobject, jint, jobject, jbyteArray, jboolean, jboolean, jint, jbyteArray);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServerDescriptorReadRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;IILandroid/bluetooth/
- * BluetoothGattDescriptor;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerDescriptorReadRequestCallback
-(JNIEnv *, jobject, jobject, jint, jint, jobject);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServerDescriptorWriteRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/
- * BluetoothGattDescriptor;ZZI[B)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerDescriptorWriteRequestCallback
-(JNIEnv *, jobject, jobject, jint, jobject, jboolean, jboolean, jint, jbyteArray);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServerExecuteWriteCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;IZ)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerExecuteWriteCallback
-(JNIEnv *, jobject, jobject, jint, jboolean);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeGattServerNotificationSentCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeGattServerNotificationSentCallback
-(JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeAdvertiseStartSuccessCallback
- * Signature: (Landroid/bluetooth/le/AdvertiseSettings;)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeAdvertiseStartSuccessCallback
-(JNIEnv *, jobject, jobject);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeAdvertiseStartFailureCallback
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeAdvertiseStartFailureCallback
-(JNIEnv *, jobject, jint);
-
-/*
- * Class:     com_iotivity_jar_caleinterface
- * Method:    CALeStateChangedCallback
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-Java_com_iotivity_jar_caleinterface_CALeStateChangedCallback
-(JNIEnv *, jobject, jint);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleclientinterface.h b/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleclientinterface.h
new file mode 100644 (file)
index 0000000..e57b2d1
--- /dev/null
@@ -0,0 +1,141 @@
+#include <jni.h>
+/* Header for class org_iotivity_jar_caleclientinterface */
+
+#ifndef CA_Included_org_iotivity_jar_caleclientinterface_H_
+#define CA_Included_org_iotivity_jar_caleclientinterface_H_
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CARegisterLeScanCallback
+ * Signature: (Landroid/bluetooth/BluetoothAdapter/LeScanCallback;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CARegisterLeScanCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CARegisterLeGattCallback
+ * Signature: (Landroid/bluetooth/BluetoothGattCallback;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CARegisterLeGattCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeScanCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;I[B)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeScanCallback
+(JNIEnv *, jobject, jobject, jint, jbyteArray);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattConnectionStateChangeCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattConnectionStateChangeCallback
+(JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattServicesDiscoveredCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattServicesDiscoveredCallback
+(JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattCharacteristicReadCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicReadCallback
+(JNIEnv *, jobject, jobject, jobject, jbyteArray, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattCharacteristicWritjclasseCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicWriteCallback
+(JNIEnv *, jobject, jobject, jobject, jbyteArray, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattCharacteristicChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattCharacteristicChangedCallback
+(JNIEnv *, jobject, jobject, jobject, jbyteArray);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattDescriptorReadCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorReadCallback
+(JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattDescriptorWriteCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattDescriptorWriteCallback
+(JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattReliableWriteCompletedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattReliableWriteCompletedCallback
+(JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeGattReadRemoteRssiCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeGattReadRemoteRssiCallback
+(JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeStateChangedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeStateChangedCallback
+(JNIEnv *, jobject, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleclientinterface
+ * Method:    CALeBondStateChangedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleclientinterface_CALeBondStateChangedCallback
+(JNIEnv *, jobject, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleserverinterface.h b/resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_jar_caleserverinterface.h
new file mode 100644 (file)
index 0000000..2f82092
--- /dev/null
@@ -0,0 +1,129 @@
+#include <jni.h>
+/* Header for class org_iotivity_jar_caleserverinterface */
+
+#ifndef CA_Included_org_iotivity_jar_caleserverinterface_H_
+#define CA_Included_org_iotivity_jar_caleserverinterface_H_
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CARegisterLeGattServerCallback
+ * Signature: (Landroid/bluetooth/BluetoothGattServerCallback;)V
+ */
+JNIEXPORT void JNICALL
+
+Java_org_iotivity_jar_caleserverinterface_CARegisterLeGattServerCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CARegisterBluetoothLeAdvertiseCallback
+ * Signature: (Landroid/bluetooth/le/AdvertiseCallback;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CARegisterBluetoothLeAdvertiseCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeGattServerConnectionStateChangeCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerConnectionStateChangeCallback
+(JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeGattServerServiceAddedCallback
+ * Signature: (ILandroid/bluetooth/BluetoothGattService;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerServiceAddedCallback
+(JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeGattServerCharacteristicReadRequestCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;IILandroid/
+ * bluetooth/BluetoothGattCharacteristic;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicReadRequestCallback
+(JNIEnv *, jobject, jobject, jint, jint, jobject, jbyteArray);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeGattServerCharacteristicWriteRequestCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/
+ * BluetoothGattCharacteristic;ZZI[B)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerCharacteristicWriteRequestCallback
+(JNIEnv *, jobject, jobject, jint, jobject, jbyteArray, jboolean, jboolean, jint, jbyteArray);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeGattServerDescriptorReadRequestCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;IILandroid/bluetooth/
+ * BluetoothGattDescriptor;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerDescriptorReadRequestCallback
+(JNIEnv *, jobject, jobject, jint, jint, jobject);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeGattServerDescriptorWriteRequestCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/
+ * BluetoothGattDescriptor;ZZI[B)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerDescriptorWriteRequestCallback
+(JNIEnv *, jobject, jobject, jint, jobject, jboolean, jboolean, jint, jbyteArray);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeGattServerExecuteWriteCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;IZ)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerExecuteWriteCallback
+(JNIEnv *, jobject, jobject, jint, jboolean);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeGattServerNotificationSentCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeGattServerNotificationSentCallback
+(JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeAdvertiseStartSuccessCallback
+ * Signature: (Landroid/bluetooth/le/AdvertiseSettings;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartSuccessCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_jar_caleserverinterface
+ * Method:    CALeAdvertiseStartFailureCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_jar_caleserverinterface_CALeAdvertiseStartFailureCallback
+(JNIEnv *, jobject, jint);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+