#define TAG PCF("OIC_CA_LE_CLIENT")
#define MICROSECS_PER_SEC 1000000
+#define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
static const char METHODID_OBJECTNONPARAM[] = "()Landroid/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 ca_thread_pool_t g_threadPoolHandle = NULL;
+
JavaVM *g_jvm;
static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
static u_arraylist_t *g_gattObjectList = NULL;
static ca_cond g_deviceDescCond = NULL;
static ca_mutex g_threadSendMutex = NULL;
+static ca_mutex g_threadWriteCharacteristicMutex = NULL;
+static ca_cond g_threadWriteCharacteristicCond = NULL;
+static bool g_isSignalSetFlag = false;
static ca_mutex g_bleReqRespClientCbMutex = NULL;
static ca_mutex g_bleServerBDAddressMutex = NULL;
// init mutex for send logic
g_threadCond = ca_cond_new();
+ g_threadWriteCharacteristicCond = ca_cond_new();
CALEClientCreateDeviceList();
CALEClientJNISetContext();
ca_cond_free(g_deviceDescCond);
ca_cond_free(g_threadCond);
+ ca_cond_free(g_threadWriteCharacteristicCond);
g_deviceDescCond = NULL;
g_threadCond = NULL;
+ g_threadWriteCharacteristicCond = NULL;
+ g_isSignalSetFlag = false;
if (isAttached)
{
if (g_sendBuffer)
{
(*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
}
jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
(*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
if (g_sendBuffer)
{
(*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
}
if (0 == u_arraylist_length(g_deviceList))
return CA_STATUS_FAILED;
}
- CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
+ CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
if (CA_STATUS_OK != ret)
{
- OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+ OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
(*env)->ReleaseStringUTFChars(env, jni_address, address);
return ret;
}
return CA_STATUS_OK;
}
-CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
+static void CALEWriteCharacteristicThread(void* object)
+{
+ VERIFY_NON_NULL(object, TAG, "object is null");
+
+ 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;
+ }
+
+ jobject gatt = (jobject)object;
+ CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
+ }
+
+ if (isAttached)
+ {
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+ }
+}
+
+CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
{
- VERIFY_NON_NULL(env, TAG, "env is null");
VERIFY_NON_NULL(gatt, TAG, "gatt is null");
+ VERIFY_NON_NULL(env, TAG, "env is null");
// send data
jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
if (CA_STATUS_OK != ret)
{
CALEClientSendFinish(env, gatt);
- return ret;
+ return CA_STATUS_FAILED;
+ }
+
+ // wait for callback for write Characteristic with success to sent data
+ OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
+ ca_mutex_lock(g_threadWriteCharacteristicMutex);
+ if (!g_isSignalSetFlag)
+ {
+ OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
+ if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
+ g_threadWriteCharacteristicMutex,
+ WAIT_TIME_WRITE_CHARACTERISTIC))
+ {
+ OIC_LOG(ERROR, TAG, "there is no response. write has failed");
+ g_isSignalSetFlag = false;
+ ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+ return CA_STATUS_FAILED;
+ }
}
+ // reset flag set by writeCharacteristic Callback
+ g_isSignalSetFlag = false;
+ ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+ OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
+{
+ OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
+ VERIFY_NON_NULL(env, TAG, "env is null");
+ VERIFY_NON_NULL(gatt, TAG, "gatt is null");
+
+ jobject gattParam = (*env)->NewGlobalRef(env, gatt);
+ if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
+ CALEWriteCharacteristicThread, (void*)gattParam))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to create read thread!");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
return CA_STATUS_OK;
}
CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
- jobject gattCharacteristic)
+ jobject gattCharacteristic)
{
OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
VERIFY_NON_NULL(env, TAG, "env is null");
gattCharacteristic);
if (ret)
{
- OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
+ OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
}
else
{
}
// notity the thread
ca_cond_signal(g_threadCond);
+
CALEClientSetSendFinishFlag(true);
OIC_LOG(DEBUG, TAG, "set signal for send data");
}
}
}
+ if (NULL == g_threadWriteCharacteristicMutex)
+ {
+ g_threadWriteCharacteristicMutex = ca_mutex_new();
+ if (NULL == g_threadWriteCharacteristicMutex)
+ {
+ OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
return CA_STATUS_OK;
}
ca_mutex_free(g_scanMutex);
g_scanMutex = NULL;
+
+ ca_mutex_free(g_threadWriteCharacteristicMutex);
+ g_threadWriteCharacteristicMutex = NULL;
}
void CALEClientSetSendFinishFlag(bool flag)
OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
}
+ ca_mutex_lock(g_threadMutex);
ca_cond_signal(g_threadCond);
+ ca_mutex_unlock(g_threadMutex);
+
+ ca_mutex_lock(g_threadWriteCharacteristicMutex);
+ ca_cond_signal(g_threadWriteCharacteristicCond);
+ ca_mutex_unlock(g_threadWriteCharacteristicMutex);
if (isAttached)
{
void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
{
- OIC_LOG(INFO, TAG, "CASetLEClientThreadPoolHandle is not support");
+ g_threadPoolHandle = handle;
}
CAResult_t CAGetLEAddress(char **local_address)
{
OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
}
+
+ if (g_sendBuffer)
+ {
+ (*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
+ }
}
return;
if (CA_STATUS_OK != res)
{
OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
- CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
- if (CA_STATUS_OK != res)
+ if (g_sendBuffer)
{
- OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
- goto error_exit;
+ CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+ 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);
+
+ // retry to write
+ CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
- }
+ OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
+ ca_mutex_lock(g_threadWriteCharacteristicMutex);
+ g_isSignalSetFlag = true;
+ ca_cond_signal(g_threadWriteCharacteristicCond);
+ ca_mutex_unlock(g_threadWriteCharacteristicMutex);
- if (g_clientErrorCallback)
- {
- jint length = (*env)->GetArrayLength(env, data);
- g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
- }
+ 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);
+ if (g_clientErrorCallback)
+ {
+ jint length = (*env)->GetArrayLength(env, data);
+ g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
+ }
+
+ CALEClientSendFinish(env, gatt);
+ goto error_exit;
+ }
}
else
{
{
OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
}
+
+ ca_mutex_lock(g_threadWriteCharacteristicMutex);
+ OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
+ g_isSignalSetFlag = true;
+ ca_cond_signal(g_threadWriteCharacteristicCond);
+ ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+
CALEClientUpdateSendCnt(env);
}
CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt);
/**
+ * call CALESetValueAndWriteCharacteristic when connection is successful.
+ * @param[in] env JNI interface pointer.
+ * @param[in] gatt Gatt profile object.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt);
+
+/**
* create GattCharacteristic and call CALEClientWriteCharacteristicImpl
* for request to write gatt characteristic.
* @param[in] env JNI interface pointer.
* @param[in] gatt Gatt profile object.
* @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
*/
-CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt);
+CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv *env, jobject gatt);
/**
* request to write gatt characteristic.
CALEClientCreateDeviceList();
CALEServerCreateCachedDeviceList();
- CAResult_t res = CALEClientStartScan();
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
- }
-
- res = CALEStartAdvertise();
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "CALEStartAdvertise has failed");
- }
-
gCALEDeviceStateChangedCallback(newStatus);
}
else if (BT_STATE_OFF == status) // STATE_OFF:10
{
+ CALEClientStopMulticastServer();
+
// remove obj for client
CAResult_t res = CALEClientRemoveAllGattObjs(env);
if (CA_STATUS_OK != res)
#define TAG PCF("OIC_CA_LE_SERVER")
+#define WAIT_TIME_WRITE_CHARACTERISTIC 10000000
+
static JavaVM *g_jvm = NULL;
static jobject g_context = NULL;
static jobject g_bluetoothGattServer = NULL;
static bool g_isStartServer = false;
static bool g_isInitializedServer = false;
+static jbyteArray g_sendBuffer = NULL;
+
static CABLEDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
static ca_mutex g_bleReqRespCbMutex = NULL;
static ca_mutex g_bleClientBDAddressMutex = NULL;
static ca_mutex g_connectedDeviceListMutex = NULL;
+static ca_mutex g_threadSendMutex = NULL;
+static ca_mutex g_threadSendNotifyMutex = NULL;
+static ca_cond g_threadSendNotifyCond = NULL;
+static bool g_isSignalSetFlag = false;
+
void CALEServerJNISetContext()
{
OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
{
- OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponseData");
+ OIC_LOG(DEBUG, TAG, "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");
return CA_SEND_FAILED;
}
- OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponseData");
+ OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
+ ca_mutex_lock(g_threadSendNotifyMutex);
+ if (!g_isSignalSetFlag)
+ {
+ OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
+ if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
+ WAIT_TIME_WRITE_CHARACTERISTIC))
+ {
+ OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
+ ca_mutex_unlock(g_threadSendNotifyMutex);
+ return CA_STATUS_FAILED;
+ }
+ }
+ // reset flag set by writeCharacteristic Callback
+ g_isSignalSetFlag = false;
+ ca_mutex_unlock(g_threadSendNotifyMutex);
+ OIC_LOG(INFO, TAG, "notifyCharacteristic success");
return CA_STATUS_OK;
}
return ret;
}
+ g_threadSendNotifyCond = ca_cond_new();
+
ret = CALEServerInitMutexVaraibles();
if (CA_STATUS_OK != ret)
{
{
OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
+ 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;
+ }
+
+ if (g_sendBuffer)
+ {
+ (*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
+ }
+
+ ca_cond_free(g_threadSendNotifyCond);
+ g_threadSendNotifyCond = NULL;
+
CALEServerTerminateMutexVaraibles();
CALEServerTerminateConditionVaraibles();
g_isInitializedServer = false;
+ if (isAttached)
+ {
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+ }
+
OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
}
return CA_STATUS_FAILED;
}
+ ca_mutex_lock(g_threadSendMutex);
+
jobject jni_obj_bluetoothDevice = NULL;
uint32_t length = u_arraylist_length(g_connectedDeviceList);
for (uint32_t index = 0; index < length; index++)
if (!jarrayObj)
{
OIC_LOG(ERROR, TAG, "jarrayObj is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
if (!jni_setAddress)
{
OIC_LOG(ERROR, TAG, "jni_setAddress is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
if (jni_obj_bluetoothDevice)
{
- jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
- (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
+ jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+ (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
+ g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
- CAResult_t res = CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
+ CAResult_t res = CALEServerSend(env, jni_obj_bluetoothDevice, g_sendBuffer);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "send has failed");
- return CA_SEND_FAILED;
+ goto error_exit;
}
}
else
{
OIC_LOG(ERROR, TAG, "There are no device to send in the list");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
+ if (g_sendBuffer)
+ {
+ (*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
+ }
+
+ ca_mutex_unlock(g_threadSendMutex);
+ OIC_LOG(INFO, TAG, "unicast - send request is successful");
return CA_STATUS_OK;
+
+error_exit:
+ if (g_sendBuffer)
+ {
+ (*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
+ }
+
+ ca_mutex_unlock(g_threadSendMutex);
+ return CA_SEND_FAILED;
}
CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
return CA_STATUS_FAILED;
}
+ ca_mutex_lock(g_threadSendMutex);
+
+ OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
+ if (g_sendBuffer)
+ {
+ (*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
+ }
+ jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+ (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
+ g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+
uint32_t length = u_arraylist_length(g_connectedDeviceList);
for (uint32_t index = 0; index < length; index++)
{
if (!jarrayObj)
{
OIC_LOG(ERROR, TAG, "jarrayObj is null");
- return CA_STATUS_FAILED;
+ continue;
}
// send data for all device
jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
(*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
+
+ jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
+ if (!jni_address)
+ {
+ OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+ continue;
+ }
+
+ const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+ if (!address)
+ {
+ OIC_LOG(ERROR, TAG, "address is not available");
+ continue;
+ }
+
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_V(ERROR, TAG, "send has failed for the device[%s]", address);
+ (*env)->ReleaseStringUTFChars(env, jni_address, address);
+ continue;
}
+
+ OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
+ (*env)->ReleaseStringUTFChars(env, jni_address, address);
}
+ if (g_sendBuffer)
+ {
+ (*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
+ }
+
+ ca_mutex_unlock(g_threadSendMutex);
return CA_STATUS_OK;
}
VERIFY_NON_NULL_VOID(obj, TAG, "obj");
VERIFY_NON_NULL_VOID(device, TAG, "device");
- OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback(%d)",
+ OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
status);
+
+ if (GATT_SUCCESS != status) // error case
+ {
+ OIC_LOG(ERROR, TAG, "it will be sent again.");
+
+ CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "send has failed");
+ ca_mutex_lock(g_threadSendNotifyMutex);
+ g_isSignalSetFlag = true;
+ ca_cond_signal(g_threadSendNotifyCond);
+ ca_mutex_unlock(g_threadSendNotifyMutex);
+ return CA_SEND_FAILED;
+ }
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "notify success");
+
+ // next data can be sent
+ ca_mutex_lock(g_threadSendNotifyMutex);
+ OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
+ g_isSignalSetFlag = true;
+ ca_cond_signal(g_threadSendNotifyCond);
+ ca_mutex_unlock(g_threadSendNotifyMutex);
+ }
+
}
JNIEXPORT void JNICALL
(*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
}
+ ca_mutex_lock(g_threadSendNotifyMutex);
+ ca_cond_signal(g_threadSendNotifyCond);
+ ca_mutex_unlock(g_threadSendNotifyMutex);
+
g_isStartServer = false;
if (isAttached)
}
}
+ 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_threadSendNotifyMutex)
+ {
+ g_threadSendNotifyMutex = ca_mutex_new();
+ if (NULL == g_threadSendNotifyMutex)
+ {
+ OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
return CA_STATUS_OK;
}
ca_mutex_free(g_connectedDeviceListMutex);
g_connectedDeviceListMutex = NULL;
+
+ ca_mutex_free(g_threadSendMutex);
+ g_threadSendMutex = NULL;
+
+ ca_mutex_free(g_threadSendNotifyMutex);
+ g_threadSendNotifyMutex = NULL;
}
void CALEServerTerminateConditionVaraibles()