-/******************************************************************
+/* ****************************************************************
*
* Copyright 2014 Samsung Electronics All Rights Reserved.
*
******************************************************************/
#include <stdio.h>
-#include <unistd.h>
#include <string.h>
#include <jni.h>
static JavaVM *g_jvm;
/**
- * @var g_mMutexSocketListManager
- * @brief Mutex to synchronize socket list update
+ * Mutex to synchronize socket list update.
*/
static ca_mutex g_mutexSocketListManager;
-// server socket instance
+/**
+ * server socket instance.
+ */
static jobject g_serverSocketObject = NULL;
/**
- * @var g_mutexUnicastServer
- * @brief Mutex to synchronize unicast server
+ * Mutex to synchronize unicast server.
*/
static ca_mutex g_mutexUnicastServer = NULL;
/**
- * @var g_stopUnicast
- * @brief Flag to control the Receive Unicast Data Thread
+ * Flag to control the Receive Unicast Data Thread.
*/
static bool g_stopUnicast = false;
/**
- * @var g_mutexMulticastServer
- * @brief Mutex to synchronize secure multicast server
+ * Mutex to synchronize secure multicast server.
*/
static ca_mutex g_mutexMulticastServer = NULL;
/**
- * @var g_stopMulticast
- * @brief Flag to control the Receive Multicast Data Thread
+ * Flag to control the Receive Multicast Data Thread.
*/
static bool g_stopMulticast = false;
/**
- * @var g_mutexAcceptServer
- * @brief Mutex to synchronize accept server
+ * Mutex to synchronize accept server.
*/
static ca_mutex g_mutexAcceptServer = NULL;
/**
- * @var g_stopAccept
- * @brief Flag to control the Accept Thread
+ * Flag to control the Accept Thread.
*/
static bool g_stopAccept = false;
static jobject g_inputStream = NULL;
/**
- * @var g_mutexServerSocket
- * @brief Mutex to synchronize server socket
+ * Mutex to synchronize server socket.
*/
static ca_mutex g_mutexServerSocket = NULL;
static jobject g_serverSocket = NULL;
/**
- * @var g_mutexStateList
- * @brief Mutex to synchronize device state list
+ * Mutex to synchronize device state list.
*/
static ca_mutex g_mutexStateList = NULL;
/**
- * @var g_mutexObjectList
- * @brief Mutex to synchronize device object list
+ * Mutex to synchronize device object list.
*/
static ca_mutex g_mutexObjectList = NULL;
+/**
+ * Mutex to synchronize input stream.
+ */
+static ca_mutex g_mutexInputStream = NULL;
+
typedef struct send_data
{
char* address;
} data_t;
/**
- @brief Thread context information for unicast, multicast and secured unicast server
+ * Thread context information for unicast, multicast and secured unicast server.
*/
typedef struct
{
} CAAdapterAcceptThreadContext_t;
/**
- * @var g_edrPacketReceivedCallback
- * @brief Maintains the callback to be notified when data received from remote Bluetooth device
+ * Maintains the callback to be notified when data received from remote
+ * Bluetooth device.
*/
static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
// 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();
- if (0 == length)
+ if (0 != length)
{
- OIC_LOG(DEBUG, TAG, "socket list is empty");
- sleep(1);
- }
-
- uint32_t idx;
- for (idx = 0; idx < length; idx++)
- {
- OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
- CAEDRNativeReadData(env, idx, ctx->type);
- sleep(1);
+ for (uint32_t idx = 0; idx < length; idx++)
+ {
+ OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
+ CAEDRNativeReadData(env, idx, ctx->type);
+ }
}
}
CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
- if (NULL == ctx)
- {
- OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: ctx is null");
- if (isAttached)
- {
- (*g_jvm)->DetachCurrentThread(g_jvm);
- }
- return;
- }
-
// it should be initialized for restart accept thread
ca_mutex_lock(g_mutexAcceptServer);
g_stopAccept = false;
}
/**
- * implement for adapter common method
+ * implement for adapter common method.
*/
-CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, ca_thread_pool_t handle)
+CAResult_t CAEDRServerStart(ca_thread_pool_t handle)
{
OIC_LOG(DEBUG, TAG, "IN");
CAEDRServerInitialize(handle);
return CA_STATUS_FAILED;
}
- *serverFD = 1;
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
-CAResult_t CAEDRServerStop(int serverFD)
+CAResult_t CAEDRServerStop()
{
OIC_LOG(DEBUG, TAG, "IN");
- CAEDRStopUnicastServer(-1);
- CAEDRStopMulticastServer(-1);
+ CAEDRStopUnicastServer();
+ CAEDRStopMulticastServer();
ca_mutex_lock(g_mutexAcceptServer);
g_stopAccept = true;
}
/**
- * Destroy Mutex
+ * Destroy Mutex.
*/
static void CAEDRServerDestroyMutex()
{
g_mutexObjectList = NULL;
}
+ if (g_mutexInputStream)
+ {
+ ca_mutex_free(g_mutexInputStream);
+ g_mutexInputStream = NULL;
+ }
+
OIC_LOG(DEBUG, TAG, "OUT");
}
return CA_STATUS_FAILED;
}
+ g_mutexInputStream = ca_mutex_new();
+ if (!g_mutexInputStream)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to created g_mutexInputStream.");
+
+ CAEDRServerDestroyMutex();
+ return CA_STATUS_FAILED;
+ }
+
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
return CA_STATUS_OK;
}
-CAResult_t CAEDRStartMulticastServer(bool isSecured)
+CAResult_t CAEDRStartMulticastServer()
{
OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
return CA_STATUS_OK;
}
-CAResult_t CAEDRStopUnicastServer(int32_t serverID)
+CAResult_t CAEDRStopUnicastServer()
{
OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
return CA_STATUS_OK;
}
-CAResult_t CAEDRStopMulticastServer(int32_t serverID)
+CAResult_t CAEDRStopMulticastServer()
{
OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
(*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+ (*env)->DeleteLocalRef(env, jni_str_address);
+
return CA_STATUS_FAILED;
}
jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
if (!jni_cid_BTsocket)
{
+ (*env)->DeleteLocalRef(env, jni_str_address);
+
OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
return CA_STATUS_FAILED;
}
"()Ljava/io/InputStream;");
OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
- if (!jni_obj_socket)
+ jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
+ jni_mid_getInputStream);
+ if (!jni_obj_inputStream)
{
- OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
+ (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
+ (*env)->DeleteLocalRef(env, jni_str_address);
+
+ OIC_LOG(ERROR, TAG, "[EDR] btReadData: jni_obj_inputStream is null");
return CA_STATUS_FAILED;
}
- jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
- jni_mid_getInputStream);
OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
- g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
-
jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
if (!jni_cid_InputStream)
{
+ (*env)->DeleteLocalRef(env, jni_obj_inputStream);
+ (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
+ (*env)->DeleteLocalRef(env, jni_str_address);
+
OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
return CA_STATUS_FAILED;
}
jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
- if (!jni_obj_socket)
+ ca_mutex_lock(g_mutexInputStream);
+ if (!g_inputStream)
{
- OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
- return CA_STATUS_FAILED;
+ g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
}
jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
MAX_PDU_BUFFER);
+ ca_mutex_unlock(g_mutexInputStream);
OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
if (-1 == length)
{
+ (*env)->DeleteLocalRef(env, jni_cid_InputStream);
+ (*env)->DeleteLocalRef(env, jbuf);
+ (*env)->DeleteLocalRef(env, jni_obj_inputStream);
+ (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
+ (*env)->DeleteLocalRef(env, jni_str_address);
+
OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
return CA_STATUS_FAILED;
}
CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
ca_mutex_unlock(g_mutexStateList);
(*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+
+ (*env)->DeleteLocalRef(env, jbuf);
+ (*env)->DeleteLocalRef(env, jni_cid_InputStream);
+ (*env)->DeleteLocalRef(env, jni_obj_inputStream);
+ (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
+ (*env)->DeleteLocalRef(env, jni_str_address);
+
return CA_STATUS_FAILED;
}
jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
if (NULL == buf)
{
+ (*env)->DeleteLocalRef(env, jni_cid_InputStream);
+ (*env)->DeleteLocalRef(env, jbuf);
+ (*env)->DeleteLocalRef(env, jni_obj_inputStream);
+ (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
+ (*env)->DeleteLocalRef(env, jni_str_address);
+
OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
return CA_STATUS_FAILED;
}
}
(*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
(*env)->ReleaseStringUTFChars(env, jni_str_address, address);
+
+ (*env)->DeleteLocalRef(env, jni_cid_InputStream);
+ (*env)->DeleteLocalRef(env, jbuf);
+ (*env)->DeleteLocalRef(env, jni_obj_inputStream);
+ (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
+ (*env)->DeleteLocalRef(env, jni_str_address);
}
else
{
"()Z");
if (!jni_mid_isConnected)
{
+ (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
+
OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
- jni_mid_isConnected is null.");
return JNI_FALSE;
jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
+ (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
+
return jni_isConnected;
}
jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
"getDefaultAdapter",
METHODID_OBJECTNONPARAM);
- if (!jni_cid_BTAdapter)
+ if (!jni_mid_getDefaultAdapter)
{
- OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
+ OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_getDefaultAdapter is null");
return NULL;
}
}
/**
- * InputStream & BluetoothServerSocket will be close for Terminating
+ * InputStream & BluetoothServerSocket will be close for Terminating.
*/
void CAEDRNatvieCloseServerTask(JNIEnv* env)
{
jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
(*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
(*env)->DeleteGlobalRef(env, g_inputStream);
+ g_inputStream = NULL;
}
if (g_serverSocket)
}
(*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
(*env)->DeleteGlobalRef(env, g_serverSocket);
+ g_serverSocket = NULL;
OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");
}
}
-