#include <jni.h>
#include <unistd.h>
+#include "calestate.h"
#include "caleclient.h"
#include "caleserver.h"
#include "caleutils.h"
#include "oic_malloc.h"
#include "oic_string.h"
#include "cathreadpool.h" /* for thread pool */
-#include "camutex.h"
+#include "octhread.h"
#include "uarraylist.h"
#include "org_iotivity_ca_CaLeClientInterface.h"
-#define TAG PCF("OIC_CA_LE_CLIENT")
+//#define TAG PCF("OIC_CA_LE_CLIENT")
+#define TAG BLE_CLIENT_TAG
#define MICROSECS_PER_SEC 1000000
#define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
+#define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
+#define WAIT_TIME_SCANNED_CHECKING 30
#define GATT_CONNECTION_PRIORITY_BALANCED 0
#define GATT_FAILURE 257
#define GATT_REQUEST_NOT_SUPPORTED 6
#define GATT_WRITE_NOT_PERMITTED 3
+// samsung
+#define BLE_SCAN_API_LEVEL (100) //(21)
+#define BLE_MIN_API_LEVEL (18)
+#define HIDDEN_API
+
static ca_thread_pool_t g_threadPoolHandle = NULL;
JavaVM *g_jvm;
// it will be prevent to start send logic when adapter has stopped.
static bool g_isStartedLEClient = 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 = NULL;
-static ca_mutex g_threadMutex = NULL;
-static ca_cond g_threadCond = 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 oc_mutex g_SendFinishMutex = NULL;
+static oc_mutex g_threadMutex = NULL;
+static oc_cond g_threadCond = NULL;
+static oc_cond g_deviceDescCond = NULL;
+
+static oc_mutex g_threadSendMutex = NULL;
+static oc_mutex g_threadWriteCharacteristicMutex = NULL;
+static oc_cond g_threadWriteCharacteristicCond = NULL;
static bool g_isSignalSetFlag = false;
-static ca_mutex g_bleReqRespClientCbMutex = NULL;
-static ca_mutex g_bleServerBDAddressMutex = NULL;
+static oc_mutex g_bleReqRespClientCbMutex = NULL;
+static oc_mutex g_bleServerBDAddressMutex = NULL;
+
+static oc_mutex g_deviceListMutex = NULL;
+static oc_mutex g_gattObjectMutex = NULL;
+static oc_mutex g_deviceStateListMutex = NULL;
-static ca_mutex g_deviceListMutex = NULL;
-static ca_mutex g_gattObjectMutex = NULL;
-static ca_mutex g_deviceStateListMutex = NULL;
+static oc_mutex g_deviceScanRetryDelayMutex = NULL;
+static oc_cond g_deviceScanRetryDelayCond = NULL;
-static ca_mutex g_deviceScanRetryDelayMutex = NULL;
-static ca_cond g_deviceScanRetryDelayCond = NULL;
+static oc_mutex g_threadScanIntervalMutex = NULL;
+static oc_cond g_threadScanIntervalCond = NULL;
-static ca_mutex g_scanMutex = NULL;
-static ca_mutex g_threadSendStateMutex = NULL;
+static oc_mutex g_threadSendStateMutex = NULL;
+static oc_mutex g_setValueMutex = NULL;
+
+static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
+static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
+static int32_t g_intervalCount = 0;
+static bool g_isWorkingScanThread = false;
+static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
+static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
+static int32_t g_jniIntSdk = -1;
+static bool g_setHighQoS = true;
+static bool g_setFullScanFlag = true;
+jclass g_LEInterface = NULL;
/**
* check if retry logic for connection routine has to be stopped or not.
* in case of error value including this method, connection routine has to be stopped.
case GATT_REQUEST_NOT_SUPPORTED:
case GATT_WRITE_NOT_PERMITTED:
return true;
+ default:
+ return false;
}
- return false;
+}
+
+/**
+ * delete global reference for g_sendBuffer
+ * @param[in] env JNI interface pointer.
+ */
+static void CALEDeleteSendBuffer(JNIEnv *env)
+{
+ OIC_LOG(INFO, TAG, "CALEDeleteSendBuffer");
+ oc_mutex_lock(g_setValueMutex);
+ if (g_sendBuffer)
+ {
+ OIC_LOG(INFO, TAG, "delete send buffer");
+ (*env)->DeleteGlobalRef(env, g_sendBuffer);
+ g_sendBuffer = NULL;
+ }
+ oc_mutex_unlock(g_setValueMutex);
+}
+
+void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
+ CALEScanState_t nextScanningStep)
+{
+ OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d, next scan state will be %d",
+ g_scanIntervalTime, intervalTime, nextScanningStep);
+
+ // previous time should be stored.
+ if (0 < workingCount)
+ {
+ g_scanIntervalTimePrev = g_scanIntervalTime;
+ }
+ g_scanIntervalTime = intervalTime;
+ g_intervalCount = workingCount;
+ g_nextScanningStep = nextScanningStep;
+}
+
+void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
+ CALEScanState_t nextScanningStep)
+{
+ if (intervalTime == g_scanIntervalTime
+ && workingCount == g_intervalCount
+ && nextScanningStep == g_nextScanningStep)
+ {
+ OIC_LOG(DEBUG, TAG, "setting duplicate interval time");
+ return;
+ }
+
+ oc_mutex_lock(g_threadScanIntervalMutex);
+ CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
+ oc_cond_signal(g_threadScanIntervalCond);
+ oc_mutex_unlock(g_threadScanIntervalMutex);
+}
+
+static void CALEScanThread(void* object)
+{
+ (void)object;
+
+ bool isAttached = false;
+ JNIEnv* env = NULL;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+ if (JNI_OK != res)
+ {
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+ if (JNI_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+ return;
+ }
+ isAttached = true;
+ }
+
+ oc_mutex_lock(g_threadScanIntervalMutex);
+ while(g_isWorkingScanThread)
+ {
+ OIC_LOG(DEBUG, TAG, "scan waiting time out");
+ if (BLE_SCAN_ENABLE == g_curScanningStep)
+ {
+ //stop scan
+ CAResult_t ret = CALEClientStopScan();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
+ }
+ }
+ else if (BLE_SCAN_DISABLE == g_curScanningStep)
+ {
+ //start scan
+ CAResult_t ret = CALEClientStartScan();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
+ }
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "scan thread is started");
+ // standby scanning
+ CALEClientSetScanInterval(0, 0, BLE_SCAN_DISABLE);
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
+ if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
+ g_threadScanIntervalMutex,
+ g_scanIntervalTime * MICROSECS_PER_SEC))
+ {
+ // called signal scan thread will be terminated
+ OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
+ if (BLE_SCAN_DISABLE == g_nextScanningStep)
+ {
+ g_curScanningStep = BLE_SCAN_ENABLE;
+ }
+ else
+ {
+ g_curScanningStep = BLE_SCAN_DISABLE;
+ }
+ }
+ else
+ {
+ if (BLE_SCAN_ENABLE == g_curScanningStep)
+ {
+ if (g_intervalCount > 0)
+ {
+ if (g_intervalCount == 1)
+ {
+ OIC_LOG(DEBUG, TAG, "reset default time");
+ CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
+ }
+ g_intervalCount--;
+ OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
+ }
+ g_curScanningStep = BLE_SCAN_DISABLE;
+ }
+ else
+ {
+ g_curScanningStep = BLE_SCAN_ENABLE;
+ }
+ }
+ }
+ oc_mutex_unlock(g_threadScanIntervalMutex);
+
+ if (isAttached)
+ {
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+ }
+}
+
+CAResult_t CALEClientStartScanWithInterval()
+{
+ if (g_isWorkingScanThread)
+ {
+ OIC_LOG(DEBUG, TAG, "scan interval logic already running");
+ return CA_STATUS_OK;
+ }
+
+ // initialize scan flags
+ g_curScanningStep = BLE_SCAN_NONE;
+ g_isWorkingScanThread = true;
+ g_intervalCount = 0;
+ g_scanIntervalTime = g_scanIntervalTimePrev;
+ g_nextScanningStep = BLE_SCAN_ENABLE;
+
+ if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEScanThread, NULL, NULL))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to create read thread!");
+ g_isWorkingScanThread = false;
+ return CA_STATUS_FAILED;
+ }
+
+ return CA_STATUS_OK;
+}
+
+void CALEClientStopScanWithInterval()
+{
+ g_isWorkingScanThread = false;
+ oc_cond_signal(g_threadScanIntervalCond);
}
//getting jvm
}
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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
if (!jApplicationContext)
{
OIC_LOG(ERROR, TAG, "Could not get application context");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
goto error_exit;
}
+ g_LEInterface = (jclass)((*env)->NewGlobalRef(env, jni_LEInterface));
jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
"(Landroid/content/Context;)V");
return CA_STATUS_OK;
error_exit:
-
+ CACheckJNIException(env);
if (isAttached)
{
(*g_jvm)->DetachCurrentThread(g_jvm);
}
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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
isAttached = true;
}
- CAResult_t ret = CALECheckPlatformVersion(env, 18);
- if (CA_STATUS_OK != ret)
+ g_jniIntSdk = CALEGetBuildVersion(env);
+ if (g_jniIntSdk < BLE_MIN_API_LEVEL)
{
OIC_LOG(ERROR, TAG, "it is not supported");
{
(*g_jvm)->DetachCurrentThread(g_jvm);
}
-
- return ret;
+ return CA_STATUS_FAILED;
}
- ret = CALEClientInitGattMutexVaraibles();
+ CAResult_t ret = CALEClientInitGattMutexVaraibles();
if (CA_STATUS_OK != ret)
{
OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
return ret;
}
- g_deviceDescCond = ca_cond_new();
+ g_deviceDescCond = oc_cond_new();
// init mutex for send logic
- g_threadCond = ca_cond_new();
- g_threadWriteCharacteristicCond = ca_cond_new();
- g_deviceScanRetryDelayCond = ca_cond_new();
+ g_threadCond = oc_cond_new();
+ g_threadWriteCharacteristicCond = oc_cond_new();
+ g_deviceScanRetryDelayCond = oc_cond_new();
+ g_threadScanIntervalCond = oc_cond_new();
CALEClientCreateDeviceList();
CALEClientJNISetContext();
}
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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
isAttached = true;
}
+ // stop scan
+ CAResult_t ret = CALEClientStopScan();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
+ }
+
if (g_leScanCallback)
{
(*env)->DeleteGlobalRef(env, g_leScanCallback);
g_leGattCallback = NULL;
}
- if (g_sendBuffer)
+ if (g_LEInterface)
{
- (*env)->DeleteGlobalRef(env, g_sendBuffer);
- g_sendBuffer = NULL;
+ (*env)->DeleteGlobalRef(env, g_LEInterface);
+ g_LEInterface = NULL;
}
+ CALEDeleteSendBuffer(env);
+
if (g_uuidList)
{
(*env)->DeleteGlobalRef(env, g_uuidList);
g_uuidList = NULL;
}
- CAResult_t ret = CALEClientRemoveAllDeviceState();
+ ret = CALERemoveAllDeviceState(g_deviceStateList,
+ g_deviceStateListMutex);
if (CA_STATUS_OK != ret)
{
- OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
+ OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
}
+ oc_mutex_lock(g_deviceStateListMutex);
+ OICFree(g_deviceStateList);
+ g_deviceStateList = NULL;
+ oc_mutex_unlock(g_deviceStateListMutex);
+
ret = CALEClientRemoveAllScanDevices(env);
if (CA_STATUS_OK != ret)
{
OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
}
- CALEClientSetScanFlag(false);
CALEClientSetSendFinishFlag(true);
CALEClientTerminateGattMutexVariables();
CALEClientDestroyJniInterface();
- ca_cond_free(g_deviceDescCond);
- ca_cond_free(g_threadCond);
- ca_cond_free(g_threadWriteCharacteristicCond);
- ca_cond_free(g_deviceScanRetryDelayCond);
+ oc_cond_free(g_deviceDescCond);
+ oc_cond_free(g_threadCond);
+ oc_cond_free(g_threadWriteCharacteristicCond);
+ oc_cond_free(g_deviceScanRetryDelayCond);
+ oc_cond_free(g_threadScanIntervalCond);
g_deviceDescCond = NULL;
g_threadCond = NULL;
g_threadWriteCharacteristicCond = NULL;
g_deviceScanRetryDelayCond = NULL;
+ g_threadScanIntervalCond = NULL;
g_isSignalSetFlag = false;
+ // stop scanning
+ CALEClientStopScanWithInterval();
+
+ if (isAttached)
+ {
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+ }
+}
+
+jobject CALEClientHiddenConnectGatt(jobject btDevice, const char* address, jboolean autoconnect)
+{
+ OIC_LOG(INFO, TAG, "IN - CALEClientHiddenConnectGatt");
+
+ if (!g_jvm)
+ {
+ OIC_LOG(ERROR, TAG, "g_jvm is null");
+ return NULL;
+ }
+
+ bool isAttached = false;
+ JNIEnv* env = NULL;
+ jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+ if (JNI_OK != res)
+ {
+ res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+ if (JNI_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+ return NULL;
+ }
+ isAttached = true;
+ }
+
+ jstring jni_address = (*env)->NewStringUTF(env, address);
+ jmethodID jni_connectGattHiddenMethod = (*env)->GetStaticMethodID(env, g_LEInterface,
+ "connectGattforHidden",
+ "(Landroid/bluetooth/BluetoothDevice;"
+ "Ljava/lang/String;Z)"
+ "Landroid/bluetooth/BluetoothGatt;");
+ if (!jni_connectGattHiddenMethod)
+ {
+ OIC_LOG(ERROR, TAG, "Could not get jni_connectGatt Hidden Method");
+ goto error_exit;
+ }
+
+ jobject gatt = (*env)->CallStaticObjectMethod(env, g_LEInterface,
+ jni_connectGattHiddenMethod,
+ btDevice, jni_address, autoconnect);
+
+ if (CACheckJNIException(env))
+ {
+ OIC_LOG(ERROR, TAG, "connectGattforHidden has failed");
+ goto detach_thread;
+ }
+
+ OIC_LOG(INFO, TAG, "OUT - CALEClientHiddenConnectGatt");
+
+ if (isAttached)
+ {
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+ }
+
+ return gatt;
+
+error_exit:
+ CACheckJNIException(env);
+
+detach_thread:
if (isAttached)
{
(*g_jvm)->DetachCurrentThread(g_jvm);
}
+
+ return NULL;
}
CAResult_t CALEClientDestroyJniInterface()
}
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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
(*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
- if ((*env)->ExceptionCheck(env))
+ if (CACheckJNIException(env))
{
OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
- goto error_exit;
+ goto detach_thread;
}
OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
return CA_STATUS_OK;
error_exit:
+ CACheckJNIException(env);
+detach_thread:
if (isAttached)
{
(*g_jvm)->DetachCurrentThread(g_jvm);
CALEClientUpdateSendCnt(env);
}
+CAResult_t CALEClientSendNegotiationMessage(const char* address)
+{
+ VERIFY_NON_NULL(address, TAG, "address is null");
+
+ return CALEClientSendUnicastMessageImpl(address, NULL, 0);
+}
+
CAResult_t CALEClientSendUnicastMessage(const char* address,
const uint8_t* data,
const uint32_t dataLen)
{
- OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
VERIFY_NON_NULL(address, TAG, "address is null");
VERIFY_NON_NULL(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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
CAResult_t CALEClientStartUnicastServer(const char* address)
{
+#ifndef TB_LOG
+ (void)address;
+#endif
OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
return CA_NOT_SUPPORTED;
if (!g_deviceList)
{
+ OIC_LOG(ERROR, TAG, "g_deviceList is not available");
return CA_STATUS_FAILED;
}
static uint64_t const TIMEOUT =
2 * MICROSECS_PER_SEC; // Microseconds
+ // set scan interval and start scan
+ CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
+
bool devicesDiscovered = false;
for (size_t i = 0; i < RETRIES; ++i)
{
OIC_LOG(DEBUG, TAG, "waiting for target device");
- if (ca_cond_wait_for(g_deviceDescCond,
+ if (oc_cond_wait_for(g_deviceDescCond,
g_threadSendMutex,
- TIMEOUT) == CA_WAIT_SUCCESS)
+ TIMEOUT) == OC_WAIT_SUCCESS)
{
- ca_mutex_lock(g_deviceListMutex);
+ OIC_LOG(DEBUG, TAG, "time out");
+ oc_mutex_lock(g_deviceListMutex);
size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
if (0 < scannedDeviceLen)
{
{
OIC_LOG(INFO, TAG, "waiting..");
- ca_mutex_lock(g_deviceScanRetryDelayMutex);
- if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
+ oc_mutex_lock(g_deviceScanRetryDelayMutex);
+ if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
g_deviceScanRetryDelayMutex,
- MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
+ MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
{
OIC_LOG(INFO, TAG, "finish to waiting for target device");
- ca_mutex_unlock(g_deviceScanRetryDelayMutex);
+ oc_mutex_unlock(g_deviceScanRetryDelayMutex);
break;
}
- ca_mutex_unlock(g_deviceScanRetryDelayMutex);
+ oc_mutex_unlock(g_deviceScanRetryDelayMutex);
// time out
// checking whether a target device is found while waiting for time-out.
}
}
+ // reset scan interval time after checking scanned devices
+ CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
+
// time out for scanning devices
if (!devicesDiscovered)
{
return CA_STATUS_FAILED;
}
}
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
+ }
return CA_STATUS_OK;
}
CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
- const uint32_t dataLen)
+ const uint32_t dataLen)
{
- OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
+ OIC_LOG_V(INFO, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
data);
VERIFY_NON_NULL(address, TAG, "address is null");
- VERIFY_NON_NULL(data, TAG, "data is null");
if (!g_jvm)
{
}
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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
{
isAttached = true;
}
- ca_mutex_lock(g_threadSendMutex);
+ oc_mutex_lock(g_threadSendMutex);
CALEClientSetSendFinishFlag(false);
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
+ CACheckJNIException(env);
goto error_exit;
}
- OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
-
- if (!strcmp(setAddress, address))
+ if (!strcasecmp(setAddress, address))
{
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
- // connect to gatt server
- ret = CALEClientStopScan();
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
- goto error_exit;
- }
+ CALEDeleteSendBuffer(env);
- if (g_sendBuffer)
+ if (data && dataLen > 0)
{
- (*env)->DeleteGlobalRef(env, g_sendBuffer);
- g_sendBuffer = NULL;
+ jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+ CACheckJNIException(env);
+ (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
+ CACheckJNIException(env);
+ g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+ CACheckJNIException(env);
}
- jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
- (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
- g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
// Target device to send message is just one.
g_targetCnt = 1;
break;
}
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
}
}
// wait for finish to send data through "CALeGattServicesDiscoveredCallback"
// if there is no connection state.
- ca_mutex_lock(g_threadMutex);
+ oc_mutex_lock(g_threadMutex);
if (!g_isFinishedSendData)
{
OIC_LOG(DEBUG, TAG, "waiting send finish signal");
- ca_cond_wait(g_threadCond, g_threadMutex);
- OIC_LOG(DEBUG, TAG, "the data was sent");
+ oc_cond_wait(g_threadCond, g_threadMutex);
+ OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
}
- ca_mutex_unlock(g_threadMutex);
+ oc_mutex_unlock(g_threadMutex);
if (isAttached)
{
(*g_jvm)->DetachCurrentThread(g_jvm);
}
- // start LE Scan again
- ret = CALEClientStartScan();
- if (CA_STATUS_OK != ret)
+ oc_mutex_unlock(g_threadSendMutex);
+ OIC_LOG(INFO, TAG, "unicast - send logic has finished");
+ if (CALEIsValidState(address, CA_LE_SEND_STATE,
+ STATE_SEND_SUCCESS,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
- OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
- ca_mutex_unlock(g_threadSendMutex);
- return ret;
+ OIC_LOG(INFO, TAG, "send success");
+ ret = CA_STATUS_OK;
}
-
- ca_mutex_unlock(g_threadSendMutex);
- OIC_LOG(INFO, TAG, "unicast - send logic has finished");
- if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
- STATE_SEND_SUCCESS))
+ else if (CALEIsValidState(address, CA_LE_SEND_STATE,
+ STATE_SEND_MTU_NEGO_SUCCESS,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
+ OIC_LOG(INFO, TAG, "mtu nego success");
ret = CA_STATUS_OK;
}
else
{
+ OIC_LOG(ERROR, TAG, "send failure");
ret = CA_SEND_FAILED;
}
// reset send state
- ret = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
- STATE_SEND_NONE);
- if (CA_STATUS_OK != ret)
+ CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+ STATE_SEND_NONE,
+ g_deviceStateList,
+ g_deviceStateListMutex);
+ if (CA_STATUS_OK != resetRet)
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+ OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
+ ret = CA_SEND_FAILED;
}
return ret;
// error label.
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);
- if (isAttached)
- {
- (*g_jvm)->DetachCurrentThread(g_jvm);
- }
- return ret;
- }
-
if (isAttached)
{
(*g_jvm)->DetachCurrentThread(g_jvm);
}
- ca_mutex_unlock(g_threadSendMutex);
+ oc_mutex_unlock(g_threadSendMutex);
return CA_SEND_FAILED;
}
return CA_STATUS_FAILED;
}
- ca_mutex_lock(g_threadSendMutex);
+ oc_mutex_lock(g_threadSendMutex);
CALEClientSetSendFinishFlag(false);
OIC_LOG(DEBUG, TAG, "set byteArray for data");
- if (g_sendBuffer)
- {
- (*env)->DeleteGlobalRef(env, g_sendBuffer);
- g_sendBuffer = NULL;
- }
+ CALEDeleteSendBuffer(env);
CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
if (CA_STATUS_OK != res)
goto error_exit;
}
- // connect to gatt server
- res = CALEClientStopScan();
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
- ca_mutex_unlock(g_threadSendMutex);
- return res;
- }
uint32_t length = u_arraylist_length(g_deviceList);
g_targetCnt = length;
{
OIC_LOG(ERROR, TAG, "BT device - send has failed");
}
-
- 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;
- }
-
- (*env)->ReleaseStringUTFChars(env, jni_address, address);
}
OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
// wait for finish to send data through "CALeGattServicesDiscoveredCallback"
- ca_mutex_lock(g_threadMutex);
+ oc_mutex_lock(g_threadMutex);
if (!g_isFinishedSendData)
{
OIC_LOG(DEBUG, TAG, "waiting send finish signal");
- ca_cond_wait(g_threadCond, g_threadMutex);
- OIC_LOG(DEBUG, TAG, "the data was sent");
- }
- ca_mutex_unlock(g_threadMutex);
-
- // start LE Scan again
- res = CALEClientStartScan();
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
- ca_mutex_unlock(g_threadSendMutex);
- return res;
+ oc_cond_wait(g_threadCond, g_threadMutex);
+ OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
}
-
- ca_mutex_unlock(g_threadSendMutex);
+ oc_mutex_unlock(g_threadMutex);
+ oc_mutex_unlock(g_threadSendMutex);
OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
return CA_STATUS_OK;
error_exit:
- res = CALEClientStartScan();
- if (CA_STATUS_OK != res)
- {
- 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");
+ oc_mutex_unlock(g_threadSendMutex);
+ OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
return CA_SEND_FAILED;
}
if (!address)
{
OIC_LOG(ERROR, TAG, "address is not available");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
- ca_mutex_lock(g_deviceStateListMutex);
- state = CALEClientGetStateInfo(address);
- ca_mutex_unlock(g_deviceStateListMutex);
+ oc_mutex_lock(g_deviceStateListMutex);
+ state = CALEGetStateInfo(address, g_deviceStateList);
+ oc_mutex_unlock(g_deviceStateListMutex);
+ }
+
+ // Since disconnect event can be caused from BT stack while connection step is running.
+ // DeviceState has to have current status for processing send failure.
+ OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
+ CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
+ CA_LE_SEND_STATE,
+ STATE_SEND_PREPARING);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
+ if (address)
+ {
+ (*env)->ReleaseStringUTFChars(env, jni_address, address);
+ }
+ return CA_STATUS_FAILED;
}
if (!state)
}
else
{
- if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
- STATE_SERVICE_CONNECTED))
+ if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+ STATE_SERVICE_CONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
OIC_LOG(INFO, TAG, "GATT has already connected");
}
(*env)->ReleaseStringUTFChars(env, jni_address, address);
}
- else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
- STATE_CONNECTED))
+ else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+ STATE_CONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
OIC_LOG(INFO, TAG, "service connecting...");
}
- else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
- STATE_DISCONNECTED))
+ else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+ STATE_DISCONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
OIC_LOG(DEBUG, TAG, "start to connect LE");
jobject gatt = CALEClientConnect(env, device,
- CALEClientGetFlagFromState(env, jni_address,
- CA_LE_AUTO_CONNECT_FLAG));
+ CALEGetFlagFromState(env, jni_address,
+ CA_LE_AUTO_CONNECT_FLAG,
+ g_deviceStateList,
+ g_deviceStateListMutex));
+
if (NULL == gatt)
{
OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
if (!jni_obj_device)
{
OIC_LOG(ERROR, TAG, "jni_obj_device is null");
+ CACheckJNIException(env);
return NULL;
}
if (!jni_address)
{
OIC_LOG(ERROR, TAG, "jni_address is null");
+ CACheckJNIException(env);
return NULL;
}
OIC_LOG(DEBUG, TAG, "request to close GATT");
(*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
- if ((*env)->ExceptionCheck(env))
+ if (CACheckJNIException(env))
{
OIC_LOG(ERROR, TAG, "closeGATT has failed");
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
return CA_STATUS_FAILED;
}
return CA_STATUS_FAILED;
}
- if (g_isStartedScan)
- {
- OIC_LOG(INFO, TAG, "scanning is already started");
- return CA_STATUS_OK;
- }
-
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(INFO, TAG, "Could not get JNIEnv pointer");
-
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
{
// scan gatt server with UUID
if (g_leScanCallback && g_uuidList)
{
-#ifdef UUID_SCAN
- ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
-#else
- ret = CALEClientStartScanImpl(env, g_leScanCallback);
-#endif
- if (CA_STATUS_OK != ret)
+ if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
{
- if (CA_ADAPTER_NOT_ENABLED == ret)
+ if (!g_setFullScanFlag)
{
- OIC_LOG(DEBUG, TAG, "Adapter is disabled");
+ //new uuid scan with callback
+ ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
}
else
{
- OIC_LOG(ERROR, TAG, "start scan has failed");
+ //new full scan with callback
+ ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
}
}
- }
-
- if (isAttached)
- {
- (*g_jvm)->DetachCurrentThread(g_jvm);
- }
+ else
+ {
+ if (!g_setFullScanFlag)
+ {
+ ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
+ }
+ else
+ {
+ ret = CALEClientStartScanImpl(env, g_leScanCallback);
+ }
+ }
+
+ if (CA_STATUS_OK != ret)
+ {
+ if (CA_ADAPTER_NOT_ENABLED == ret)
+ {
+ OIC_LOG(DEBUG, TAG, "Adapter is disabled");
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "start scan has failed");
+ }
+ }
+ }
+
+ if (isAttached)
+ {
+ (*g_jvm)->DetachCurrentThread(g_jvm);
+ }
return ret;
}
CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
{
+ OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl IN");
VERIFY_NON_NULL(callback, TAG, "callback is null");
VERIFY_NON_NULL(env, TAG, "env is null");
if (!jni_cid_BTAdapter)
{
OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
if (!jni_mid_getDefaultAdapter)
{
OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
if (!jni_mid_startLeScan)
{
OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
if (!jni_obj_BTAdapter)
{
OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
if (!jni_obj_startLeScan)
{
OIC_LOG(INFO, TAG, "startLeScan has failed");
+ CACheckJNIException(env);
}
else
{
OIC_LOG(DEBUG, TAG, "LeScan has started");
- CALEClientSetScanFlag(true);
}
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
return CA_STATUS_OK;
}
+CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback)
+{
+ OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 IN");
+ VERIFY_NON_NULL(callback, TAG, "callback is null");
+ VERIFY_NON_NULL(env, TAG, "env is null");
+
+ if (!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ CAResult_t res = CA_STATUS_FAILED;
+ // get default bt adapter class
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+ if (!jni_cid_BTAdapter)
+ {
+ OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+ CACheckJNIException(env);
+ 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");
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ 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");
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ return CA_STATUS_FAILED;
+ }
+
+ // get bluetoothLeScanner class
+ jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
+ if (!jni_cid_leScanner)
+ {
+ OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+ return CA_STATUS_FAILED;
+ }
+
+ // get remote bt adapter method
+ jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+ "getBluetoothLeScanner",
+ "()Landroid/bluetooth/"
+ "le/BluetoothLeScanner;");
+ if (!jni_mid_getBluetoothLeScanner)
+ {
+ OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
+ CACheckJNIException(env);
+ goto error_exit;
+ }
+
+ // get startScan(ScanCallback callback) method
+ jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner, "startScan",
+ "(Landroid/bluetooth/le/ScanCallback;)V");
+ if (!jni_mid_startScan)
+ {
+ OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
+ CACheckJNIException(env);
+ goto error_exit;
+ }
+
+ // gat le scanner object
+ jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+ jni_mid_getBluetoothLeScanner);
+ if (!jni_obj_leScanner)
+ {
+ OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
+ CACheckJNIException(env);
+ goto error_exit;
+ }
+
+ // call startScan method
+ OIC_LOG(INFO, TAG, "CALL API - startScan(for level21)");
+ (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, callback);
+ if (CACheckJNIException(env))
+ {
+ OIC_LOG(INFO, TAG, "startScan has failed");
+ (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+ goto error_exit;
+ }
+ res = CA_STATUS_OK;
+ (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+
+error_exit:
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+ return res;
+}
+
CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
{
+ OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl IN");
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 (!jni_cid_BTAdapter)
{
OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
if (!jni_mid_getDefaultAdapter)
{
OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
if (!jni_mid_startLeScan)
{
OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
if (!jni_obj_BTAdapter)
{
OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
if (!jni_obj_startLeScan)
{
OIC_LOG(INFO, TAG, "startLeScan has failed");
+ CACheckJNIException(env);
}
else
{
OIC_LOG(DEBUG, TAG, "LeScan has started");
- CALEClientSetScanFlag(true);
}
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
return CA_STATUS_OK;
}
+CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids, jobject callback)
+{
+ OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 IN");
+ 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(INFO, TAG, "BT adapter is not enabled");
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ // get bluetoothLeScanner class
+ jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
+ if (!jni_cid_leScanner)
+ {
+ OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
+ CACheckJNIException(env);
+ return CA_STATUS_FAILED;
+ }
+
+ // get startScan(with UUID) method
+ jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner,
+ "startScan",
+ "(Ljava/util/List;"
+ "Landroid/bluetooth/le/ScanSettings;"
+ "Landroid/bluetooth/le/ScanCallback;"
+ ")V");
+ if (!jni_mid_startScan)
+ {
+ OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+
+ // get scanfilter.Builder class id
+ jclass jni_cid_scanfilterBuilder = (*env)->FindClass(env,
+ "android/bluetooth/le/"
+ "ScanFilter$Builder");
+ if (!jni_cid_scanfilterBuilder)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilder is null");
+ CACheckJNIException(env);
+ return CA_STATUS_FAILED;
+ }
+
+ // get scanfilter.Builder(ctor) method id
+ jmethodID jni_mid_scanfilterBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
+ "<init>", "()V");
+ if (!jni_mid_scanfilterBuilderCtor)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilderCtor is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ // call scanfilter.Builder()
+ jobject jni_obj_scanfilterBuilder = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
+ jni_mid_scanfilterBuilderCtor);
+ if (!jni_obj_scanfilterBuilder)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ // get scanfilter.Builder.setServiceUuid method id
+ jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
+ "setServiceUuid",
+ "(Landroid/os/ParcelUuid;)Landroid/"
+ "bluetooth/le/ScanFilter$Builder;");
+ if (!jni_mid_setServiceUuid)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setServiceUuid is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ // get scanfilter.Builder.build method id
+ jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
+ jni_cid_scanfilterBuilder,
+ "build",
+ "()Landroid/bluetooth/le/"
+ "ScanFilter;");
+ if (!jni_mid_build_scanfilterBuilder)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_build_scanfilterBuilder is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+
+ // call ParcelUuid.fromSting(uuid)
+ jobject jni_obj_parcelUuid = CALEGetParcelUuidFromString(env, OIC_GATT_SERVICE_UUID);
+ if (!jni_obj_parcelUuid)
+ {
+ OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ // call setServiceUuid(uuid)
+ jobject jni_obj_setServiceUuid = (*env)->CallObjectMethod(env,
+ jni_obj_scanfilterBuilder,
+ jni_mid_setServiceUuid,
+ jni_obj_parcelUuid);
+ if (!jni_obj_setServiceUuid)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+ (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
+ (*env)->DeleteLocalRef(env, jni_obj_setServiceUuid);
+
+ // call build()
+ jobject jni_obj_scanfilter = (*env)->CallObjectMethod(env,
+ jni_obj_scanfilterBuilder,
+ jni_mid_build_scanfilterBuilder);
+ if (!jni_obj_scanfilter)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+
+ // get scanSettings.Builder class id
+ jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
+ "android/bluetooth/le/"
+ "ScanSettings$Builder");
+ if (!jni_cid_scanSettingsBuilder)
+ {
+ OIC_LOG(ERROR, TAG, "scanSettings: jni_cid_scanSettingsBuilder is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ return CA_STATUS_FAILED;
+ }
+
+ // get scanSettings.Builder(ctor) method id
+ jmethodID jni_mid_scanSettingsBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
+ "<init>", "()V");
+ if (!jni_mid_scanSettingsBuilderCtor)
+ {
+ OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_scanSettingsBuilderCtor is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ // get scanSettings.Builder.setScanMode method id
+ jmethodID jni_mid_setScanMode = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
+ "setScanMode",
+ "(I)Landroid/"
+ "bluetooth/le/ScanSettings$Builder;");
+ if (!jni_mid_setScanMode)
+ {
+ OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_setScanMode is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ // get scanSettings.Builder.build method id
+ jmethodID jni_mid_build_scanSettings = (*env)->GetMethodID(env,
+ jni_cid_scanSettingsBuilder,
+ "build",
+ "()Landroid/bluetooth/le/"
+ "ScanSettings;");
+ if (!jni_mid_build_scanSettings)
+ {
+ OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_build_scanSettings is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ // call scanSettings.Builder()
+ jobject jni_obj_scanSettingBuilder = (*env)->NewObject(env, jni_cid_scanSettingsBuilder,
+ jni_mid_scanSettingsBuilderCtor);
+ if (!jni_obj_scanSettingBuilder)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettingBuilder is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+
+ jclass jni_cid_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
+ if (!jni_cid_arrayList)
+ {
+ OIC_LOG(ERROR, TAG, "ArrayList: jni_cid_arrayList is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ jmethodID jni_mid_arrayListCtor = (*env)->GetMethodID(env, jni_cid_arrayList, "<init>", "()V");
+ if (!jni_mid_arrayListCtor)
+ {
+ OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListCtor is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_cid_arrayList);
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ jmethodID jni_mid_arrayListAdd = (*env)->GetMethodID(env, jni_cid_arrayList,
+ "add", "(Ljava/lang/Object;)Z");
+ if (!jni_mid_arrayListAdd)
+ {
+ OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListAdd is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_cid_arrayList);
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+ return CA_STATUS_FAILED;
+ }
+
+ jobject jni_obj_filterList = (*env)->NewObject(env, jni_cid_arrayList, jni_mid_arrayListCtor);
+ if (!jni_obj_filterList)
+ {
+ OIC_LOG(ERROR, TAG, "ArrayList: jni_obj_filterList is null");
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_cid_arrayList);
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_cid_arrayList);
+
+ jboolean jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
+ jni_mid_arrayListAdd,
+ jni_obj_scanfilter);
+ if (!jni_bool_arrayListIsAdded)
+ {
+ OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
+ (*env)->DeleteLocalRef(env, jni_obj_filterList);
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+
+ // get ScanSettings.SCAN_MODE_BALANCED jint value
+ jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
+ "SCAN_MODE_BALANCED");
+ CACheckJNIException(env);
+
+ // call setScanMode(SCAN_MODE_BALANCED)
+ jobject jni_obj_setScanMode = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
+ jni_mid_setScanMode,
+ jni_int_scanBalancedMode);
+ if (!jni_obj_setScanMode)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setScanMode is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+ (*env)->DeleteLocalRef(env, jni_obj_filterList);
+ return CA_STATUS_FAILED;
+ }
+
+ // call build
+ jobject jni_obj_scanSettings = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
+ jni_mid_build_scanSettings);
+ if (!jni_obj_scanSettings)
+ {
+ OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettings is null");
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+ (*env)->DeleteLocalRef(env, jni_obj_filterList);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+
+ CAResult_t res = CA_STATUS_FAILED;
+ // get default bt adapter class
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+ if (!jni_cid_BTAdapter)
+ {
+ OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+ CACheckJNIException(env);
+ goto error_exit;
+ }
+
+ 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");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ goto error_exit;
+ }
+
+ 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");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ goto error_exit;
+ }
+
+ // get remote bt adapter method
+ jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+ "getBluetoothLeScanner",
+ "()Landroid/bluetooth/"
+ "le/BluetoothLeScanner;");
+ if (!jni_mid_getBluetoothLeScanner)
+ {
+ OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+ goto error_exit;
+ }
+
+ // get le scanner object
+ jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+ jni_mid_getBluetoothLeScanner);
+ if (!jni_obj_leScanner)
+ {
+ OIC_LOG(ERROR, TAG, "jni_obj_leScanner is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+ goto error_exit;
+ }
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+
+ // call startScan method
+ OIC_LOG(INFO, TAG, "CALL API - startScanWithUUID(for level 21)");
+ (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, jni_obj_filterList,
+ jni_obj_scanSettings, callback);
+ if (CACheckJNIException(env))
+ {
+ OIC_LOG(INFO, TAG, "startScan has failed");
+ }
+ else
+ {
+ res = CA_STATUS_OK;
+ }
+ (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+
+error_exit:
+ (*env)->DeleteLocalRef(env, jni_obj_scanSettings);
+ (*env)->DeleteLocalRef(env, jni_obj_filterList);
+ return res;
+}
+
jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
{
VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
if (!jni_cid_uuid)
{
OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
- return NULL;
+ goto error_exit;
}
jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
if (!jni_mid_fromString)
{
OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
- return NULL;
+ goto error_exit;
}
jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
+ CACheckJNIException(env);
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;
+ goto error_exit;
}
return jni_obj_uuid;
+
+error_exit:
+ CACheckJNIException(env);
+ return NULL;
}
CAResult_t CALEClientStopScan()
return CA_STATUS_FAILED;
}
- if (!g_isStartedScan)
- {
- OIC_LOG(INFO, TAG, "scanning is already stopped");
- return CA_STATUS_OK;
- }
-
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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
{
isAttached = true;
}
- CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
+ CAResult_t ret = CA_STATUS_FAILED;
+
+ if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
+ {
+ ret = CALEClientStopScanImplForV21(env, g_leScanCallback);
+ }
+ else
+ {
+ ret = CALEClientStopScanImpl(env, g_leScanCallback);
+ }
+
if (CA_STATUS_OK != ret)
{
if (CA_ADAPTER_NOT_ENABLED == ret)
OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
}
}
- else
- {
- CALEClientSetScanFlag(false);
- }
if (isAttached)
{
return ret;
}
-void CALEClientSetScanFlag(bool flag)
-{
- ca_mutex_lock(g_scanMutex);
- g_isStartedScan = flag;
- ca_mutex_unlock(g_scanMutex);
-}
-
CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
{
- OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
+ OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl IN");
VERIFY_NON_NULL(callback, TAG, "callback is null");
VERIFY_NON_NULL(env, TAG, "env is null");
if (!jni_cid_BTAdapter)
{
OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
if (!jni_mid_getDefaultAdapter)
{
OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
if (!jni_mid_stopLeScan)
{
OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
- // gat bt adapter object
+ // 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, "jni_obj_BTAdapter is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
return CA_STATUS_FAILED;
}
OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
// call start le scan method
(*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
- if ((*env)->ExceptionCheck(env))
+ if (CACheckJNIException(env))
{
OIC_LOG(ERROR, TAG, "stopLeScan has failed");
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
return CA_STATUS_FAILED;
}
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
return CA_STATUS_OK;
}
-CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
+CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback)
{
- OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
- VERIFY_NON_NULL(env, TAG, "env");
- VERIFY_NON_NULL(jni_address, TAG, "jni_address");
+ OIC_LOG(DEBUG, TAG, "CALEClientStopScanImplForV21 IN");
+ VERIFY_NON_NULL(callback, TAG, "callback is null");
+ VERIFY_NON_NULL(env, TAG, "env is null");
- ca_mutex_lock(g_deviceStateListMutex);
+ if (!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+ return CA_ADAPTER_NOT_ENABLED;
+ }
- char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
- if (!address)
+ // get default bt adapter class
+ jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+ if (!jni_cid_BTAdapter)
{
- OIC_LOG(ERROR, TAG, "address is not available");
+ OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
- if (CALEClientIsDeviceInList(address))
+ jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+ "getDefaultAdapter",
+ "()Landroid/bluetooth/"
+ "BluetoothAdapter;");
+ if (!jni_mid_getDefaultAdapter)
{
- CALEState_t* curState = CALEClientGetStateInfo(address);
- if(!curState)
- {
- OIC_LOG(ERROR, TAG, "curState is null");
- (*env)->ReleaseStringUTFChars(env, jni_address, address);
- ca_mutex_unlock(g_deviceStateListMutex);
- return CA_STATUS_FAILED;
- }
- OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
+ OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ return CA_STATUS_FAILED;
+ }
- switch(state_idx)
- {
- case CA_LE_AUTO_CONNECT_FLAG:
- curState->autoConnectFlag = flag;
- break;
- case CA_LE_DESCRIPTOR_FOUND:
- curState->isDescriptorFound = flag;
- break;
- default:
- break;
- }
+ 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");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ return CA_STATUS_FAILED;
}
- (*env)->ReleaseStringUTFChars(env, jni_address, address);
- ca_mutex_unlock(g_deviceStateListMutex);
- OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
+ // get bluetoothLeScanner class
+ jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
+ if (!jni_cid_leScanner)
+ {
+ OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+ return CA_STATUS_FAILED;
+ }
+
+ // get remote bt adapter method
+ jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+ "getBluetoothLeScanner",
+ "()Landroid/bluetooth/"
+ "le/BluetoothLeScanner;");
+ if (!jni_mid_getBluetoothLeScanner)
+ {
+ OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+
+ // get stopScan(ScanCallback callback) method
+ jmethodID jni_mid_stopScan = (*env)->GetMethodID(env, jni_cid_leScanner, "stopScan",
+ "(Landroid/bluetooth/le/ScanCallback;)V");
+ if (!jni_mid_stopScan)
+ {
+ OIC_LOG(ERROR, TAG, "stopScan: jni_mid_stopScan is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+ (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+ return CA_STATUS_FAILED;
+ }
+ (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+
+ // gat le scanner object
+ jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+ jni_mid_getBluetoothLeScanner);
+ if (!jni_obj_leScanner)
+ {
+ OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
+ CACheckJNIException(env);
+ return CA_STATUS_FAILED;
+ }
+
+ // call stopScan method
+ OIC_LOG(INFO, TAG, "CALL API - stopScan for level 21");
+ (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_stopScan, callback);
+ if (CACheckJNIException(env))
+ {
+ OIC_LOG(INFO, TAG, "stopScan for level 21 has failed");
+ (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+ return CA_STATUS_FAILED;
+ }
+
+ (*env)->DeleteLocalRef(env, jni_obj_leScanner);
return CA_STATUS_OK;
}
-jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
+CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
{
- OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
- VERIFY_NON_NULL_RET(env, TAG, "env", false);
- VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
+ OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
+ VERIFY_NON_NULL(env, TAG, "env is null");
+ VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
- ca_mutex_lock(g_deviceStateListMutex);
+ oc_mutex_lock(g_threadSendMutex);
- char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
- if (!address)
+ jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
+ if (!jni_address)
{
- OIC_LOG(ERROR, TAG, "address is not available");
- ca_mutex_unlock(g_deviceStateListMutex);
- return JNI_FALSE;
+ OIC_LOG(ERROR, TAG, "jni_address is not available");
+ oc_mutex_unlock(g_threadSendMutex);
+ return CA_STATUS_FAILED;
}
- CALEState_t* curState = CALEClientGetStateInfo(address);
- (*env)->ReleaseStringUTFChars(env, jni_address, address);
- if(!curState)
+ const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+ if (!address)
{
- OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
- ca_mutex_unlock(g_deviceStateListMutex);
- return JNI_FALSE;
+ OIC_LOG(ERROR, TAG, "address is not available");
+ CACheckJNIException(env);
+ oc_mutex_unlock(g_threadSendMutex);
+ return CA_STATUS_FAILED;
}
- jboolean ret = JNI_FALSE;
- switch(state_idx)
+ CAResult_t res = CA_STATUS_OK;
+ if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+ STATE_DISCONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
- case CA_LE_AUTO_CONNECT_FLAG:
- ret = curState->autoConnectFlag;
- break;
- case CA_LE_DESCRIPTOR_FOUND:
- ret = curState->isDescriptorFound;
- break;
- default:
- break;
+ jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
+ if (NULL == newGatt)
+ {
+ OIC_LOG(INFO, TAG, "newGatt is not available");
+ res = CA_STATUS_FAILED;
+ }
}
- ca_mutex_unlock(g_deviceStateListMutex);
+ oc_mutex_unlock(g_threadSendMutex);
- OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
- OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
- return ret;
+ return res;
}
jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
+ // reset scan interval time after checking scanned devices
+ CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
+
+ // since there is no callback related stop success
+ // and scanning should be stopped before connectGatt is called.
+ // it should wait a few micro seconds.
+ usleep(100000);
+
// get gatt object from Bluetooth Device object for closeProfileProxy(..)
jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
if (jni_address)
return NULL;
}
- // get BluetoothDevice method
- OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
- jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
- "connectGatt",
- "(Landroid/content/Context;ZLandroid/"
- "bluetooth/BluetoothGattCallback;)"
- "Landroid/bluetooth/BluetoothGatt;");
- if (!jni_mid_connectGatt)
+ jobject jni_obj_connectGatt = NULL;
+ jint jni_int_sdk = CALEGetBuildVersion(env);
+ OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
+ if (jni_int_sdk >= 23) // upper than API level 23
{
- OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
- return NULL;
- }
+ jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
+ "connectGatt",
+ "(Landroid/content/Context;ZLandroid/"
+ "bluetooth/BluetoothGattCallback;I)"
+ "Landroid/bluetooth/BluetoothGatt;");
+ if (!jni_mid_connectGatt)
+ {
+ OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
+ return NULL;
+ }
- OIC_LOG(INFO, TAG, "CALL API - connectGatt");
- jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
- jni_mid_connectGatt,
- NULL,
- autoconnect, g_leGattCallback);
- if (!jni_obj_connectGatt)
- {
- OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
- CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
- CALEClientUpdateSendCnt(env);
- return NULL;
+ jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
+ OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
+ jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
+ jni_mid_connectGatt, NULL,
+ autoconnect, g_leGattCallback,
+ jni_transport_le);
+ if (!jni_obj_connectGatt)
+ {
+ OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
+ CACheckJNIException(env);
+ CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
+ CALEClientUpdateSendCnt(env);
+ return NULL;
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
+ }
}
- else
+ else // lower than API level 23
{
- OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
+#ifdef HIDDEN_API
+ const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+ if (!address)
+ {
+ OIC_LOG(ERROR, TAG, "GetStringUTFChars has failed");
+ return NULL;
+ }
+ OIC_LOG(INFO, TAG, "CALL API - connectGatt for hidden");
+ jni_obj_connectGatt = CALEClientHiddenConnectGatt(bluetoothDevice, address, autoconnect);
+
+#else
+
+ jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
+ "connectGatt",
+ "(Landroid/content/Context;ZLandroid/"
+ "bluetooth/BluetoothGattCallback;)"
+ "Landroid/bluetooth/BluetoothGatt;");
+ if (!jni_mid_connectGatt)
+ {
+ OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
+ return NULL;
+ }
+
+ OIC_LOG(INFO, TAG, "CALL API - connectGatt");
+ jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
+ jni_mid_connectGatt,
+ NULL,
+ autoconnect, g_leGattCallback);
+#endif
+ if (!jni_obj_connectGatt)
+ {
+ OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
+ CACheckJNIException(env);
+ CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
+ CALEClientUpdateSendCnt(env);
+ return NULL;
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
+ }
+
}
+
return jni_obj_connectGatt;
}
+bool CALEClientIsConnected(const char* address)
+{
+ if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+ STATE_SERVICE_CONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex))
+ {
+ OIC_LOG(DEBUG, TAG, "current state is connected");
+ return true;
+ }
+ OIC_LOG(DEBUG, TAG, "current state is not connected");
+ return false;
+}
+
CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
{
OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
if (!jni_cid_BTAdapter)
{
OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
// get remote bt adapter method
if (!jni_mid_getDefaultAdapter)
{
OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
// gat bt adapter object
if (!jni_obj_BTAdapter)
{
OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
// get closeProfileProxy method
if (!jni_mid_closeProfileProxy)
{
OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
if (!jni_cid_BTProfile)
{
OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
// GATT - Constant value : 7 (0x00000007)
if (!id_gatt)
{
OIC_LOG(ERROR, TAG, "id_gatt is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
+ CACheckJNIException(env);
OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
(*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
- if ((*env)->ExceptionCheck(env))
+ if (CACheckJNIException(env))
{
OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
return CA_STATUS_FAILED;
}
OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
return CA_STATUS_OK;
+
+error_exit:
+ CACheckJNIException(env);
+ return CA_STATUS_FAILED;
}
// call disconnect gatt method
OIC_LOG(INFO, TAG, "CALL API - disconnect");
(*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
- if ((*env)->ExceptionCheck(env))
+ if (CACheckJNIException(env))
{
OIC_LOG(ERROR, TAG, "disconnect has failed");
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
return CA_STATUS_FAILED;
}
if (!address)
{
OIC_LOG(ERROR, TAG, "address is null");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
+ CACheckJNIException(env);
(*env)->ReleaseStringUTFChars(env, remote_address, address);
return CA_STATUS_FAILED;
}
OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
- if (!strcmp(address, setAddress))
+ if (!strcasecmp(address, setAddress))
{
CAResult_t res = CALEClientDisconnect(env, jarrayObj);
if (CA_STATUS_OK != res)
return CA_STATUS_OK;
}
+CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
+{
+ VERIFY_NON_NULL(env, TAG, "env is null");
+ VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+
+ if (!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ // get BluetoothGatt.requestMtu method
+ OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
+ jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
+ "requestMtu", "(I)Z");
+ if (!jni_mid_requestMtu)
+ {
+ OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
+ return CA_STATUS_FAILED;
+ }
+
+ // call requestMtu
+ OIC_LOG(INFO, TAG, "CALL API - requestMtu");
+ jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
+ if (!ret)
+ {
+ OIC_LOG(ERROR, TAG, "requestMtu has failed");
+ CACheckJNIException(env);
+ return CA_STATUS_FAILED;
+ }
+
+ return CA_STATUS_OK;
+}
+
CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
{
VERIFY_NON_NULL(env, TAG, "env is null");
if (!ret)
{
OIC_LOG(ERROR, TAG, "discoverServices has not been started");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
VERIFY_NON_NULL_VOID(object, TAG, "object 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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
if (!address)
{
+ CACheckJNIException(env);
CALEClientSendFinish(env, gatt);
return CA_STATUS_FAILED;
}
- ca_mutex_lock(g_threadSendStateMutex);
+ oc_mutex_lock(g_threadSendStateMutex);
- if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
+ if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
OIC_LOG(INFO, TAG, "current state is SENDING");
(*env)->ReleaseStringUTFChars(env, jni_address, address);
- ca_mutex_unlock(g_threadSendStateMutex);
+ oc_mutex_unlock(g_threadSendStateMutex);
return CA_STATUS_OK;
}
- if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
- STATE_SENDING))
+ if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+ STATE_SENDING,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
(*env)->ReleaseStringUTFChars(env, jni_address, address);
CALEClientSendFinish(env, gatt);
- ca_mutex_unlock(g_threadSendStateMutex);
+ oc_mutex_unlock(g_threadSendStateMutex);
return CA_STATUS_FAILED;
}
(*env)->ReleaseStringUTFChars(env, jni_address, address);
- ca_mutex_unlock(g_threadSendStateMutex);
+ oc_mutex_unlock(g_threadSendStateMutex);
+
+ jbyteArray sendData = NULL;
+ oc_mutex_lock(g_setValueMutex);
+ if (g_sendBuffer)
+ {
+ OIC_LOG(INFO, TAG, "alloc local reference for data");
+ sendData = (jbyteArray)(*env)->NewLocalRef(env, g_sendBuffer);
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "send Buffer is empty");
+ oc_mutex_unlock(g_setValueMutex);
+ return CA_STATUS_FAILED;
+ }
+ oc_mutex_unlock(g_setValueMutex);
// send data
- jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
+ jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, sendData);
if (!jni_obj_character)
{
+ if (sendData)
+ {
+ (*env)->DeleteLocalRef(env, sendData);
+ }
CALEClientSendFinish(env, gatt);
return CA_STATUS_FAILED;
}
+ if (sendData)
+ {
+ (*env)->DeleteLocalRef(env, sendData);
+ }
+
CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
if (CA_STATUS_OK != ret)
{
// 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);
+ oc_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,
+ if (OC_WAIT_SUCCESS != oc_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);
+ oc_mutex_unlock(g_threadWriteCharacteristicMutex);
return CA_STATUS_FAILED;
}
}
// reset flag set by writeCharacteristic Callback
g_isSignalSetFlag = false;
- ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+ oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+ CALEClientUpdateSendCnt(env);
OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
return CA_STATUS_OK;
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))
+ CACheckJNIException(env);
+ if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEWriteCharacteristicThread,
+ (void*)gattParam, NULL))
{
OIC_LOG(ERROR, TAG, "Failed to create read thread!");
return CA_STATUS_FAILED;
}
else
{
+ CACheckJNIException(env);
OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
return CA_STATUS_FAILED;
}
if (!jni_uuid)
{
OIC_LOG(ERROR, TAG, "jni_uuid is null");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
else
{
OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
else
{
OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
+ CACheckJNIException(env);
return CA_STATUS_FAILED;
}
if (!jni_obj_gattService)
{
OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
+ CACheckJNIException(env);
return NULL;
}
if (!uuid)
{
OIC_LOG(ERROR, TAG, "uuid is null");
+ CACheckJNIException(env);
return NULL;
}
return NULL;
}
- OIC_LOG(DEBUG, TAG, "request to get Characteristic");
+ OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
jni_mid_getCharacteristic,
jni_obj_tx_uuid);
+ if (!jni_obj_GattCharacteristic)
+ {
+ OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
+ CACheckJNIException(env);
+ return NULL;
+ }
(*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
return jni_obj_GattCharacteristic;
if (!jni_uuid)
{
OIC_LOG(ERROR, TAG, "jni_uuid is null");
- return NULL;
+ goto error_exit;
}
jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
if (!jni_cid_BTGattCharacteristic)
{
OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
- return NULL;
+ goto error_exit;
}
OIC_LOG(DEBUG, TAG, "set value in Characteristic");
if (!jni_mid_setValue)
{
OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
- return NULL;
+ goto error_exit;
}
+ OIC_LOG(DEBUG, TAG, "CALL API - setValue");
jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
data);
if (JNI_TRUE == ret)
}
else
{
- 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;
+ OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
+ goto error_exit;
}
- jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
- "WRITE_TYPE_NO_RESPONSE", "I");
- if (!jni_fid_no_response)
+ if (!g_setHighQoS)
{
- OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
- return NULL;
- }
+ OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
+ // 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");
+ goto error_exit;
+ }
- jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
- jni_fid_no_response);
+ 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");
+ goto error_exit;
+ }
+
+ jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
+ jni_fid_no_response);
+ CACheckJNIException(env);
- (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
+ (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
+ if (CACheckJNIException(env))
+ {
+ OIC_LOG(ERROR, TAG, "setWriteType has failed");
+ }
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "It will run with response property");
+ }
return jni_obj_GattCharacteristic;
+
+error_exit:
+ CACheckJNIException(env);
+ return NULL;
}
jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
jni_mid_getValue);
+ CACheckJNIException(env);
return jni_obj_data_array;
}
}
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(INFO, TAG, "Could not get JNIEnv pointer");
res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
if (JNI_OK != res)
if (!jni_cid_uuid_list)
{
OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
+ CACheckJNIException(env);
goto error_exit;
}
if (!jni_obj_uuid_list)
{
OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
+ CACheckJNIException(env);
goto error_exit;
}
(*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
+ CACheckJNIException(env);
if (isAttached)
{
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");
if (!jni_obj_descriptor)
{
OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
- return CA_NOT_SUPPORTED;
+ goto error_exit;
}
OIC_LOG(DEBUG, TAG, "set value in descriptor");
if (!jni_cid_descriptor)
{
OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
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;
+ goto error_exit;
}
- jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
- "ENABLE_NOTIFICATION_VALUE", "[B");
- if (!jni_fid_NotiValue)
+ jfieldID jni_fid_NotiValue = NULL;
+ if (g_setHighQoS)
{
- OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
- return CA_STATUS_FAILED;
+ OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
+ jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
+ "ENABLE_INDICATION_VALUE", "[B");
+ if (!jni_fid_NotiValue)
+ {
+ OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
+ goto error_exit;
+ }
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
+ 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");
+ goto error_exit;
+ }
}
-
- OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
jboolean jni_setvalue = (*env)->CallBooleanMethod(
env, jni_obj_descriptor, jni_mid_setValue,
else
{
OIC_LOG(ERROR, TAG, "setValue has failed");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
else
{
OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
- return CA_STATUS_FAILED;
+ goto error_exit;
}
return CA_STATUS_OK;
+
+error_exit:
+ CACheckJNIException(env);
+ return CA_STATUS_FAILED;
}
void CALEClientCreateScanDeviceList(JNIEnv *env)
OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
VERIFY_NON_NULL_VOID(env, TAG, "env is null");
- ca_mutex_lock(g_deviceListMutex);
+ oc_mutex_lock(g_deviceListMutex);
// create new object array
if (g_deviceList == NULL)
{
g_deviceList = u_arraylist_create();
}
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
}
CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
VERIFY_NON_NULL(device, TAG, "device is null");
VERIFY_NON_NULL(env, TAG, "env is null");
- ca_mutex_lock(g_deviceListMutex);
+ oc_mutex_lock(g_deviceListMutex);
if (!g_deviceList)
{
OIC_LOG(ERROR, TAG, "gdevice_list is null");
-
- CALEClientSetScanFlag(false);
- if (CA_STATUS_OK != CALEClientStopScan())
- {
- OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
- }
-
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
if (!jni_remoteAddress)
{
OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
if (!remoteAddress)
{
OIC_LOG(ERROR, TAG, "remoteAddress is null");
- ca_mutex_unlock(g_deviceListMutex);
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_remoteAddress);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
{
jobject gdevice = (*env)->NewGlobalRef(env, device);
+ CACheckJNIException(env);
u_arraylist_add(g_deviceList, gdevice);
- ca_cond_signal(g_deviceDescCond);
+ oc_cond_signal(g_deviceDescCond);
OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
}
(*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
+ (*env)->DeleteLocalRef(env, jni_remoteAddress);
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_OK;
}
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
return true;
}
- if (!strcmp(remoteAddress, setAddress))
+ if (!strcasecmp(remoteAddress, setAddress))
{
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
return true;
}
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
}
-
- OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
-
return false;
}
OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
VERIFY_NON_NULL(env, TAG, "env is null");
- ca_mutex_lock(g_deviceListMutex);
+ oc_mutex_lock(g_deviceListMutex);
if (!g_deviceList)
{
OIC_LOG(ERROR, TAG, "g_deviceList is null");
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
OICFree(g_deviceList);
g_deviceList = NULL;
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_OK;
}
VERIFY_NON_NULL(address, TAG, "address is null");
VERIFY_NON_NULL(env, TAG, "env is null");
- ca_mutex_lock(g_deviceListMutex);
+ oc_mutex_lock(g_deviceListMutex);
if (!g_deviceList)
{
OIC_LOG(ERROR, TAG, "g_deviceList is null");
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
if (!jarrayObj)
{
OIC_LOG(ERROR, TAG, "jarrayObj is null");
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
if (!jni_setAddress)
{
OIC_LOG(ERROR, TAG, "jni_setAddress is null");
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
- ca_mutex_unlock(g_deviceListMutex);
+ CACheckJNIException(env);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
if (!remoteAddress)
{
OIC_LOG(ERROR, TAG, "remoteAddress is null");
+ CACheckJNIException(env);
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
- if (!strcmp(setAddress, remoteAddress))
+ if (!strcasecmp(setAddress, remoteAddress))
{
OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
(*env)->DeleteGlobalRef(env, jarrayObj);
if (NULL == u_arraylist_remove(g_deviceList, index))
{
OIC_LOG(ERROR, TAG, "List removal failed.");
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_FAILED;
}
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
return CA_STATUS_OK;
}
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
(*env)->ReleaseStringUTFChars(env, address, remoteAddress);
}
- ca_mutex_unlock(g_deviceListMutex);
+ oc_mutex_unlock(g_deviceListMutex);
OIC_LOG(DEBUG, TAG, "There are no object in the device list");
return CA_STATUS_OK;
VERIFY_NON_NULL(env, TAG, "env is null");
VERIFY_NON_NULL(gatt, TAG, "gatt is null");
- ca_mutex_lock(g_gattObjectMutex);
+ oc_mutex_lock(g_gattObjectMutex);
if (!g_gattObjectList)
{
OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
if (!jni_remoteAddress)
{
OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
if (!remoteAddress)
{
OIC_LOG(ERROR, TAG, "remoteAddress is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_remoteAddress);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
}
(*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
- ca_mutex_unlock(g_gattObjectMutex);
+ (*env)->DeleteLocalRef(env, jni_remoteAddress);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_OK;
}
bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
{
- OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
VERIFY_NON_NULL(env, TAG, "env is null");
VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
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)
{
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
return true;
}
- if (!strcmp(remoteAddress, setAddress))
+ if (!strcasecmp(remoteAddress, setAddress))
{
OIC_LOG(DEBUG, TAG, "the device is already set");
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
return true;
}
- else
- {
- (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
- continue;
- }
+ (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
}
OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
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);
+ oc_mutex_lock(g_gattObjectMutex);
uint32_t length = u_arraylist_length(g_gattObjectList);
for (uint32_t index = 0; index < length; index++)
{
if (!jarrayObj)
{
OIC_LOG(ERROR, TAG, "jarrayObj is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return NULL;
}
if (!jni_setAddress)
{
OIC_LOG(ERROR, TAG, "jni_setAddress is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return NULL;
}
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
+ oc_mutex_unlock(g_gattObjectMutex);
return NULL;
}
- if (!strcmp(remoteAddress, setAddress))
+ if (!strcasecmp(remoteAddress, setAddress))
{
OIC_LOG(DEBUG, TAG, "the device is already set");
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return jarrayObj;
}
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+ (*env)->DeleteLocalRef(env, jni_setAddress);
}
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
return NULL;
}
OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
VERIFY_NON_NULL(env, TAG, "env is null");
- ca_mutex_lock(g_gattObjectMutex);
+ oc_mutex_lock(g_gattObjectMutex);
if (!g_gattObjectList)
{
OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_OK;
}
OICFree(g_gattObjectList);
g_gattObjectList = NULL;
OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_OK;
}
VERIFY_NON_NULL(gatt, TAG, "gatt is null");
VERIFY_NON_NULL(env, TAG, "env is null");
- ca_mutex_lock(g_gattObjectMutex);
+ oc_mutex_lock(g_gattObjectMutex);
if (!g_gattObjectList)
{
OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_OK;
}
if (!jarrayObj)
{
OIC_LOG(ERROR, TAG, "jarrayObj is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
if (!jni_setAddress)
{
OIC_LOG(ERROR, TAG, "jni_setAddress is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ CACheckJNIException(env);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
{
OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
if (!remoteAddress)
{
OIC_LOG(ERROR, TAG, "remoteAddress is null");
+ CACheckJNIException(env);
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
- if (!strcmp(setAddress, remoteAddress))
+ if (!strcasecmp(setAddress, remoteAddress))
{
OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
(*env)->DeleteGlobalRef(env, jarrayObj);
if (NULL == u_arraylist_remove(g_gattObjectList, index))
{
OIC_LOG(ERROR, TAG, "List removal failed.");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_OK;
}
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
(*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
}
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
OIC_LOG(DEBUG, TAG, "there are no target object");
return CA_STATUS_OK;
}
VERIFY_NON_NULL(addr, TAG, "addr is null");
VERIFY_NON_NULL(env, TAG, "env is null");
- ca_mutex_lock(g_gattObjectMutex);
+ oc_mutex_lock(g_gattObjectMutex);
if (!g_gattObjectList)
{
OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_OK;
}
if (!jarrayObj)
{
OIC_LOG(ERROR, TAG, "jarrayObj is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
if (!jni_setAddress)
{
OIC_LOG(ERROR, TAG, "jni_setAddress is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
if (!setAddress)
{
OIC_LOG(ERROR, TAG, "setAddress is null");
- ca_mutex_unlock(g_gattObjectMutex);
+ CACheckJNIException(env);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
{
OIC_LOG(ERROR, TAG, "remoteAddress is null");
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
- if (!strcmp(setAddress, remoteAddress))
+ if (!strcasecmp(setAddress, remoteAddress))
{
OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
(*env)->DeleteGlobalRef(env, jarrayObj);
if (NULL == u_arraylist_remove(g_gattObjectList, index))
{
OIC_LOG(ERROR, TAG, "List removal failed.");
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_FAILED;
}
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
return CA_STATUS_OK;
}
(*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
(*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
}
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
OIC_LOG(DEBUG, TAG, "there are no target object");
return CA_STATUS_FAILED;
}
jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
{
- OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
-
VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
if (!targetAddress)
{
OIC_LOG(ERROR, TAG, "targetAddress is not available");
+ CACheckJNIException(env);
return NULL;
}
return NULL;
}
- ca_mutex_lock(g_gattObjectMutex);
+ oc_mutex_lock(g_gattObjectMutex);
size_t length = u_arraylist_length(g_gattObjectList);
OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
if (!jarrayObj)
{
- ca_mutex_unlock(g_gattObjectMutex);
+ oc_mutex_unlock(g_gattObjectMutex);
OIC_LOG(ERROR, TAG, "jarrayObj is null");
(*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
return NULL;
- }
-
- jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
- if (!jni_obj_device)
- {
- ca_mutex_unlock(g_gattObjectMutex);
- OIC_LOG(ERROR, TAG, "jni_obj_device is null");
- (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
- return NULL;
- }
-
- jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
- if (!jni_btAddress)
- {
- ca_mutex_unlock(g_gattObjectMutex);
- OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
- (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
- return NULL;
- }
-
- const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
- if (!btAddress)
- {
- ca_mutex_unlock(g_gattObjectMutex);
- OIC_LOG(ERROR, TAG, "btAddress is not available");
- (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
- return NULL;
- }
-
- OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
- if (!strcmp(targetAddress, btAddress))
- {
- OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
-
- // get LE address
- jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
- if (!jni_LEAddress)
- {
- OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
- }
- ca_mutex_unlock(g_gattObjectMutex);
- (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
- (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
- (*env)->DeleteLocalRef(env, jni_btAddress);
- (*env)->DeleteLocalRef(env, jni_obj_device);
- return jni_LEAddress;
- }
- (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
- (*env)->DeleteLocalRef(env, jni_btAddress);
- (*env)->DeleteLocalRef(env, jni_obj_device);
- }
- ca_mutex_unlock(g_gattObjectMutex);
-
- (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
- OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
- return NULL;
-}
-
-/**
- * BT State List
- */
-
-CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
- uint16_t target_state)
-{
- VERIFY_NON_NULL(address, TAG, "address is null");
- VERIFY_NON_NULL(address, TAG, "state_type is null");
- VERIFY_NON_NULL(address, TAG, "target_state is null");
-
- if (!g_deviceStateList)
- {
- OIC_LOG(ERROR, TAG, "gdevice_list is null");
- return CA_STATUS_FAILED;
- }
-
- ca_mutex_lock(g_deviceStateListMutex);
-
- if (CALEClientIsDeviceInList(address))
- {
- CALEState_t* curState = CALEClientGetStateInfo(address);
- if(!curState)
- {
- OIC_LOG(ERROR, TAG, "curState is null");
- ca_mutex_unlock(g_deviceStateListMutex);
- return CA_STATUS_FAILED;
- }
-
- switch(state_type)
- {
- case CA_LE_CONNECTION_STATE:
- curState->connectedState = target_state;
- break;
- case CA_LE_SEND_STATE:
- curState->sendState = target_state;
- break;
- default:
- break;
- }
- OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
- curState->address, curState->connectedState, curState->sendState,
- curState->autoConnectFlag);
- }
- else /** state is added newly **/
- {
- if (strlen(address) > CA_MACADDR_SIZE)
- {
- OIC_LOG(ERROR, TAG, "address is not proper");
- ca_mutex_unlock(g_deviceStateListMutex);
- return CA_STATUS_INVALID_PARAM;
- }
-
- CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
- if (!newstate)
- {
- OIC_LOG(ERROR, TAG, "out of memory");
- ca_mutex_unlock(g_deviceStateListMutex);
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- OICStrcpy(newstate->address, sizeof(newstate->address), address);
-
- switch(state_type)
- {
- case CA_LE_CONNECTION_STATE:
- newstate->connectedState = target_state;
- newstate->sendState = STATE_SEND_NONE;
- break;
- case CA_LE_SEND_STATE:
- newstate->connectedState = STATE_DISCONNECTED;
- newstate->sendState = target_state;
- break;
- default:
- break;
- }
- OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
- "conn : %d, send : %d, ACFlag : %d",
- newstate->address, newstate->connectedState, newstate->sendState,
- newstate->autoConnectFlag);
- u_arraylist_add(g_deviceStateList, newstate); // update new state
- }
-
- 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, "CALEClientRemoveAllDeviceState");
-
- 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 CALEClientResetDeviceStateForAll()
-{
- OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
-
- 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;
- }
-
- size_t length = u_arraylist_length(g_deviceStateList);
- for (size_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;
- }
-
- // autoConnectFlag value will be not changed,
- // since it has reset only termination case.
- state->connectedState = STATE_DISCONNECTED;
- state->sendState = STATE_SEND_NONE;
- }
- 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", state->address);
-
- CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
- index);
- if (NULL == targetState)
- {
- OIC_LOG(ERROR, TAG, "List removal failed.");
- return CA_STATUS_FAILED;
- }
-
- OICFree(targetState);
- return CA_STATUS_OK;
- }
- }
-
- return CA_STATUS_OK;
-}
-
-CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
-{
- 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);
- OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
- OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
+ jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
+ if (!jni_obj_device)
+ {
+ CACheckJNIException(env);
+ oc_mutex_unlock(g_gattObjectMutex);
+ OIC_LOG(ERROR, TAG, "jni_obj_device is null");
+ (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+ return NULL;
+ }
- for (uint32_t index = 0; index < length; index++)
- {
- CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
- if (!state)
+ jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
+ if (!jni_btAddress)
{
- OIC_LOG(ERROR, TAG, "CALEState_t object is null");
- continue;
+ oc_mutex_unlock(g_gattObjectMutex);
+ OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+ (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+ (*env)->DeleteLocalRef(env, jni_obj_device);
+ return NULL;
}
- OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
+ const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
+ if (!btAddress)
+ {
+ CACheckJNIException(env);
+ oc_mutex_unlock(g_gattObjectMutex);
+ OIC_LOG(ERROR, TAG, "btAddress is not available");
+ (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+ (*env)->DeleteLocalRef(env, jni_btAddress);
+ (*env)->DeleteLocalRef(env, jni_obj_device);
+ return NULL;
+ }
- if (!strcmp(state->address, remoteAddress))
+ OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
+ if (!strcasecmp(targetAddress, btAddress))
{
- OIC_LOG(DEBUG, TAG, "found state");
- return state;
+ OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
+
+ // get LE address
+ jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
+ if (!jni_LEAddress)
+ {
+ OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
+ }
+ oc_mutex_unlock(g_gattObjectMutex);
+ (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+ (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
+ (*env)->DeleteLocalRef(env, jni_btAddress);
+ (*env)->DeleteLocalRef(env, jni_obj_device);
+ return jni_LEAddress;
}
+ (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
+ (*env)->DeleteLocalRef(env, jni_btAddress);
+ (*env)->DeleteLocalRef(env, jni_obj_device);
}
+ oc_mutex_unlock(g_gattObjectMutex);
- OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
+ (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+ OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
return NULL;
}
-bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
- uint16_t target_state)
+/**
+ * BT State List
+ */
+CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
+ jobject device,
+ uint16_t state_type,
+ uint16_t target_state)
{
- OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
- state_type, target_state);
- VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+ VERIFY_NON_NULL(device, TAG, "device is null");
- ca_mutex_lock(g_deviceStateListMutex);
- if (!g_deviceStateList)
+ // get Bluetooth Address
+ jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
+ if (!jni_Address)
{
- OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
- ca_mutex_unlock(g_deviceStateListMutex);
- return false;
+ OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+ return CA_STATUS_FAILED;
}
- CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
- if (NULL == state)
+ const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
+ if (!address)
{
- OIC_LOG(ERROR, TAG, "state is null");
- ca_mutex_unlock(g_deviceStateListMutex);
- return false;
+ OIC_LOG(ERROR, TAG, "targetAddress is not available");
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_Address);
+ return CA_STATUS_FAILED;
}
- uint16_t curValue = 0;
- switch(state_type)
+ if (CALEIsValidState(address, state_type, target_state,
+ g_deviceStateList,
+ g_deviceStateListMutex))
{
- case CA_LE_CONNECTION_STATE:
- curValue = state->connectedState;
- break;
- case CA_LE_SEND_STATE:
- curValue = state->sendState;
- break;
- default:
- break;
+ (*env)->DeleteLocalRef(env, jni_Address);
+ return CA_STATUS_OK;
}
- if (target_state == curValue)
- {
- ca_mutex_unlock(g_deviceStateListMutex);
- return true;
- }
- else
+ CAResult_t res = CALEUpdateDeviceState(address, state_type,
+ target_state,
+ g_deviceStateList,
+ g_deviceStateListMutex);
+ if (CA_STATUS_OK != res)
{
- ca_mutex_unlock(g_deviceStateListMutex);
- return false;
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
}
+ (*env)->ReleaseStringUTFChars(env, jni_Address, address);
+ (*env)->DeleteLocalRef(env, jni_Address);
- ca_mutex_unlock(g_deviceStateListMutex);
- return false;
+ return res;
+}
+
+CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
+ jint state_idx, jboolean flag)
+{
+ return CALESetFlagToState(env, jni_address, state_idx, flag,
+ g_deviceStateList, g_deviceStateListMutex);
+}
+
+jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
+{
+ return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
+ g_deviceStateListMutex);
+}
+
+uint16_t CALEClientGetMtuSize(const char* address)
+{
+ return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
}
void CALEClientCreateDeviceList()
}
}
+CAResult_t CALEClientResetDeviceStateForAll()
+{
+ return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
+}
+
/**
* Check Sent Count for remove g_sendBuffer
*/
VERIFY_NON_NULL_VOID(env, TAG, "env is null");
// mutex lock
- ca_mutex_lock(g_threadMutex);
+ oc_mutex_lock(g_threadMutex);
g_currentSentCnt++;
g_targetCnt = 0;
g_currentSentCnt = 0;
- if (g_sendBuffer)
- {
- (*env)->DeleteGlobalRef(env, g_sendBuffer);
- g_sendBuffer = NULL;
- }
+ CALEDeleteSendBuffer(env);
+
// notity the thread
- ca_cond_signal(g_threadCond);
+ oc_cond_signal(g_threadCond);
+ oc_cond_signal(g_threadWriteCharacteristicCond);
CALEClientSetSendFinishFlag(true);
OIC_LOG(DEBUG, TAG, "set signal for send data");
}
+
+#ifdef SCAN_INTERVAL
+ // reset interval scan logic
+ CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
+#endif
+
// mutex unlock
- ca_mutex_unlock(g_threadMutex);
+ oc_mutex_unlock(g_threadMutex);
}
CAResult_t CALEClientInitGattMutexVaraibles()
{
if (NULL == g_bleReqRespClientCbMutex)
{
- g_bleReqRespClientCbMutex = ca_mutex_new();
+ g_bleReqRespClientCbMutex = oc_mutex_new();
if (NULL == g_bleReqRespClientCbMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_bleServerBDAddressMutex)
{
- g_bleServerBDAddressMutex = ca_mutex_new();
+ g_bleServerBDAddressMutex = oc_mutex_new();
if (NULL == g_bleServerBDAddressMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_threadMutex)
{
- g_threadMutex = ca_mutex_new();
+ g_threadMutex = oc_mutex_new();
if (NULL == g_threadMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_threadSendMutex)
{
- g_threadSendMutex = ca_mutex_new();
+ g_threadSendMutex = oc_mutex_new();
if (NULL == g_threadSendMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_deviceListMutex)
{
- g_deviceListMutex = ca_mutex_new();
+ g_deviceListMutex = oc_mutex_new();
if (NULL == g_deviceListMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_gattObjectMutex)
{
- g_gattObjectMutex = ca_mutex_new();
+ g_gattObjectMutex = oc_mutex_new();
if (NULL == g_gattObjectMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_deviceStateListMutex)
{
- g_deviceStateListMutex = ca_mutex_new();
+ g_deviceStateListMutex = oc_mutex_new();
if (NULL == g_deviceStateListMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_SendFinishMutex)
{
- g_SendFinishMutex = ca_mutex_new();
+ g_SendFinishMutex = oc_mutex_new();
if (NULL == g_SendFinishMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
- return CA_STATUS_FAILED;
- }
- }
-
- if (NULL == g_scanMutex)
- {
- g_scanMutex = ca_mutex_new();
- if (NULL == g_scanMutex)
- {
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_threadWriteCharacteristicMutex)
{
- g_threadWriteCharacteristicMutex = ca_mutex_new();
+ g_threadWriteCharacteristicMutex = oc_mutex_new();
if (NULL == g_threadWriteCharacteristicMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_deviceScanRetryDelayMutex)
{
- g_deviceScanRetryDelayMutex = ca_mutex_new();
+ g_deviceScanRetryDelayMutex = oc_mutex_new();
if (NULL == g_deviceScanRetryDelayMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (NULL == g_threadSendStateMutex)
{
- g_threadSendStateMutex = ca_mutex_new();
+ g_threadSendStateMutex = oc_mutex_new();
if (NULL == g_threadSendStateMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ if (NULL == g_threadScanIntervalMutex)
+ {
+ g_threadScanIntervalMutex = oc_mutex_new();
+ if (NULL == g_threadScanIntervalMutex)
+ {
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ if (NULL == g_setValueMutex)
+ {
+ g_setValueMutex = oc_mutex_new();
+ if (NULL == g_setValueMutex)
+ {
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
void CALEClientTerminateGattMutexVariables()
{
- ca_mutex_free(g_bleReqRespClientCbMutex);
+ oc_mutex_free(g_bleReqRespClientCbMutex);
g_bleReqRespClientCbMutex = NULL;
- ca_mutex_free(g_bleServerBDAddressMutex);
+ oc_mutex_free(g_bleServerBDAddressMutex);
g_bleServerBDAddressMutex = NULL;
- ca_mutex_free(g_threadMutex);
+ oc_mutex_free(g_threadMutex);
g_threadMutex = NULL;
- ca_mutex_free(g_threadSendMutex);
+ oc_mutex_free(g_threadSendMutex);
g_threadSendMutex = NULL;
- ca_mutex_free(g_deviceListMutex);
+ oc_mutex_free(g_deviceListMutex);
g_deviceListMutex = NULL;
- ca_mutex_free(g_SendFinishMutex);
+ oc_mutex_free(g_SendFinishMutex);
g_SendFinishMutex = NULL;
- ca_mutex_free(g_scanMutex);
- g_scanMutex = NULL;
-
- ca_mutex_free(g_threadWriteCharacteristicMutex);
+ oc_mutex_free(g_threadWriteCharacteristicMutex);
g_threadWriteCharacteristicMutex = NULL;
- ca_mutex_free(g_deviceScanRetryDelayMutex);
+ oc_mutex_free(g_deviceScanRetryDelayMutex);
g_deviceScanRetryDelayMutex = NULL;
- ca_mutex_free(g_threadSendStateMutex);
+ oc_mutex_free(g_threadSendStateMutex);
g_threadSendStateMutex = NULL;
+
+ oc_mutex_free(g_threadScanIntervalMutex);
+ g_threadScanIntervalMutex = NULL;
+
+ oc_mutex_free(g_gattObjectMutex);
+ g_gattObjectMutex = NULL;
+
+ oc_mutex_free(g_deviceStateListMutex);
+ g_deviceStateListMutex = NULL;
+
+ oc_mutex_free(g_setValueMutex);
+ g_setValueMutex = NULL;
}
void CALEClientSetSendFinishFlag(bool flag)
{
OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
- ca_mutex_lock(g_SendFinishMutex);
+ oc_mutex_lock(g_SendFinishMutex);
g_isFinishedSendData = flag;
- ca_mutex_unlock(g_SendFinishMutex);
+ oc_mutex_unlock(g_SendFinishMutex);
}
/**
// init mutex for send logic
if (!g_deviceDescCond)
{
- g_deviceDescCond = ca_cond_new();
+ g_deviceDescCond = oc_cond_new();
}
if (!g_threadCond)
{
- g_threadCond = ca_cond_new();
+ g_threadCond = oc_cond_new();
}
if (!g_threadWriteCharacteristicCond)
{
- g_threadWriteCharacteristicCond = ca_cond_new();
+ g_threadWriteCharacteristicCond = oc_cond_new();
+ }
+
+ if (!g_threadScanIntervalCond)
+ {
+ g_threadScanIntervalCond = oc_cond_new();
}
- CAResult_t ret = CALEClientStartScan();
+ CAResult_t ret = CALEClientStartScanWithInterval();
if (CA_STATUS_OK != ret)
{
- OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+ OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has 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)
{
- 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, "CALEClientDisconnectAll has failed");
}
- ret = CALEClientStopScan();
- if(CA_STATUS_OK != ret)
- {
- OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
- }
+ CALEClientStopScanWithInterval();
+
+ oc_mutex_lock(g_threadWriteCharacteristicMutex);
+ OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
+ oc_cond_signal(g_threadWriteCharacteristicCond);
+ oc_mutex_unlock(g_threadWriteCharacteristicMutex);
- ca_mutex_lock(g_threadMutex);
- OIC_LOG(DEBUG, TAG, "signal - connection cond");
- ca_cond_signal(g_threadCond);
CALEClientSetSendFinishFlag(true);
- ca_mutex_unlock(g_threadMutex);
+ oc_mutex_lock(g_threadMutex);
+ OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
+ oc_cond_signal(g_threadCond);
+ oc_mutex_unlock(g_threadMutex);
- ca_mutex_lock(g_threadWriteCharacteristicMutex);
- OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
- ca_cond_signal(g_threadWriteCharacteristicCond);
- ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+ oc_mutex_lock(g_deviceScanRetryDelayMutex);
+ OIC_LOG(DEBUG, TAG, "signal - delay cond");
+ oc_cond_signal(g_deviceScanRetryDelayCond);
+ oc_mutex_unlock(g_deviceScanRetryDelayMutex);
- ca_mutex_lock(g_deviceScanRetryDelayMutex);
+ oc_mutex_lock(g_threadScanIntervalMutex);
OIC_LOG(DEBUG, TAG, "signal - delay cond");
- ca_cond_signal(g_deviceScanRetryDelayCond);
- ca_mutex_unlock(g_deviceScanRetryDelayMutex);
+ oc_cond_signal(g_threadScanIntervalCond);
+ oc_mutex_unlock(g_threadScanIntervalMutex);
- ca_cond_free(g_deviceDescCond);
- ca_cond_free(g_threadCond);
- ca_cond_free(g_threadWriteCharacteristicCond);
- ca_cond_free(g_deviceScanRetryDelayCond);
+ oc_mutex_lock(g_threadSendMutex);
+ OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
+ oc_cond_signal(g_deviceDescCond);
+ oc_mutex_unlock(g_threadSendMutex);
+
+ oc_cond_free(g_deviceDescCond);
+ oc_cond_free(g_threadCond);
+ oc_cond_free(g_threadWriteCharacteristicCond);
+ oc_cond_free(g_deviceScanRetryDelayCond);
+ oc_cond_free(g_threadScanIntervalCond);
g_deviceDescCond = NULL;
g_threadCond = NULL;
g_threadWriteCharacteristicCond = NULL;
g_deviceScanRetryDelayCond = NULL;
+ g_threadScanIntervalCond = NULL;
if (isAttached)
{
void CATerminateLEGattClient()
{
- OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
+ OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
CAStopLEGattClient();
CALEClientTerminate();
+ OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
}
CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
uint32_t dataLen, CALETransferType_t type,
int32_t position)
{
- OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
- VERIFY_NON_NULL(data, TAG, "data is null");
+ OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
if (LE_UNICAST != type || position < 0)
void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
{
- ca_mutex_lock(g_bleReqRespClientCbMutex);
+ oc_mutex_lock(g_bleReqRespClientCbMutex);
g_CABLEClientDataReceivedCallback = callback;
- ca_mutex_unlock(g_bleReqRespClientCbMutex);
+ oc_mutex_unlock(g_bleReqRespClientCbMutex);
}
void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
CAResult_t CAGetLEAddress(char **local_address)
{
VERIFY_NON_NULL(local_address, TAG, "local_address");
- OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
return CA_NOT_SUPPORTED;
}
VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
g_leScanCallback = (*env)->NewGlobalRef(env, callback);
+ CACheckJNIException(env);
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallbackForV21(JNIEnv *env,
+ jobject obj,
+ jobject callback)
+{
+ OIC_LOG(DEBUG, TAG, "caLeRegisterLeScanCallbackForV21");
+ VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+ VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
+ VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
+
+ g_leScanCallback = (*env)->NewGlobalRef(env, callback);
+ CACheckJNIException(env);
}
JNIEXPORT void JNICALL
VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
g_leGattCallback = (*env)->NewGlobalRef(env, callback);
+ CACheckJNIException(env);
}
JNIEXPORT void JNICALL
}
}
-static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj,
+ jint errorCode)
{
- OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
-
- VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
- VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
+ VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+ VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
- jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
- "getDevice", METHODID_BT_DEVICE);
- if (!jni_mid_getDevice)
+ switch (errorCode)
{
- OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
- return NULL;
- }
+ case 1:
+ OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED");
+ break;
- jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
- if (!jni_obj_device)
- {
- OIC_LOG(ERROR, TAG, "jni_obj_device is null");
- return NULL;
- }
+ case 2:
+ OIC_LOG(ERROR, TAG,
+ "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED");
+ break;
- jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
- if (!jni_address)
- {
- OIC_LOG(ERROR, TAG, "jni_address is null");
- return NULL;
- }
+ case 3:
+ OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR");
+ break;
- OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
- return jni_address;
+ case 4:
+ OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_FEATURE_UNSUPPORTED");
+ break;
+
+ default:
+ OIC_LOG(ERROR, TAG, "BLE scan has failed with unknown error");
+ break;
+ }
}
/*
if (!address)
{
OIC_LOG(ERROR, TAG, "address is null");
+ CACheckJNIException(env);
goto error_exit;
}
- OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
+ OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
- CAResult_t res;
if (state_connected == newstate)
{
OIC_LOG(DEBUG, TAG, "LE is connected");
if (GATT_SUCCESS == status)
{
- res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_CONNECTED);
+ CAResult_t res = CALEUpdateDeviceState(address,
+ CA_LE_CONNECTION_STATE,
+ STATE_CONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex);
(*env)->ReleaseStringUTFChars(env, jni_address, address);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
goto error_exit;
}
{
OIC_LOG(DEBUG, TAG, "LE is disconnected");
- res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_DISCONNECTED);
- (*env)->ReleaseStringUTFChars(env, jni_address, address);
+ if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
+ g_deviceStateList, g_deviceStateListMutex))
+ {
+ OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
+ CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+ STATE_SEND_FAIL,
+ g_deviceStateList,
+ g_deviceStateListMutex);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
+ }
+ }
+
+ CAResult_t res = CALEUpdateDeviceState(address,
+ CA_LE_CONNECTION_STATE,
+ STATE_DISCONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
- goto error_exit;
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
}
+ (*env)->ReleaseStringUTFChars(env, jni_address, address);
res = CALEClientGattClose(env, gatt);
if (CA_STATUS_OK != res)
OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
}
- if (GATT_ERROR == status)
+ if (CALECheckConnectionStateValue(status))
{
- // when we get GATT ERROR(0x85), gatt connection can be called again.
- OIC_LOG(INFO, TAG, "retry gatt connect");
-
- jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
- if (!leAddress)
- {
- OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
- goto error_exit;
- }
-
- jobject btObject = CALEGetRemoteDevice(env, leAddress);
- if (!btObject)
- {
- OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
- goto error_exit;
- }
-
- jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
- if (!newGatt)
- {
- OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
- goto error_exit;
- }
-
- return;
+ // this state is unexpected reason to disconnect
+ // if the reason is suitable, connection logic of the device will be destroyed.
+ OIC_LOG(INFO, TAG, "connection logic destroy");
}
else
{
- if (CALECheckConnectionStateValue(status))
- {
- // this state is unexpected reason to disconnect
- // if the reason is suitable, connection logic of the device will be destroyed.
- OIC_LOG(INFO, TAG, "connection logic destroy");
- goto error_exit;
- }
- else
- {
- // other reason except for gatt_success is expected to running
- // background connection in BT platform.
- OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
- CALEClientUpdateSendCnt(env);
- return;
- }
- }
-
- if (g_sendBuffer)
- {
- (*env)->DeleteGlobalRef(env, g_sendBuffer);
- g_sendBuffer = NULL;
+ // other reason except for gatt_success is expected to running
+ // background connection in BT platform.
+ OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
}
+ CALEClientUpdateSendCnt(env);
}
return;
const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
if (!address)
{
+ CACheckJNIException(env);
CALEClientSendFinish(env, gatt);
return;
}
{
OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
- res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE);
+ res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
+ g_deviceStateList, g_deviceStateListMutex);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
+ OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
goto error_exit;
}
- res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
- STATE_SERVICE_CONNECTED);
+ res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
+ STATE_SERVICE_CONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
goto error_exit;
}
- if (g_sendBuffer)
+ res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
+ if (CA_STATUS_OK != res)
{
- CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
- goto error_exit;
- }
+ OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
+ goto error_exit;
}
}
else
{
- res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE);
+ res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
+ g_deviceStateList, g_deviceStateListMutex);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
+ OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
goto error_exit;
}
}
+#ifdef SCAN_INTERVAL
+ // reset interval scan logic
+ CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
+#endif
+
OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
(*env)->ReleaseStringUTFChars(env, jni_address, address);
return;
const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
if (!address)
{
+ CACheckJNIException(env);
goto error_exit;
}
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
- ca_mutex_lock(g_threadWriteCharacteristicMutex);
+ oc_mutex_lock(g_threadWriteCharacteristicMutex);
g_isSignalSetFlag = true;
- ca_cond_signal(g_threadWriteCharacteristicCond);
- ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+ oc_cond_signal(g_threadWriteCharacteristicCond);
+ oc_mutex_unlock(g_threadWriteCharacteristicMutex);
- CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
- STATE_SEND_FAIL);
+ CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+ STATE_SEND_FAIL,
+ g_deviceStateList,
+ g_deviceStateListMutex);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
}
if (g_clientErrorCallback)
{
jint length = (*env)->GetArrayLength(env, data);
+ CACheckJNIException(env);
g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
+ CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
+ false, "writeChar failure");
}
(*env)->ReleaseStringUTFChars(env, jni_address, address);
else
{
OIC_LOG(DEBUG, TAG, "send success");
- CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
- STATE_SEND_SUCCESS);
+ CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+ STATE_SEND_SUCCESS,
+ g_deviceStateList,
+ g_deviceStateListMutex);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
}
- ca_mutex_lock(g_threadWriteCharacteristicMutex);
+ oc_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);
+ oc_cond_signal(g_threadWriteCharacteristicCond);
+ oc_mutex_unlock(g_threadWriteCharacteristicMutex);
- CALEClientUpdateSendCnt(env);
+ CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
+ (*env)->GetArrayLength(env, data),
+ true, "writeChar success");
}
(*env)->ReleaseStringUTFChars(env, jni_address, address);
Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
{
- OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
+ OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
VERIFY_NON_NULL_VOID(env, TAG, "env is null");
VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
jboolean isCopy;
jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
-
- OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
- jni_byte_responseData);
+ CACheckJNIException(env);
uint8_t* receivedData = OICMalloc(length);
if (!receivedData)
if (!address)
{
OIC_LOG(ERROR, TAG, "address is null");
+ CACheckJNIException(env);
OICFree(receivedData);
return;
}
receivedData, length);
uint32_t sentLength = 0;
- ca_mutex_lock(g_bleServerBDAddressMutex);
+ oc_mutex_lock(g_bleServerBDAddressMutex);
g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
- ca_mutex_unlock(g_bleServerBDAddressMutex);
+ oc_mutex_unlock(g_bleServerBDAddressMutex);
(*env)->ReleaseStringUTFChars(env, jni_address, address);
}
const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
if (!address)
{
+ CACheckJNIException(env);
goto error_exit;
}
- CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
- STATE_SERVICE_CONNECTED);
+ CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
+ STATE_SERVICE_CONNECTED,
+ g_deviceStateList,
+ g_deviceStateListMutex);
(*env)->ReleaseStringUTFChars(env, jni_address, address);
if (CA_STATUS_OK != res)
{
- OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
goto error_exit;
}
- if (g_sendBuffer)
+ res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
+ if (CA_STATUS_OK != res)
{
- CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
- goto error_exit;
- }
+ OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
+ goto error_exit;
}
return;
CALEClientSendFinish(env, gatt);
return;
}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
+ jobject obj,
+ jobject gatt,
+ jint mtu,
+ jint status)
+{
+ OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d, "
+ "mtu[%d-including Header size 3 byte]", status, mtu);
+
+ (void)obj;
+
+ if (0 == status || 133 == status)
+ {
+ if (g_sendBuffer)
+ {
+ CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+ }
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "mtu nego is done");
+ jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+ if (!jni_address)
+ {
+ CALEClientSendFinish(env, gatt);
+ return;
+ }
+
+ const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+ if (!address)
+ {
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_address);
+ CALEClientSendFinish(env, gatt);
+ return;
+ }
+
+ // update mtu size
+ CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
+ g_deviceStateList, g_deviceStateListMutex);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
+ }
+
+ res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+ STATE_SEND_MTU_NEGO_SUCCESS,
+ g_deviceStateList,
+ g_deviceStateListMutex);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
+ }
+ CALEClientUpdateSendCnt(env);
+ (*env)->ReleaseStringUTFChars(env, jni_address, address);
+ (*env)->DeleteLocalRef(env, jni_address);
+ }
+ }
+}