From 1cb38df732d0c5436e78f4e5d36bb6233ac93b54 Mon Sep 17 00:00:00 2001 From: "s.bhuwalka@samsung.com" Date: Fri, 22 Nov 2019 13:24:26 +0530 Subject: [PATCH] Split Android CaleClient in two different files. (#619) caleclient.c is now divided into caleclient.c and caleclient_jni.h Additionally caleclient_utils.h is also added https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/619 (cherry-picked from 6bb06b060dff697c20a13b638c6d6bbcd83a2360) Change-Id: Ia1592b281ef64a293eb7075ea88bf03fd4db7228 Signed-off-by: sourav bhuwalka Signed-off-by: DoHyun Pyun --- .../src/bt_le_adapter/android/SConscript | 3 +- .../src/bt_le_adapter/android/caleclient.c | 648 +------------------- .../src/bt_le_adapter/android/caleclient.h | 10 + .../src/bt_le_adapter/android/caleclient_jni.c | 656 +++++++++++++++++++++ .../src/bt_le_adapter/android/caleclient_utils.h | 40 ++ 5 files changed, 729 insertions(+), 628 deletions(-) create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_jni.c create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_utils.h diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/SConscript b/resource/csdk/connectivity/src/bt_le_adapter/android/SConscript index a12b289..1f68e5b 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/android/SConscript +++ b/resource/csdk/connectivity/src/bt_le_adapter/android/SConscript @@ -11,6 +11,7 @@ src_files = [ 'caleclient.c', 'caleserver.c', 'calenwmonitor.c', 'caleutils.c', - 'calestate.c' ] + 'calestate.c', + 'caleclient_jni.c' ] Return('src_files') diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c index 6207788..ebd8a30 100755 --- a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c @@ -38,6 +38,7 @@ #include "octhread.h" #include "uarraylist.h" #include "org_iotivity_ca_CaLeClientInterface.h" +#include "caleclient_utils.h" //#define TAG PCF("OIC_CA_LE_CLIENT") #define TAG BLE_CLIENT_TAG @@ -68,19 +69,14 @@ static ca_thread_pool_t g_threadPoolHandle = NULL; JavaVM *g_jvm; static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID static u_arraylist_t *g_gattObjectList = NULL; -static u_arraylist_t *g_deviceStateList = NULL; static CAPacketReceiveCallback g_packetReceiveCallback = NULL; -static CABLEErrorHandleCallback g_clientErrorCallback; -static jobject g_leScanCallback = NULL; -static jobject g_leGattCallback = NULL; static jobject g_context = NULL; static jobjectArray g_uuidList = NULL; // it will be prevent to start send logic when adapter has stopped. static bool g_isStartedLEClient = false; -static jbyteArray g_sendBuffer = NULL; static uint32_t g_targetCnt = 0; static uint32_t g_currentSentCnt = 0; static bool g_isFinishedSendData = false; @@ -90,15 +86,9 @@ 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 oc_mutex g_bleServerBDAddressMutex = NULL; static oc_mutex g_deviceListMutex = NULL; static oc_mutex g_gattObjectMutex = NULL; -static oc_mutex g_deviceStateListMutex = NULL; static oc_mutex g_deviceScanRetryDelayMutex = NULL; static oc_cond g_deviceScanRetryDelayCond = NULL; @@ -116,7 +106,6 @@ 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; @@ -131,6 +120,25 @@ static u_arraylist_t* g_serviceUuidList = NULL; // List of Manufacture Data static u_arraylist_t* g_manufactureDataList = NULL; +//Variables are defined as extern in other file so using it as non-static here +u_arraylist_t *g_deviceStateList = NULL; +oc_mutex g_deviceStateListMutex = NULL; + +oc_mutex g_threadWriteCharacteristicMutex = NULL; +oc_cond g_threadWriteCharacteristicCond = NULL; +oc_mutex g_bleServerBDAddressMutex = NULL; + +CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL; + +jobject g_leScanCallback = NULL; +jobject g_leGattCallback = NULL; + +bool g_isSignalSetFlag = false; + +jbyteArray g_sendBuffer = NULL; + +CABLEErrorHandleCallback g_clientErrorCallback = 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. @@ -139,7 +147,7 @@ static u_arraylist_t* g_manufactureDataList = NULL; * @return true - waiting for background connection in BT platform. * false - connection routine has to be stopped. */ -static bool CALECheckConnectionStateValue(jint state) +bool CALECheckConnectionStateValue(jint state) { switch(state) { @@ -4939,617 +4947,3 @@ CAResult_t CAGetLEAddress(char **local_address) VERIFY_NON_NULL(local_address, TAG, "local_address"); return CA_NOT_SUPPORTED; } - -JNIEXPORT void JNICALL -Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj, - jobject callback) -{ - OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback"); - 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 -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 -Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj, - jobject callback) -{ - OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback"); - 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_leGattCallback = (*env)->NewGlobalRef(env, callback); - CACheckJNIException(env); -} - -JNIEXPORT void JNICALL -Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj, - jobject device) -{ - VERIFY_NON_NULL_VOID(env, TAG, "env is null"); - VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); - VERIFY_NON_NULL_VOID(device, TAG, "device is null"); - - CAResult_t res = CALEClientAddScanDeviceToList(env, device); - if (CA_STATUS_OK != res) - { - OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res); - } -} - -JNIEXPORT void JNICALL -Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj, - jint errorCode) -{ - VERIFY_NON_NULL_VOID(env, TAG, "env is null"); - VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); - - switch (errorCode) - { - case 1: - OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED"); - break; - - case 2: - OIC_LOG(ERROR, TAG, - "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED"); - break; - - case 3: - OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR"); - break; - - 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; - } -} - -/* - * Class: org_iotivity_ca_jar_caleinterface - * Method: CALeGattConnectionStateChangeCallback - * Signature: (Landroid/bluetooth/BluetoothGatt;II)V - */ -JNIEXPORT void JNICALL -Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env, - jobject obj, - jobject gatt, - jint status, - jint newstate) -{ - OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status, - newstate); - 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"); - - jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED"); - - jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); - if (!jni_address) - { - OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed"); - goto error_exit; - } - - const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); - if (!address) - { - OIC_LOG(ERROR, TAG, "address is null"); - CACheckJNIException(env); - goto error_exit; - } - OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address); - - if (state_connected == newstate) - { - OIC_LOG(DEBUG, TAG, "LE is connected"); - if (GATT_SUCCESS == status) - { - 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, "CALEUpdateDeviceState has failed"); - goto error_exit; - } - - res = CALEClientAddGattobjToList(env, gatt); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed"); - goto error_exit; - } - - res = CALEClientDiscoverServices(env, gatt); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed"); - goto error_exit; - } - } - else - { - OIC_LOG(INFO, TAG, "unknown status"); - (*env)->ReleaseStringUTFChars(env, jni_address, address); - } - } - else // STATE_DISCONNECTED == newstate - { - OIC_LOG(DEBUG, TAG, "LE is disconnected"); - - 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, "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 (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"); - } - 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; - - // error label. -error_exit: - CALEClientSendFinish(env, gatt); - return; -} - -/* - * Class: org_iotivity_ca_jar_caleinterface - * Method: CALeGattServicesDiscoveredCallback - * Signature: (Landroid/bluetooth/BluetoothGatt;I)V - */ -JNIEXPORT void JNICALL -Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env, - jobject obj, - jobject gatt, - jint status) -{ - OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status); - 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"); - - if (GATT_SUCCESS != status) // discovery error - { - CALEClientSendFinish(env, gatt); - return; - } - - 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); - CALEClientSendFinish(env, gatt); - return; - } - - jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID); - if (!jni_uuid) - { - OIC_LOG(ERROR, TAG, "jni_uuid is null"); - goto error_exit; - } - - jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid); - if (!jni_obj_GattCharacteristic) - { - OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null"); - goto error_exit; - } - - CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt, - jni_obj_GattCharacteristic); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed"); - goto error_exit; - } - - res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic); - if (CA_STATUS_OK != res) - { - OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res); - - res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE, - g_deviceStateList, g_deviceStateListMutex); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed"); - goto error_exit; - } - - res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE, - STATE_SERVICE_CONNECTED, - g_deviceStateList, - g_deviceStateListMutex); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed"); - goto error_exit; - } - - res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed"); - goto error_exit; - } - } - else - { - res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE, - g_deviceStateList, g_deviceStateListMutex); - if (CA_STATUS_OK != res) - { - 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; - - // error label. -error_exit: - OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed"); - (*env)->ReleaseStringUTFChars(env, jni_address, address); - CALEClientSendFinish(env, gatt); - return; -} - -/* - * Class: org_iotivity_ca_jar_caleinterface - * Method: CALeGattCharacteristicWritjclasseCallback - * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V - */ -JNIEXPORT void JNICALL -Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback( - JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status) -{ - OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status); - 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"); - - // send success & signal - jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); - if (!jni_address) - { - goto error_exit; - } - - const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); - if (!address) - { - CACheckJNIException(env); - goto error_exit; - } - - if (GATT_SUCCESS != status) // error case - { - OIC_LOG(ERROR, TAG, "send failure"); - - // retry to write - CAResult_t res = CALEClientWriteCharacteristic(env, gatt); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed"); - oc_mutex_lock(g_threadWriteCharacteristicMutex); - g_isSignalSetFlag = true; - oc_cond_signal(g_threadWriteCharacteristicCond); - oc_mutex_unlock(g_threadWriteCharacteristicMutex); - - 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"); - } - - 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); - goto error_exit; - } - } - else - { - OIC_LOG(DEBUG, TAG, "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, "CALEUpdateDeviceState has failed"); - } - - oc_mutex_lock(g_threadWriteCharacteristicMutex); - OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal"); - g_isSignalSetFlag = true; - oc_cond_signal(g_threadWriteCharacteristicCond); - oc_mutex_unlock(g_threadWriteCharacteristicMutex); - - CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, - (*env)->GetArrayLength(env, data), - true, "writeChar success"); - } - - (*env)->ReleaseStringUTFChars(env, jni_address, address); - return; - - // error label. -error_exit: - - CALEClientSendFinish(env, gatt); - return; -} - -/* - * Class: org_iotivity_ca_jar_caleinterface - * Method: CALeGattCharacteristicChangedCallback - * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V - */ -JNIEXPORT void JNICALL -Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback( - JNIEnv *env, jobject obj, jobject gatt, jbyteArray data) -{ - 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"); - VERIFY_NON_NULL_VOID(data, TAG, "data is null"); - - // get Byte Array and convert to uint8_t* - jint length = (*env)->GetArrayLength(env, data); - - jboolean isCopy; - jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy); - CACheckJNIException(env); - - uint8_t* receivedData = OICMalloc(length); - if (!receivedData) - { - OIC_LOG(ERROR, TAG, "receivedData is null"); - return; - } - - memcpy(receivedData, jni_byte_responseData, length); - (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT); - - jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); - if (!jni_address) - { - OIC_LOG(ERROR, TAG, "jni_address is null"); - OICFree(receivedData); - return; - } - - const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); - if (!address) - { - OIC_LOG(ERROR, TAG, "address is null"); - CACheckJNIException(env); - OICFree(receivedData); - return; - } - - OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d", - receivedData, length); - - uint32_t sentLength = 0; - oc_mutex_lock(g_bleServerBDAddressMutex); - g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength); - oc_mutex_unlock(g_bleServerBDAddressMutex); - - (*env)->ReleaseStringUTFChars(env, jni_address, address); -} - -/* - * Class: org_iotivity_ca_jar_caleinterface - * Method: CALeGattDescriptorWriteCallback - * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V - */ -JNIEXPORT void JNICALL -Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj, - jobject gatt, - jint status) -{ - OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status); - 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"); - - if (GATT_SUCCESS != status) // error - { - goto error_exit; - } - - jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); - if (!jni_address) - { - goto error_exit; - } - - const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); - if (!address) - { - CACheckJNIException(env); - goto error_exit; - } - - 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, "CALEUpdateDeviceState has failed"); - goto error_exit; - } - - res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed"); - goto error_exit; - } - return; - -// error label. -error_exit: - - 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); - } - } -} diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h index f108cea..46d9649 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h +++ b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h @@ -648,6 +648,16 @@ CAResult_t CALEClientStartScanWithInterval(); */ void CALEClientStopScanWithInterval(); +/** + * 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. + * since there is no retry logic for this error reason in this client. + * @param state constant value of bluetoothgatt. + * @return true - waiting for background connection in BT platform. + * false - connection routine has to be stopped. + */ +bool CALECheckConnectionStateValue(jint state); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_jni.c b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_jni.c new file mode 100644 index 0000000..13a1efa --- /dev/null +++ b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_jni.c @@ -0,0 +1,656 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include +#include +#include +#include + +#include "calestate.h" +#include "caleclient.h" +#include "caleserver.h" +#include "caleutils.h" +#include "caleinterface.h" +#include "caadapterutils.h" + +#include "uarraylist.h" +#include "logger.h" +#include "oic_malloc.h" +#include "oic_string.h" +#include "cathreadpool.h" /* for thread pool */ +#include "octhread.h" +#include "uarraylist.h" +#include "org_iotivity_ca_CaLeClientInterface.h" +#include "caleclient_utils.h" +#include "caleclient.h" + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj, + jobject callback) +{ + OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback"); + 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 +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 +Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj, + jobject callback) +{ + OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback"); + 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_leGattCallback = (*env)->NewGlobalRef(env, callback); + CACheckJNIException(env); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj, + jobject device) +{ + VERIFY_NON_NULL_VOID(env, TAG, "env is null"); + VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); + VERIFY_NON_NULL_VOID(device, TAG, "device is null"); + + CAResult_t res = CALEClientAddScanDeviceToList(env, device); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj, + jint errorCode) +{ + VERIFY_NON_NULL_VOID(env, TAG, "env is null"); + VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); + + switch (errorCode) + { + case 1: + OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED"); + break; + + case 2: + OIC_LOG(ERROR, TAG, + "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED"); + break; + + case 3: + OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR"); + break; + + 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; + } +} + +/* + * Class: org_iotivity_ca_jar_caleinterface + * Method: CALeGattConnectionStateChangeCallback + * Signature: (Landroid/bluetooth/BluetoothGatt;II)V + */ +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env, + jobject obj, + jobject gatt, + jint status, + jint newstate) +{ + OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status, + newstate); + 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"); + + jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED"); + + jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); + if (!jni_address) + { + OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed"); + goto error_exit; + } + + const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); + if (!address) + { + OIC_LOG(ERROR, TAG, "address is null"); + CACheckJNIException(env); + goto error_exit; + } + OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address); + + if (state_connected == newstate) + { + OIC_LOG(DEBUG, TAG, "LE is connected"); + if (GATT_SUCCESS == status) + { + 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, "CALEUpdateDeviceState has failed"); + goto error_exit; + } + + res = CALEClientAddGattobjToList(env, gatt); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed"); + goto error_exit; + } + + res = CALEClientDiscoverServices(env, gatt); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed"); + goto error_exit; + } + } + else + { + OIC_LOG(INFO, TAG, "unknown status"); + (*env)->ReleaseStringUTFChars(env, jni_address, address); + } + } + else // STATE_DISCONNECTED == newstate + { + OIC_LOG(DEBUG, TAG, "LE is disconnected"); + + 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, "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 (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"); + } + 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; + + // error label. +error_exit: + CALEClientSendFinish(env, gatt); + return; +} + +/* + * Class: org_iotivity_ca_jar_caleinterface + * Method: CALeGattServicesDiscoveredCallback + * Signature: (Landroid/bluetooth/BluetoothGatt;I)V + */ +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env, + jobject obj, + jobject gatt, + jint status) +{ + OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status); + 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"); + + if (GATT_SUCCESS != status) // discovery error + { + CALEClientSendFinish(env, gatt); + return; + } + + 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); + CALEClientSendFinish(env, gatt); + return; + } + + jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID); + if (!jni_uuid) + { + OIC_LOG(ERROR, TAG, "jni_uuid is null"); + goto error_exit; + } + + jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid); + if (!jni_obj_GattCharacteristic) + { + OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null"); + goto error_exit; + } + + CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt, + jni_obj_GattCharacteristic); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed"); + goto error_exit; + } + + res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res); + + res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE, + g_deviceStateList, g_deviceStateListMutex); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed"); + goto error_exit; + } + + res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE, + STATE_SERVICE_CONNECTED, + g_deviceStateList, + g_deviceStateListMutex); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed"); + goto error_exit; + } + + res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed"); + goto error_exit; + } + } + else + { + res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE, + g_deviceStateList, g_deviceStateListMutex); + if (CA_STATUS_OK != res) + { + 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; + + // error label. +error_exit: + OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed"); + (*env)->ReleaseStringUTFChars(env, jni_address, address); + CALEClientSendFinish(env, gatt); + return; +} + +/* + * Class: org_iotivity_ca_jar_caleinterface + * Method: CALeGattCharacteristicWritjclasseCallback + * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V + */ +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback( + JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status) +{ + OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status); + 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"); + + // send success & signal + jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); + if (!jni_address) + { + goto error_exit; + } + + const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); + if (!address) + { + CACheckJNIException(env); + goto error_exit; + } + + if (GATT_SUCCESS != status) // error case + { + OIC_LOG(ERROR, TAG, "send failure"); + + // retry to write + CAResult_t res = CALEClientWriteCharacteristic(env, gatt); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed"); + oc_mutex_lock(g_threadWriteCharacteristicMutex); + g_isSignalSetFlag = true; + oc_cond_signal(g_threadWriteCharacteristicCond); + oc_mutex_unlock(g_threadWriteCharacteristicMutex); + + 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"); + } + + 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); + goto error_exit; + } + } + else + { + OIC_LOG(DEBUG, TAG, "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, "CALEUpdateDeviceState has failed"); + } + + oc_mutex_lock(g_threadWriteCharacteristicMutex); + OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal"); + g_isSignalSetFlag = true; + oc_cond_signal(g_threadWriteCharacteristicCond); + oc_mutex_unlock(g_threadWriteCharacteristicMutex); + + CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, + (*env)->GetArrayLength(env, data), + true, "writeChar success"); + } + + (*env)->ReleaseStringUTFChars(env, jni_address, address); + return; + + // error label. +error_exit: + + CALEClientSendFinish(env, gatt); + return; +} + +/* + * Class: org_iotivity_ca_jar_caleinterface + * Method: CALeGattCharacteristicChangedCallback + * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V + */ +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback( + JNIEnv *env, jobject obj, jobject gatt, jbyteArray data) +{ + 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"); + VERIFY_NON_NULL_VOID(data, TAG, "data is null"); + + // get Byte Array and convert to uint8_t* + jint length = (*env)->GetArrayLength(env, data); + + jboolean isCopy; + jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy); + CACheckJNIException(env); + + uint8_t* receivedData = OICMalloc(length); + if (!receivedData) + { + OIC_LOG(ERROR, TAG, "receivedData is null"); + return; + } + + memcpy(receivedData, jni_byte_responseData, length); + (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT); + + jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); + if (!jni_address) + { + OIC_LOG(ERROR, TAG, "jni_address is null"); + OICFree(receivedData); + return; + } + + const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); + if (!address) + { + OIC_LOG(ERROR, TAG, "address is null"); + CACheckJNIException(env); + OICFree(receivedData); + return; + } + + OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d", + receivedData, length); + + uint32_t sentLength = 0; + oc_mutex_lock(g_bleServerBDAddressMutex); + g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength); + oc_mutex_unlock(g_bleServerBDAddressMutex); + + (*env)->ReleaseStringUTFChars(env, jni_address, address); +} + +/* + * Class: org_iotivity_ca_jar_caleinterface + * Method: CALeGattDescriptorWriteCallback + * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V + */ +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj, + jobject gatt, + jint status) +{ + OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status); + 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"); + + if (GATT_SUCCESS != status) // error + { + goto error_exit; + } + + jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); + if (!jni_address) + { + goto error_exit; + } + + const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); + if (!address) + { + CACheckJNIException(env); + goto error_exit; + } + + 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, "CALEUpdateDeviceState has failed"); + goto error_exit; + } + + res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed"); + goto error_exit; + } + return; + +// error label. +error_exit: + + 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); + } + } +} diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_utils.h b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_utils.h new file mode 100644 index 0000000..4b5501c --- /dev/null +++ b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_utils.h @@ -0,0 +1,40 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#define TAG BLE_CLIENT_TAG + +extern u_arraylist_t *g_deviceStateList; +extern oc_mutex g_deviceStateListMutex; + +extern oc_mutex g_threadWriteCharacteristicMutex; +extern oc_cond g_threadWriteCharacteristicCond; + +extern oc_mutex g_bleServerBDAddressMutex; + +extern CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback; + +extern jobject g_leScanCallback; +extern jobject g_leGattCallback; + +extern bool g_isSignalSetFlag; + +extern CABLEErrorHandleCallback g_clientErrorCallback; + +extern jbyteArray g_sendBuffer; -- 2.7.4