replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_edr_adapter / android / caedrserver.c
index 1a9cf1f..0ef0117 100644 (file)
 #include "logger.h"
 #include "oic_malloc.h"
 #include "cathreadpool.h" /* for thread pool */
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caadapterutils.h"
 #include "org_iotivity_ca_CaEdrInterface.h"
 #include "oic_string.h"
 
-//#define DEBUG_MODE
-#define TAG PCF("CA_EDR_SERVER")
-#define MAX_PDU_BUFFER (1024)
+#define TAG PCF("OIC_CA_EDR_SERVER")
 
 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
+static const char CLASSPATH_BT_SERVER_SOCKET[] = "android/bluetooth/BluetoothServerSocket";
 
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
 static JavaVM *g_jvm;
 
 /**
- * Maximum CoAP over TCP header length
- * to know the total data length.
+ * when Both Mode(server and client) in App is set,
+ * startDiscoveryServer and startListenningServer is calling.
+ * and then both accept thread and receive thread is running redundantly.
  */
-#define EDR_MAX_HEADER_LEN  6
+static bool g_isStartServer = false;
 
 /**
- * server socket instance.
+ * Maximum CoAP over TCP header length
+ * to know the total data length.
  */
-static jobject g_serverSocketObject = NULL;
+#define EDR_MAX_HEADER_LEN  6
 
 /**
- * Mutex to synchronize unicast server.
+ * Mutex to synchronize receive server.
  */
-static ca_mutex g_mutexUnicastServer = NULL;
+static oc_mutex g_mutexReceiveServer = NULL;
 
 /**
  * Flag to control the Receive Unicast Data Thread.
@@ -68,19 +69,9 @@ static ca_mutex g_mutexUnicastServer = NULL;
 static bool g_stopUnicast = false;
 
 /**
- * Mutex to synchronize secure multicast server.
- */
-static ca_mutex g_mutexMulticastServer = NULL;
-
-/**
- * Flag to control the Receive Multicast Data Thread.
- */
-static bool g_stopMulticast = false;
-
-/**
  * Mutex to synchronize accept server.
  */
-static ca_mutex g_mutexAcceptServer = NULL;
+static oc_mutex g_mutexAcceptServer = NULL;
 
 /**
  * Flag to control the Accept Thread.
@@ -90,19 +81,27 @@ static bool g_stopAccept = false;
 /**
  * Mutex to synchronize server socket.
  */
-static ca_mutex g_mutexServerSocket = NULL;
+static oc_mutex g_mutexServerSocket = NULL;
 
+/**
+ * Flag to control the server socket.
+ */
 static jobject g_serverSocket = NULL;
 
 /**
  * Mutex to synchronize device state list.
  */
-static ca_mutex g_mutexStateList = NULL;
+static oc_mutex g_mutexStateList = NULL;
 
 /**
  * Mutex to synchronize device object list.
  */
-static ca_mutex g_mutexObjectList = NULL;
+static oc_mutex g_mutexObjectList = NULL;
+
+/**
+ * Mutex to synchronize start server state.
+ */
+static oc_mutex g_mutexStartServerState = NULL;
 
 /**
  * Thread context information for unicast, multicast and secured unicast server.
@@ -131,7 +130,7 @@ static void CAReceiveHandler(void *data)
     VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
 
     bool isAttached = false;
-    JNIEnv* env;
+    JNIEnv* env = NULL;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
@@ -150,6 +149,12 @@ static void CAReceiveHandler(void *data)
 
     while (true != *(ctx->stopFlag))
     {
+        if (!CAEDRNativeIsEnableBTAdapter(env))
+        {
+            OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+            break;
+        }
+
         // if new socket object is added in socket list after below logic is ran.
         // new socket will be started to read after next while loop
         uint32_t length = CAEDRGetSocketListLength();
@@ -157,7 +162,7 @@ static void CAReceiveHandler(void *data)
         {
             for (uint32_t idx = 0; idx < length; idx++)
             {
-                CAEDRNativeReadData(env, idx, ctx->type);
+                CAEDRNativeReadData(env, idx);
             }
         }
     }
@@ -176,14 +181,14 @@ static void CAAcceptHandler(void *data)
 {
     OIC_LOG(DEBUG, TAG, "AcceptThread start");
 
-    VERIFY_NON_NULL_VOID(data, TAG, "CAAcceptHandler: data is null");
+    VERIFY_NON_NULL_VOID(data, TAG, "data is null");
 
     bool isAttached = false;
-    JNIEnv* env;
+    JNIEnv* env = NULL;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
+        OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -197,7 +202,7 @@ static void CAAcceptHandler(void *data)
     jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
     if (!jni_obj_BTServerSocket)
     {
-        OIC_LOG(ERROR, TAG, "AcceptThread: jni_obj_BTServerSocket is null");
+        OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
 
         if (isAttached)
         {
@@ -207,31 +212,29 @@ static void CAAcceptHandler(void *data)
         return;
     }
 
-    ca_mutex_lock(g_mutexServerSocket);
+    oc_mutex_lock(g_mutexServerSocket);
     g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
-    ca_mutex_unlock(g_mutexServerSocket);
+    oc_mutex_unlock(g_mutexServerSocket);
 
     CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
 
     // it should be initialized for restart accept thread
-    ca_mutex_lock(g_mutexAcceptServer);
+    oc_mutex_lock(g_mutexAcceptServer);
     g_stopAccept = false;
-    ca_mutex_unlock(g_mutexAcceptServer);
+    oc_mutex_unlock(g_mutexAcceptServer);
 
     while (true != *(ctx->stopFlag))
     {
-        OIC_LOG(DEBUG, TAG, "AcceptThread running");
-
         // when BT state is changed with Off. its thread will be stopped
         if (!CAEDRNativeIsEnableBTAdapter(env))
         {
-            OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
-            ca_mutex_lock(g_mutexAcceptServer);
+            OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+            oc_mutex_lock(g_mutexAcceptServer);
             g_stopAccept = true;
-            ca_mutex_unlock(g_mutexAcceptServer);
-            ca_mutex_lock(g_mutexServerSocket);
+            oc_mutex_unlock(g_mutexAcceptServer);
+            oc_mutex_lock(g_mutexServerSocket);
             g_serverSocket = NULL;
-            ca_mutex_unlock(g_mutexServerSocket);
+            oc_mutex_unlock(g_mutexServerSocket);
         }
         else
         {
@@ -251,22 +254,38 @@ static void CAAcceptHandler(void *data)
     return;
 }
 
-CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
+/**
+ * implement for adapter common method.
+ */
+CAResult_t CAEDRServerStart()
 {
-    CAResult_t res = CAEDRServerInitialize(handle);
-    if (CA_STATUS_OK != res)
+    if (!g_threadPoolHandle)
     {
-        OIC_LOG(ERROR, TAG, "CAEDRServerInitialize failed");
-        CAEDRServerStop();
-        return CA_STATUS_FAILED;
+        return CA_STATUS_NOT_INITIALIZED;
     }
 
-    res = CAEDRStartUnicastServer(false);
-    if (CA_STATUS_OK != res)
+    oc_mutex_lock(g_mutexStartServerState);
+    if (g_isStartServer)
     {
-        OIC_LOG(ERROR, TAG, "CAEDRStartUnicastServer failed");
-        CAEDRServerStop();
-        return CA_STATUS_FAILED;
+        OIC_LOG(DEBUG, TAG, "server already started");
+        oc_mutex_unlock(g_mutexStartServerState);
+        return CA_STATUS_OK;
+    }
+    oc_mutex_unlock(g_mutexStartServerState);
+
+    CAResult_t res = CAEDRServerStartAcceptThread();
+    if (CA_STATUS_OK == res)
+    {
+        res = CAEDRStartReceiveThread(false);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "failed to start receive thread");
+            CAEDRServerStop();
+            return CA_STATUS_FAILED;
+        }
+        oc_mutex_lock(g_mutexStartServerState);
+        g_isStartServer = true;
+        oc_mutex_unlock(g_mutexStartServerState);
     }
 
     return res;
@@ -274,12 +293,11 @@ CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
 
 CAResult_t CAEDRServerStop()
 {
-    CAEDRStopUnicastServer();
-    CAEDRStopMulticastServer();
+    CAEDRStopReceiveThread();
 
-    ca_mutex_lock(g_mutexAcceptServer);
+    oc_mutex_lock(g_mutexAcceptServer);
     g_stopAccept = true;
-    ca_mutex_unlock(g_mutexAcceptServer);
+    oc_mutex_unlock(g_mutexAcceptServer);
 
     if (!g_jvm)
     {
@@ -288,7 +306,7 @@ CAResult_t CAEDRServerStop()
     }
 
     bool isAttached = false;
-    JNIEnv* env;
+    JNIEnv* env = NULL;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
@@ -304,6 +322,9 @@ CAResult_t CAEDRServerStop()
     }
 
     CAEDRNatvieCloseServerTask(env);
+    oc_mutex_lock(g_mutexStartServerState);
+    g_isStartServer = false;
+    oc_mutex_unlock(g_mutexStartServerState);
 
     if (isAttached)
     {
@@ -320,54 +341,54 @@ void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCall
 
 static void CAEDRServerDestroyMutex()
 {
-    if (g_mutexUnicastServer)
-    {
-        ca_mutex_free(g_mutexUnicastServer);
-        g_mutexUnicastServer = NULL;
-    }
-
-    if (g_mutexMulticastServer)
+    if (g_mutexReceiveServer)
     {
-        ca_mutex_free(g_mutexMulticastServer);
-        g_mutexMulticastServer = NULL;
+        oc_mutex_free(g_mutexReceiveServer);
+        g_mutexReceiveServer = NULL;
     }
 
     if (g_mutexAcceptServer)
     {
-        ca_mutex_free(g_mutexAcceptServer);
+        oc_mutex_free(g_mutexAcceptServer);
         g_mutexAcceptServer = NULL;
     }
 
     if (g_mutexServerSocket)
     {
-        ca_mutex_free(g_mutexServerSocket);
+        oc_mutex_free(g_mutexServerSocket);
         g_mutexServerSocket = NULL;
     }
 
     if (g_mutexStateList)
     {
-        ca_mutex_free(g_mutexStateList);
+        oc_mutex_free(g_mutexStateList);
         g_mutexStateList = NULL;
     }
 
     if (g_mutexObjectList)
     {
-        ca_mutex_free(g_mutexObjectList);
+        oc_mutex_free(g_mutexObjectList);
         g_mutexObjectList = NULL;
     }
+
+    if (g_mutexStartServerState)
+    {
+        oc_mutex_free(g_mutexStartServerState);
+        g_mutexStartServerState = NULL;
+    }
 }
 
 static CAResult_t CAEDRServerCreateMutex()
 {
-    g_mutexUnicastServer = ca_mutex_new();
-    if (!g_mutexUnicastServer)
+    g_mutexReceiveServer = oc_mutex_new();
+    if (!g_mutexReceiveServer)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
         return CA_STATUS_FAILED;
     }
 
-    g_mutexMulticastServer = ca_mutex_new();
-    if (!g_mutexMulticastServer)
+    g_mutexAcceptServer = oc_mutex_new();
+    if (!g_mutexAcceptServer)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
 
@@ -375,8 +396,8 @@ static CAResult_t CAEDRServerCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexAcceptServer = ca_mutex_new();
-    if (!g_mutexAcceptServer)
+    g_mutexServerSocket = oc_mutex_new();
+    if (!g_mutexServerSocket)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
 
@@ -384,8 +405,8 @@ static CAResult_t CAEDRServerCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexServerSocket = ca_mutex_new();
-    if (!g_mutexServerSocket)
+    g_mutexStateList = oc_mutex_new();
+    if (!g_mutexStateList)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
 
@@ -393,8 +414,8 @@ static CAResult_t CAEDRServerCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexStateList = ca_mutex_new();
-    if (!g_mutexStateList)
+    g_mutexObjectList = oc_mutex_new();
+    if (!g_mutexObjectList)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
 
@@ -402,8 +423,8 @@ static CAResult_t CAEDRServerCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexObjectList = ca_mutex_new();
-    if (!g_mutexObjectList)
+    g_mutexStartServerState = oc_mutex_new();
+    if (!g_mutexStartServerState)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
 
@@ -423,35 +444,18 @@ void CAEDRServerJniInit()
 CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
+    VERIFY_NON_NULL(handle, TAG, "handle is NULL");
 
     g_threadPoolHandle = handle;
+    CAEDRServerJniInit();
 
-    CAResult_t res = CAEDRServerStartAcceptThread();
-    if (CA_STATUS_OK != res)
-    {
-        OIC_LOG(ERROR, TAG, "CAEDRServerCreateMutex failed");
-        return res;
-    }
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-
-    return res;
+    return CAEDRServerCreateMutex();
 }
 
 CAResult_t CAEDRServerStartAcceptThread()
 {
-    CAEDRServerJniInit();
-
-    // init mutex
-    CAResult_t ret = CAEDRServerCreateMutex();
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(ERROR, TAG, "CAEDRServerCreateMutex failed");
-        return ret;
-    }
-
     bool isAttached = false;
-    JNIEnv* env;
+    JNIEnv* env = NULL;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
@@ -474,13 +478,13 @@ CAResult_t CAEDRServerStartAcceptThread()
         (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
     }
 
-    ca_mutex_lock(g_mutexStateList);
+    oc_mutex_lock(g_mutexStateList);
     CAEDRNativeCreateDeviceStateList();
-    ca_mutex_unlock(g_mutexStateList);
+    oc_mutex_unlock(g_mutexStateList);
 
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
     CAEDRNativeCreateDeviceSocketList();
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
 
     if (isAttached)
     {
@@ -496,7 +500,8 @@ CAResult_t CAEDRServerStartAcceptThread()
     }
 
     ctx->stopFlag = &g_stopAccept;
-    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
+    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler,
+                                                (void *) ctx, NULL))
     {
         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
         OICFree((void *) ctx);
@@ -515,7 +520,7 @@ void CAEDRServerTerminate()
         return;
     }
     bool isAttached = false;
-    JNIEnv* env;
+    JNIEnv* env = NULL;
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
@@ -544,11 +549,11 @@ void CAEDRServerTerminate()
     CAEDRServerDestroyMutex();
 }
 
-CAResult_t CAEDRStartUnicastServer(bool isSecured)
+CAResult_t CAEDRStartReceiveThread(bool isSecured)
 {
-    OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
+    OIC_LOG(DEBUG, TAG, "CAEDRStartReceiveThread");
 
-    ca_mutex_lock(g_mutexUnicastServer);
+    oc_mutex_lock(g_mutexReceiveServer);
 
     /**
      * The task to listen for data from unicast is added to the thread pool.
@@ -562,100 +567,40 @@ CAResult_t CAEDRStartUnicastServer(bool isSecured)
     if (!ctx)
     {
         OIC_LOG(ERROR, TAG, "Out of memory!");
-        ca_mutex_unlock(g_mutexUnicastServer);
+        oc_mutex_unlock(g_mutexReceiveServer);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
+    g_stopUnicast = false;
     ctx->stopFlag = &g_stopUnicast;
     ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
-    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
+    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler,
+                                                (void *) ctx, NULL))
     {
         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
-        ca_mutex_unlock(g_mutexUnicastServer);
-        OICFree((void *) ctx);
-        return CA_STATUS_FAILED;
-    }
-    ca_mutex_unlock(g_mutexUnicastServer);
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAEDRStartMulticastServer()
-{
-    OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
-
-    ca_mutex_lock(g_mutexMulticastServer);
-
-    /**
-     * The task to listen to data from multicast socket is added to the thread pool.
-     * This is a blocking call is made where we try to receive some data.
-     * We will keep waiting until some data is received.
-     * This task will be terminated when thread pool is freed on stopping the adapters.
-     * Thread context will be freed by thread on exit.
-     */
-    CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
-            sizeof(CAAdapterReceiveThreadContext_t));
-    if (!ctx)
-    {
-        OIC_LOG(ERROR, TAG, "Out of memory!");
-        ca_mutex_unlock(g_mutexMulticastServer);
-
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    ctx->stopFlag = &g_stopMulticast;
-    ctx->type = CA_MULTICAST_SERVER;
-
-    g_stopMulticast = false;
-    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
-    {
-        OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
-
-        g_stopMulticast = true;
-        ca_mutex_unlock(g_mutexMulticastServer);
+        oc_mutex_unlock(g_mutexReceiveServer);
         OICFree((void *) ctx);
-
         return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_mutexMulticastServer);
+    oc_mutex_unlock(g_mutexReceiveServer);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CAEDRStopUnicastServer()
+CAResult_t CAEDRStopReceiveThread()
 {
-    OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
+    OIC_LOG(DEBUG, TAG, "CAEDRStopReceiveThread");
 
-    ca_mutex_lock(g_mutexUnicastServer);
+    oc_mutex_lock(g_mutexReceiveServer);
     g_stopUnicast = true;
-    ca_mutex_unlock(g_mutexUnicastServer);
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAEDRStopMulticastServer()
-{
-    OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
-
-    ca_mutex_lock(g_mutexMulticastServer);
-    g_stopMulticast = true;
-    ca_mutex_unlock(g_mutexMulticastServer);
-
-    OIC_LOG(INFO, TAG, "Multicast server stopped");
+    oc_mutex_unlock(g_mutexReceiveServer);
 
     return CA_STATUS_OK;
 }
 
-CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
+CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t idx)
 {
-    if (!CAEDRNativeIsEnableBTAdapter(env))
-    {
-        OIC_LOG(ERROR, TAG, "BT adpater is not enable");
-        return CA_STATUS_INVALID_PARAM;
-    }
-
     if ((*env)->ExceptionCheck(env))
     {
         (*env)->ExceptionDescribe(env);
@@ -664,132 +609,132 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t
         return CA_STATUS_FAILED;
     }
 
-    // check whether this socket object is connected or not.
-    jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
-    if (!jni_obj_socket)
-    {
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
-    if (!jni_str_address)
-    {
-        OIC_LOG(ERROR, TAG, "jni_str_address is null");
-        return CA_STATUS_FAILED;
-    }
-    const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
-
-    // check it whether is still connected or not through google api
-    jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
-    if (!ret)
-    {
-        OIC_LOG(ERROR, TAG, "it is not connected yet.");
-
-        // remove socket to list
-        CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
-        (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
-        (*env)->DeleteLocalRef(env, jni_str_address);
-
-        return CA_STATUS_FAILED;
-    }
-
-    // start to read through InputStream
-    jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
-    if (!jni_cid_BTsocket)
-    {
-        OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null");
-        (*env)->DeleteLocalRef(env, jni_str_address);
-        return CA_STATUS_FAILED;
-    }
-    jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
-                                                           "getInputStream",
-                                                           "()Ljava/io/InputStream;");
-
-    jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
-                                                           jni_mid_getInputStream);
+    jobject jni_obj_inputStream = CAEDRNativeGetInputStream(idx);
     if (!jni_obj_inputStream)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
-        (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
-        (*env)->DeleteLocalRef(env, jni_str_address);
         return CA_STATUS_FAILED;
     }
 
-    jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
-    if (!jni_cid_InputStream)
-    {
-        OIC_LOG(ERROR, TAG, "jni_cid_InputStream is null");
-        goto exit;
-    }
-
-    jmethodID jni_mid_available = (*env)->GetMethodID(env, jni_cid_InputStream,
-                                                      "available", "()I");
+    jmethodID jni_mid_available = CAGetJNIMethodID(env, "java/io/InputStream", "available", "()I");
     if (!jni_mid_available)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_available is null");
-        goto exit;
+        return CA_STATUS_FAILED;
     }
 
     jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
 
-    CAConnectedDeviceInfo_t *deviceInfo = NULL;
     if (0 < available)
     {
-        OIC_LOG_V(DEBUG, TAG, "get InputStream..%d, %s", id, address);
-        jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream,
-                                                     "read", "([BII)I");
-        if (!jni_mid_read)
+        jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(idx);
+        if (!jni_obj_socket)
         {
-            OIC_LOG(ERROR, TAG, "jni_mid_read is null");
-            goto exit;
+            OIC_LOG(ERROR, TAG, "jni_obj_socket is null");
+            return CA_STATUS_FAILED;
+        }
+
+        jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
+        if (!jni_str_address)
+        {
+            OIC_LOG(ERROR, TAG, "jni_str_address is null");
+            return CA_STATUS_FAILED;
         }
 
-        deviceInfo = (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
+        const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
+        if (!address)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            (*env)->DeleteLocalRef(env, jni_str_address);
+            return CA_STATUS_FAILED;
+        }
+
+        CAConnectedDeviceInfo_t *deviceInfo =
+                (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
         if (!deviceInfo)
         {
             OIC_LOG(ERROR, TAG, "failed to get device info from list");
-            goto exit;
+            (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+            (*env)->DeleteLocalRef(env, jni_str_address);
+            return CA_STATUS_FAILED;
         }
 
-        jint bufSize = (deviceInfo->totalDataLen == 0) ?
-                EDR_MAX_HEADER_LEN : deviceInfo->totalDataLen;
+        jint bufSize = (deviceInfo->totalDataLen == 0) ? EDR_MAX_HEADER_LEN
+                                                       : deviceInfo->totalDataLen;
         if (!deviceInfo->recvData)
         {
             deviceInfo->recvData = OICCalloc(1, bufSize);
             if (!deviceInfo->recvData)
             {
                 OIC_LOG(ERROR, TAG, "out of memory");
-                goto exit;
+                (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+                (*env)->DeleteLocalRef(env, jni_str_address);
+                return CA_STATUS_FAILED;
             }
         }
 
-        jbyteArray jbuf = (*env)->NewByteArray(env, (jint) bufSize - deviceInfo->recvDataLen);
+        jint remainSize = (jint) bufSize - deviceInfo->recvDataLen;
+        if (0 >= remainSize)
+        {
+            OIC_LOG(ERROR, TAG, "remainSize value is invalid.");
+            (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+            (*env)->DeleteLocalRef(env, jni_str_address);
+            return CA_STATUS_FAILED;
+        }
+
+        jbyteArray jbuf = (*env)->NewByteArray(env, remainSize);
+        if (!jbuf)
+        {
+            OIC_LOG(ERROR, TAG, "jbuf is null");
+            (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+            (*env)->DeleteLocalRef(env, jni_str_address);
+            return CA_STATUS_FAILED;
+        }
+
+        jmethodID jni_mid_read = CAGetJNIMethodID(env, "java/io/InputStream", "read", "([BII)I");
+        if (!jni_mid_read)
+        {
+            OIC_LOG(ERROR, TAG, "jni_mid_read is null");
+            (*env)->DeleteLocalRef(env, jbuf);
+            (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+            (*env)->DeleteLocalRef(env, jni_str_address);
+            return CA_STATUS_FAILED;
+        }
+
+        OIC_LOG_V(DEBUG, TAG, "read InputStream (idx:%d, addr:%s)", idx, address);
         jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read,
-                                             jbuf, (jint) 0,
-                                             (jint) bufSize - deviceInfo->recvDataLen);
+                                             jbuf, (jint) 0, remainSize);
         if (-1 == recvLen)
         {
+            OIC_LOG(ERROR, TAG, "recvLen is -1");
             (*env)->DeleteLocalRef(env, jbuf);
-            goto exit;
+            (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+            (*env)->DeleteLocalRef(env, jni_str_address);
+            return CA_STATUS_FAILED;
         }
+        OIC_LOG_V(DEBUG, TAG, "read success (length: %d bytes)", recvLen);
 
         jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
         if (!buf)
         {
+            OIC_LOG(ERROR, TAG, "buf is null");
             (*env)->DeleteLocalRef(env, jbuf);
-            goto exit;
+            (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+            (*env)->DeleteLocalRef(env, jni_str_address);
+            return CA_STATUS_FAILED;
         }
         memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen);
         deviceInfo->recvDataLen += recvLen;
 
-        OIC_LOG(DEBUG, TAG, "read something from InputStream");
+        (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
+        (*env)->DeleteLocalRef(env, jbuf);
 
-        if (!deviceInfo->totalDataLen)
+        if (!deviceInfo->totalDataLen && deviceInfo->recvData)
         {
-            coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
+            coap_transport_t transport = coap_get_tcp_header_type_from_initbyte(
                     ((unsigned char *) deviceInfo->recvData)[0] >> 4);
             size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
-            if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen)
+            if (deviceInfo->recvDataLen >= headerLen)
             {
                 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
                                                                          deviceInfo->recvDataLen);
@@ -799,9 +744,9 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t
                 if (!newBuf)
                 {
                     OIC_LOG(ERROR, TAG, "out of memory");
-                    (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
-                    (*env)->DeleteLocalRef(env, jbuf);
-                    goto exit;
+                    (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+                    (*env)->DeleteLocalRef(env, jni_str_address);
+                    return CA_STATUS_FAILED;
                 }
                 deviceInfo->recvData = newBuf;
             }
@@ -817,19 +762,19 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t
 
                 // update state to disconnect
                 // the socket will be close next read thread routine
-                ca_mutex_lock(g_mutexStateList);
+                oc_mutex_lock(g_mutexStateList);
                 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
-                ca_mutex_unlock(g_mutexStateList);
+                oc_mutex_unlock(g_mutexStateList);
 
-                (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
-                (*env)->DeleteLocalRef(env, jbuf);
-                goto exit;
+                (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+                (*env)->DeleteLocalRef(env, jni_str_address);
+                return CA_STATUS_FAILED;
             }
 
             if (g_edrPacketReceivedCallback)
             {
-                OIC_LOG_V(DEBUG, TAG,"data will be sent to callback routine: \
-                          %s, %d", deviceInfo->recvData, deviceInfo->recvDataLen);
+                OIC_LOG_V(DEBUG, TAG, "data will be sent to callback routine: %s, %d",
+                          deviceInfo->recvData, deviceInfo->recvDataLen);
 
                 uint32_t sentLength = 0;
                 g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData,
@@ -841,56 +786,12 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t t
                 deviceInfo->totalDataLen = 0;
             }
         }
-        (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
-        (*env)->DeleteLocalRef(env, jbuf);
-    }
-    (*env)->DeleteLocalRef(env, jni_obj_inputStream);
-    (*env)->DeleteLocalRef(env, jni_cid_InputStream);
-    (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
-    (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
-    (*env)->DeleteLocalRef(env, jni_str_address);
-
-    return CA_STATUS_OK;
-
-exit:
-    (*env)->DeleteLocalRef(env, jni_obj_inputStream);
-    (*env)->DeleteLocalRef(env, jni_cid_InputStream);
-    (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
-    (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
-    (*env)->DeleteLocalRef(env, jni_str_address);
 
-    return CA_STATUS_FAILED;
-}
-
-jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
-{
-    if (!socket)
-    {
-        OIC_LOG(ERROR, TAG, "socket is null");
-        return JNI_FALSE;
-    }
-
-    jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
-    if (!jni_cid_BTsocket)
-    {
-        OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null");
-        return JNI_FALSE;
-    }
-
-    jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
-                                                        "()Z");
-    if (!jni_mid_isConnected)
-    {
-        OIC_LOG(ERROR, TAG, "jni_mid_isConnected is null.");
-        (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
-        return JNI_FALSE;
+        (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+        (*env)->DeleteLocalRef(env, jni_str_address);
     }
 
-    jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
-
-    (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
-
-    return jni_isConnected;
+    return CA_STATUS_OK;
 }
 
 void CANativeStartListenTask(JNIEnv *env)
@@ -902,9 +803,9 @@ void CANativeStartListenTask(JNIEnv *env)
         return;
     }
 
-    ca_mutex_lock(g_mutexServerSocket);
+    oc_mutex_lock(g_mutexServerSocket);
     g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
-    ca_mutex_unlock(g_mutexServerSocket);
+    oc_mutex_unlock(g_mutexServerSocket);
 }
 
 jobject CAEDRNativeListen(JNIEnv *env)
@@ -913,7 +814,7 @@ jobject CAEDRNativeListen(JNIEnv *env)
 
     if (!CAEDRNativeIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adpater is not enable");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
@@ -997,8 +898,6 @@ jobject CAEDRNativeListen(JNIEnv *env)
         return NULL;
     }
 
-    g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
-
     OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT");
 
     return jni_obj_BTServerSocket;
@@ -1010,23 +909,16 @@ void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
 
     if (NULL != serverSocketObject)
     {
-        jclass jni_cid_BTServerSocket = (*env)->FindClass(
-                env, "android/bluetooth/BluetoothServerSocket");
-        if (!jni_cid_BTServerSocket)
-        {
-            OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null");
-            return;
-        }
-
-        jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
-                                                       "()Landroid/bluetooth/BluetoothSocket;");
+        jmethodID jni_mid_accept = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
+                                                    "accept",
+                                                    "()Landroid/bluetooth/BluetoothSocket;");
         if (!jni_mid_accept)
         {
             OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
             return;
         }
 
-        OIC_LOG(DEBUG, TAG, "initiating accept...");
+        OIC_LOG(DEBUG, TAG, "waiting for the new connection request...");
 
         jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
                                                             jni_mid_accept);
@@ -1052,23 +944,32 @@ void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
         }
 
         const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
-        OIC_LOG_V(DEBUG, TAG, "address is %s", address);
 
-        // set socket to list
-        jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
-        ca_mutex_lock(g_mutexObjectList);
-        CAEDRNativeAddDeviceSocketToList(env, jni_socket);
-        ca_mutex_unlock(g_mutexObjectList);
-
-        OIC_LOG(DEBUG, TAG, "Accepted!!");
+        OIC_LOG_V(INFO, TAG, "accept a new connection from [%s]", address);
 
         // update state
-        ca_mutex_lock(g_mutexStateList);
+        oc_mutex_lock(g_mutexStateList);
         CAEDRUpdateDeviceState(STATE_CONNECTED, address);
-        ca_mutex_unlock(g_mutexStateList);
+        oc_mutex_unlock(g_mutexStateList);
 
         (*env)->ReleaseStringUTFChars(env, j_str_address, address);
         (*env)->DeleteLocalRef(env, j_str_address);
+
+        // set socket to list
+        jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
+        if (!jni_socket)
+        {
+            OIC_LOG(ERROR, TAG, "jni_socket is null");
+            (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
+            return;
+        }
+
+        oc_mutex_lock(g_mutexObjectList);
+        CAEDRNativeAddDeviceSocketToList(env, jni_socket);
+        oc_mutex_unlock(g_mutexObjectList);
+
+        (*env)->DeleteGlobalRef(env, jni_socket);
+        (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
     }
     else
     {
@@ -1087,21 +988,15 @@ void CAEDRNatvieCloseServerTask(JNIEnv* env)
     {
         OIC_LOG(DEBUG, TAG, "Accept Resource will be close");
 
-        jclass jni_cid_BTServerSocket = (*env)->FindClass(
-                env, "android/bluetooth/BluetoothServerSocket");
-        if (!jni_cid_BTServerSocket)
+        jmethodID jni_mid_close = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
+                                                   "close", "()V");
+        if (!jni_mid_close)
         {
-            OIC_LOG(ERROR, TAG, "jni_cid_BTServerSocket is null");
+            OIC_LOG(ERROR, TAG, "jni_mid_close is null");
             return;
         }
 
-        jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
-        if (!jni_mid_accept)
-        {
-            OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
-            return;
-        }
-        (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
+        (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_close);
         (*env)->DeleteGlobalRef(env, g_serverSocket);
         g_serverSocket = NULL;