Split Android CaleClient in two different files. (#619) 98/218798/1
authors.bhuwalka@samsung.com <s.bhuwalka@samsung.com>
Fri, 22 Nov 2019 07:54:26 +0000 (13:24 +0530)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Thu, 28 Nov 2019 07:27:37 +0000 (16:27 +0900)
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 <s.bhuwalka@samsung.com>
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
resource/csdk/connectivity/src/bt_le_adapter/android/SConscript
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_jni.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient_utils.h [new file with mode: 0644]

index a12b289..1f68e5b 100644 (file)
@@ -11,6 +11,7 @@ src_files = [ 'caleclient.c',
               'caleserver.c',
               'calenwmonitor.c',
               'caleutils.c',
-              'calestate.c' ]
+              'calestate.c',
+              'caleclient_jni.c' ]
 
 Return('src_files')
index 6207788..ebd8a30 100755 (executable)
@@ -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);
-        }
-    }
-}
index f108cea..46d9649 100644 (file)
@@ -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 (file)
index 0000000..13a1efa
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <jni.h>
+#include <unistd.h>
+
+#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 (file)
index 0000000..4b5501c
--- /dev/null
@@ -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;