clean up android ble implement code
authorjihwan.seo <jihwan.seo@samsung.com>
Wed, 17 Feb 2016 06:27:18 +0000 (15:27 +0900)
committerJon A. Cruz <jonc@osg.samsung.com>
Thu, 18 Feb 2016 19:07:26 +0000 (19:07 +0000)
Change-Id: I0123497c72b28d78e208da013267b6f0e949396c
Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/5017
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jonc@osg.samsung.com>
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/calenwmonitor.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.h

index 25f036d..4d824ee 100644 (file)
 #define MICROSECS_PER_SEC 1000000
 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
 
-static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
-static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
-static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
-static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
-
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
 JavaVM *g_jvm;
@@ -927,32 +922,58 @@ CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
     VERIFY_NON_NULL(device, TAG, "device is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    jstring jni_address = CALEGetAddressFromBTDevice(env, device);
-    if (!jni_address)
+    // get BLE address from bluetooth device object.
+    char* address = NULL;
+    CALEState_t* state = NULL;
+    jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
+    if (jni_address)
     {
-        OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
-        return CA_STATUS_FAILED;
-    }
-
-    const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
-    if (!address)
-    {
-        OIC_LOG(ERROR, TAG, "address is not available");
-        return CA_STATUS_FAILED;
+        OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
+        address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
+        if (!address)
+        {
+            OIC_LOG(ERROR, TAG, "address is not available");
+            return CA_STATUS_FAILED;
+        }
+        ca_mutex_lock(g_deviceStateListMutex);
+        state = CALEClientGetStateInfo(address);
+        ca_mutex_unlock(g_deviceStateListMutex);
+        (*env)->ReleaseStringUTFChars(env, jni_address, address);
     }
 
-    ca_mutex_lock(g_deviceStateListMutex);
-    CALEState_t* state = CALEClientGetStateInfo(address);
-    ca_mutex_unlock(g_deviceStateListMutex);
     if (!state)
     {
         OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
-        CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
-        if (CA_STATUS_OK != ret)
+
+        // cancel previous connection request before connection
+        // if there is gatt object in g_gattObjectList.
+        if (jni_address)
         {
-            OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
+            address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
+            if (!address)
+            {
+                OIC_LOG(ERROR, TAG, "address is not available");
+                return CA_STATUS_FAILED;
+            }
+
+            jobject gatt = CALEClientGetGattObjInList(env, address);
+            if (gatt)
+            {
+                CAResult_t res = CALEClientDisconnect(env, gatt);
+                if (CA_STATUS_OK != res)
+                {
+                    OIC_LOG(INFO, TAG, "there is no gatt object");
+                }
+            }
             (*env)->ReleaseStringUTFChars(env, jni_address, address);
-            return ret;
+        }
+
+        // connection request
+        jobject newGatt = CALEClientConnect(env, device, JNI_TRUE);
+        if (NULL == newGatt)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
+            return CA_STATUS_FAILED;
         }
     }
     else
@@ -960,6 +981,19 @@ CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
         if (STATE_CONNECTED == state->connectedState)
         {
             OIC_LOG(INFO, TAG, "GATT has already connected");
+            if (!jni_address)
+            {
+                OIC_LOG(ERROR, TAG, "jni_address is not available");
+                return CA_STATUS_FAILED;
+            }
+
+            address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
+            if (!address)
+            {
+                OIC_LOG(ERROR, TAG, "address is not available");
+                return CA_STATUS_FAILED;
+            }
+
             jobject gatt = CALEClientGetGattObjInList(env, address);
             if (!gatt)
             {
@@ -975,21 +1009,20 @@ CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
                 return ret;
             }
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
         }
         else
         {
             OIC_LOG(DEBUG, TAG, "start to connect LE");
-            CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
-            if (CA_STATUS_OK != ret)
+            jobject gatt = CALEClientConnect(env, device, JNI_TRUE);
+            if (NULL == gatt)
             {
                 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
-                (*env)->ReleaseStringUTFChars(env, jni_address, address);
-                return ret;
+                return CA_STATUS_FAILED;
             }
         }
     }
 
-    (*env)->ReleaseStringUTFChars(env, jni_address, address);
     return CA_STATUS_OK;
 }
 
@@ -1121,17 +1154,20 @@ CAResult_t CALEClientStartScan()
     {
 #ifdef UUID_SCAN
         ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
-        if(CA_STATUS_OK != ret)
-        {
-            OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
-        }
 #else
         ret = CALEClientStartScanImpl(env, g_leScanCallback);
+#endif
         if (CA_STATUS_OK != ret)
         {
-            OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
+            if (CA_ADAPTER_NOT_ENABLED == ret)
+            {
+                OIC_LOG(DEBUG, TAG, "Adapter is disabled");
+            }
+            else
+            {
+                OIC_LOG(ERROR, TAG, "start scan has failed");
+            }
         }
-#endif
     }
 
     if (isAttached)
@@ -1149,7 +1185,7 @@ CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
@@ -1215,7 +1251,7 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobj
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
@@ -1338,7 +1374,14 @@ CAResult_t CALEClientStopScan()
     CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
     if (CA_STATUS_OK != ret)
     {
-        OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
+        if (CA_ADAPTER_NOT_ENABLED == ret)
+        {
+            OIC_LOG(DEBUG, TAG, "Adapter is disabled");
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
+        }
     }
     else
     {
@@ -1368,7 +1411,7 @@ CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
@@ -1423,25 +1466,82 @@ CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
     return CA_STATUS_OK;
 }
 
-CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
-                             jobject callback)
+jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientConnect");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
+
+    // get gatt object from Bluetooth Device object for closeProfileProxy(..)
+    jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
+    if (jni_address)
+    {
+        const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+        if (!address)
+        {
+            OIC_LOG(ERROR, TAG, "address is not available");
+            return NULL;
+        }
+
+        // close the gatt service
+        jobject gatt = CALEClientGetGattObjInList(env, address);
+        if (gatt)
+        {
+            CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
+                (*env)->ReleaseStringUTFChars(env, jni_address, address);
+                return NULL;
+            }
+
+            // clean previous gatt object after close profile service
+            res = CALEClientRemoveGattObjForAddr(env, jni_address);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
+                (*env)->ReleaseStringUTFChars(env, jni_address, address);
+                return NULL;
+            }
+        }
+        (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    }
+
+    jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
+    if (!newGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "re-connection will be started");
+        return NULL;
+    }
+
+    // add new gatt object into g_gattObjectList
+    CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
+        return NULL;
+    }
+
+    return newGatt;
+}
+
+jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
 {
     OIC_LOG(DEBUG, TAG, "GATT CONNECT");
-    VERIFY_NON_NULL(env, TAG, "env is null");
-    VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
-    VERIFY_NON_NULL(callback, TAG, "callback is null");
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
-        return CA_ADAPTER_NOT_ENABLED;
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return NULL;
     }
 
     jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
     if (!jni_address)
     {
         OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
-        return CA_STATUS_FAILED;
+        return NULL;
     }
 
     // get BluetoothDevice class
@@ -1450,7 +1550,7 @@ CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean auto
     if (!jni_cid_BluetoothDevice)
     {
         OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
-        return CA_STATUS_FAILED;
+        return NULL;
     }
 
     // get connectGatt method
@@ -1462,40 +1562,111 @@ CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean auto
     if (!jni_mid_connectGatt)
     {
         OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
-        return CA_STATUS_FAILED;
+        return NULL;
     }
 
-    OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
+    OIC_LOG(INFO, TAG, "CALL API - connectGatt");
     jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
                                                            jni_mid_connectGatt,
                                                            NULL,
-                                                           autoconnect, callback);
+                                                           autoconnect, g_leGattCallback);
     if (!jni_obj_connectGatt)
     {
-        OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
+        OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
         CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
         CALEClientUpdateSendCnt(env);
-        return CA_STATUS_FAILED;
+        return NULL;
     }
     else
     {
         OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
     }
+    return jni_obj_connectGatt;
+}
+
+CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
+
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(gatt, TAG, "gatt is null");
+
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
+        return CA_STATUS_FAILED;
+    }
+
+    // get remote bt adapter method
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                                                    "getDefaultAdapter",
+                                                                    METHODID_OBJECTNONPARAM);
+    if (!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        return CA_STATUS_FAILED;
+    }
+
+    // gat bt adapter object
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
+                                                               jni_mid_getDefaultAdapter);
+    if (!jni_obj_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        return CA_STATUS_FAILED;
+    }
+
+    // get closeProfileProxy method
+    jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+                                                              "closeProfileProxy",
+                                                              "(ILandroid/bluetooth/"
+                                                              "BluetoothProfile;)V");
+    if (!jni_mid_closeProfileProxy)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
+    if (!jni_cid_BTProfile)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
+        return CA_STATUS_FAILED;
+    }
+
+    // GATT - Constant value : 7 (0x00000007)
+    jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
+                                                "GATT", "I");
+    if (!id_gatt)
+    {
+        OIC_LOG(ERROR, TAG, "id_gatt is null");
+        return CA_STATUS_FAILED;
+    }
+
+    jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
+
+    OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
+    (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
     return CA_STATUS_OK;
 }
 
+
 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
 {
     OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
 
-    if (!CALEIsEnableBTAdapter(env))
-    {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
     // get BluetoothGatt class
     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
     if (!jni_cid_BluetoothGatt)
@@ -1514,6 +1685,7 @@ CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
     }
 
     // call disconnect gatt method
+    OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
     if ((*env)->ExceptionCheck(env))
     {
@@ -1535,13 +1707,15 @@ CAResult_t CALEClientDisconnectAll(JNIEnv *env)
 
     if (!g_gattObjectList)
     {
-        OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
-        return CA_STATUS_FAILED;
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
+        return CA_STATUS_OK;
     }
 
     uint32_t length = u_arraylist_length(g_gattObjectList);
+    OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
     for (uint32_t index = 0; index < length; index++)
     {
+        OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
         if (!jarrayObj)
         {
@@ -1556,9 +1730,73 @@ CAResult_t CALEClientDisconnectAll(JNIEnv *env)
         }
     }
 
-    OICFree(g_gattObjectList);
-    g_gattObjectList = NULL;
+    return CA_STATUS_OK;
+}
 
+CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
+        return CA_STATUS_OK;
+    }
+
+    char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is null");
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
+        if (!jarrayObj)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            continue;
+        }
+
+        jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
+        if (!jni_setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "jni_setAddress is null");
+            (*env)->ReleaseStringUTFChars(env, remote_address, address);
+            return CA_STATUS_FAILED;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            (*env)->ReleaseStringUTFChars(env, remote_address, address);
+            return CA_STATUS_FAILED;
+        }
+
+        OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
+        if (!strcmp(address, setAddress))
+        {
+            CAResult_t res = CALEClientDisconnect(env, jarrayObj);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
+                (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+                (*env)->ReleaseStringUTFChars(env, remote_address, address);
+                return CA_STATUS_FAILED;
+            }
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            (*env)->ReleaseStringUTFChars(env, remote_address, address);
+            return CA_STATUS_OK;
+        }
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+    }
+    (*env)->ReleaseStringUTFChars(env, remote_address, address);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
     return CA_STATUS_OK;
 }
 
@@ -1569,7 +1807,7 @@ CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
@@ -1604,7 +1842,7 @@ CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
 
 static void CALEWriteCharacteristicThread(void* object)
 {
-    VERIFY_NON_NULL(object, TAG, "object is null");
+    VERIFY_NON_NULL_VOID(object, TAG, "object is null");
 
     bool isAttached = false;
     JNIEnv* env;
@@ -1707,7 +1945,7 @@ CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return CA_STATUS_FAILED;
     }
 
@@ -1756,7 +1994,7 @@ CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return CA_STATUS_FAILED;
     }
 
@@ -1818,7 +2056,7 @@ CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoot
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
@@ -1865,7 +2103,7 @@ jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring cha
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
@@ -1958,7 +2196,7 @@ jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, j
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
@@ -2037,7 +2275,7 @@ jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteris
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return NULL;
     }
 
@@ -2140,7 +2378,7 @@ CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
 
     if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
         return CA_ADAPTER_NOT_ENABLED;
     }
 
@@ -2303,7 +2541,7 @@ CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
         jobject gdevice = (*env)->NewGlobalRef(env, device);
         u_arraylist_add(g_deviceList, gdevice);
         ca_cond_signal(g_deviceDescCond);
-        OIC_LOG_V(DEBUG, TAG, "Added this Device[%s] in the List", remoteAddress);
+        OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
     }
     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
 
@@ -2477,12 +2715,19 @@ CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
 
 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
 {
-    OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
+    OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL(gatt, TAG, "gatt is null");
 
     ca_mutex_lock(g_gattObjectMutex);
 
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
+        ca_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_FAILED;
+    }
+
     jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
     if (!jni_remoteAddress)
     {
@@ -2499,11 +2744,12 @@ CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
         return CA_STATUS_FAILED;
     }
 
+    OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
     if (!CALEClientIsGattObjInList(env, remoteAddress))
     {
         jobject newGatt = (*env)->NewGlobalRef(env, gatt);
         u_arraylist_add(g_gattObjectList, newGatt);
-        OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
+        OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
     }
 
     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
@@ -2616,9 +2862,9 @@ CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
     ca_mutex_lock(g_gattObjectMutex);
     if (!g_gattObjectList)
     {
-        OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
         ca_mutex_unlock(g_gattObjectMutex);
-        return CA_STATUS_FAILED;
+        return CA_STATUS_OK;
     }
 
     uint32_t length = u_arraylist_length(g_gattObjectList);
@@ -2635,6 +2881,7 @@ CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
 
     OICFree(g_gattObjectList);
     g_gattObjectList = NULL;
+    OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
     ca_mutex_unlock(g_gattObjectMutex);
     return CA_STATUS_OK;
 }
@@ -2648,9 +2895,9 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
     ca_mutex_lock(g_gattObjectMutex);
     if (!g_gattObjectList)
     {
-        OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
         ca_mutex_unlock(g_gattObjectMutex);
-        return CA_STATUS_FAILED;
+        return CA_STATUS_OK;
     }
 
     uint32_t length = u_arraylist_length(g_gattObjectList);
@@ -2732,9 +2979,9 @@ CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
     ca_mutex_lock(g_gattObjectMutex);
     if (!g_gattObjectList)
     {
-        OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
         ca_mutex_unlock(g_gattObjectMutex);
-        return CA_STATUS_FAILED;
+        return CA_STATUS_OK;
     }
 
     uint32_t length = u_arraylist_length(g_gattObjectList);
@@ -2798,6 +3045,109 @@ CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
     return CA_STATUS_FAILED;
 }
 
+jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+    VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
+
+    // get Bluetooth Address
+    jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
+    if (!jni_btTargetAddress)
+    {
+        OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+        return NULL;
+    }
+
+    const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
+    if (!targetAddress)
+    {
+        OIC_LOG(ERROR, TAG, "targetAddress is not available");
+        return NULL;
+    }
+
+    // get method ID of getDevice()
+    jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
+    if (!jni_cid_gattdevice_list)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
+        (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+        return NULL;
+    }
+
+    jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
+                                                      METHODID_BT_DEVICE);
+    if (!jni_mid_getDevice)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
+        (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+        return NULL;
+    }
+
+    size_t length = u_arraylist_length(g_gattObjectList);
+    for (size_t index = 0; index < length; index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
+        if (!jarrayObj)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            return CA_STATUS_FAILED;
+        }
+
+        OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
+        jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
+        if (!jni_obj_device)
+        {
+            OIC_LOG(ERROR, TAG, "jni_obj_device is null");
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            return NULL;
+        }
+
+        jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
+        if (!jni_btAddress)
+        {
+            OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            return NULL;
+        }
+
+        const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
+        if (!btAddress)
+        {
+            OIC_LOG(ERROR, TAG, "btAddress is not available");
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            return NULL;
+        }
+
+        OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
+        OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
+        if (!strcmp(targetAddress, btAddress))
+        {
+            OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
+
+            // get LE address
+            jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
+            if (!jni_LEAddress)
+            {
+                OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
+            }
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
+            (*env)->DeleteLocalRef(env, jni_btAddress);
+            (*env)->DeleteLocalRef(env, jni_obj_device);
+            return jni_LEAddress;
+        }
+        (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
+        (*env)->DeleteLocalRef(env, jni_btAddress);
+        (*env)->DeleteLocalRef(env, jni_obj_device);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
+    return NULL;
+}
+
 /**
  * BT State List
  */
@@ -2866,8 +3216,8 @@ CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
         }
     }
     u_arraylist_add(g_deviceStateList, state); // update new state
-    OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
-              state->connectedState, state->notificationState);
+    OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
+              state->connectedState, state->notificationState, state->address);
 
     ca_mutex_unlock(g_deviceStateListMutex);
     return CA_STATUS_OK;
@@ -2910,7 +3260,7 @@ bool CALEClientIsDeviceInList(const char* remoteAddress)
 
 CAResult_t CALEClientRemoveAllDeviceState()
 {
-    OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
 
     ca_mutex_lock(g_deviceStateListMutex);
     if (!g_deviceStateList)
@@ -2962,20 +3312,22 @@ CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
 
         if (!strcmp(state->address, remoteAddress))
         {
-            OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
-            OICFree(state);
+            OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
 
-            if (NULL == u_arraylist_remove(g_deviceStateList, index))
+            CALEState_t* targetState  = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
+                                                                         index);
+            if (NULL == targetState)
             {
                 OIC_LOG(ERROR, TAG, "List removal failed.");
                 return CA_STATUS_FAILED;
             }
 
+            OICFree(targetState);
             return CA_STATUS_OK;
         }
     }
 
-    return CA_STATUS_FAILED;
+    return CA_STATUS_OK;
 }
 
 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
@@ -2990,6 +3342,8 @@ CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
     }
 
     uint32_t length = u_arraylist_length(g_deviceStateList);
+    OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
+
     for (uint32_t index = 0; index < length; index++)
     {
         CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
@@ -2999,6 +3353,9 @@ CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
             continue;
         }
 
+        OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
+        OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
+
         if (!strcmp(state->address, remoteAddress))
         {
             OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
@@ -3376,6 +3733,7 @@ CAResult_t CAInitializeLEGattClient()
 void CATerminateLEGattClient()
 {
     OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
+    CAStopLEGattClient();
     CALEClientTerminate();
 }
 
@@ -3480,7 +3838,11 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J
     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
 
-    if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
+    jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
+    jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
+    jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
+
+    if (gatt_success == status && state_connected == newstate) // le connected
     {
         jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
         if (!jni_address)
@@ -3500,6 +3862,8 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J
                 (*env)->ReleaseStringUTFChars(env, jni_address, address);
                 goto error_exit;
             }
+            OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
+
             (*env)->ReleaseStringUTFChars(env, jni_address, address);
         }
 
@@ -3517,13 +3881,25 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J
             goto error_exit;
         }
     }
+    else if (GATT_ERROR == status && state_disconnected == newstate)
+    {
+        OIC_LOG(INFO, TAG, "Background connection running.. please wait");
+    }
     else // le disconnected
     {
         CAResult_t res = CALEClientStartScan();
         if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
-            goto error_exit;
+            if (CA_ADAPTER_NOT_ENABLED == res)
+            {
+                // scan will be started with start server when adapter is enabled
+                OIC_LOG(INFO, TAG, "Adapter was disabled");
+            }
+            else
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+                goto error_exit;
+            }
         }
 
         jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
@@ -3543,13 +3919,6 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J
                 goto error_exit;
             }
 
-            res = CALEClientRemoveGattObjForAddr(env, jni_address);
-            if (CA_STATUS_OK != res)
-            {
-                OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
-                goto error_exit;
-            }
-
             (*env)->ReleaseStringUTFChars(env, jni_address, address);
         }
 
@@ -3666,11 +4035,13 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIE
             goto error_exit;
         }
     }
+    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;
@@ -3709,7 +4080,8 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
         goto error_exit;
     }
 
-    if (GATT_SUCCESS != status) // error case
+    jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
+    if (gatt_success != status) // error case
     {
         OIC_LOG(ERROR, TAG, "send failure");
 
index 144da1f..da572c9 100644 (file)
@@ -35,6 +35,8 @@ extern "C"
 {
 #endif
 
+static const uint16_t GATT_ERROR = 133;
+
 static const uint16_t STATE_CHARACTER_SET = 2;
 static const uint16_t STATE_CHARACTER_UNSET = 1;
 static const uint16_t STATE_CHARACTER_NO_CHANGE = 0;
@@ -276,11 +278,9 @@ CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback);
  * @param[in]   autoconnect           whether to directly connect to the remote device(false) or
  *                                     to automatically connect as soon as the remote device
  *                                     becomes available.
- * @param[in]   callback              callback for connection state change.
- * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ * @return  gatt object
  */
-CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
-                             jobject callback);
+jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect);
 
 /**
  * disconnect to gatt server by a target device.
@@ -298,6 +298,14 @@ CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt);
 CAResult_t CALEClientDisconnectAll(JNIEnv *env);
 
 /**
+ * disconnect to gatt server by selected address.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   remoteAddress         remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remoteAddress);
+
+/**
  * start discovery server.
  * @param[in]   env                   JNI interface pointer.
  * @param[in]   bluetoothGatt         Gatt profile object.
@@ -471,6 +479,14 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt);
 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr);
 
 /**
+ * get ble address from Bluetooth device.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   bluetoothDevice       Bluetooth device.
+ * @return  ble address.
+ */
+jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
+
+/**
  * update new state information.
  * @param[in]   address               remote address.
  * @param[in]   connectedState        connection state.
@@ -557,6 +573,23 @@ void CALEClientTerminateGattMutexVariables();
  */
 void CALEClientSetSendFinishFlag(bool flag);
 
+/**
+ * close the connection of the profile proxy to the Service.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   gatt                  gatt profile object.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt);
+
+/**
+ * connect to GATT Server hosted by this device.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   bluetoothDevice       bluetooth device object.
+ * @param[in]   autoconnect           connect as soon as the device becomes avaiable(true).
+ * @return  gatt profile object
+ */
+jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index d4bad5e..ba00403 100644 (file)
@@ -35,9 +35,6 @@
 
 #define TAG PCF("OIC_CA_LE_MONITOR")
 
-#define BT_STATE_ON (12)
-#define BT_STATE_OFF (10)
-
 static JavaVM *g_jvm;
 
 /**
@@ -223,7 +220,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
 
-    OIC_LOG(DEBUG, TAG, "CaLeClientInterface - Network State Changed");
+    OIC_LOG_V(DEBUG, TAG, "CaLeClientInterface - Network State Changed : status(%d)", status);
 
     if (!gCALEDeviceStateChangedCallback)
     {
@@ -231,7 +228,11 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
         return;
     }
 
-    if (BT_STATE_ON == status) // STATE_ON:12
+    jint state_on = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_ON");
+    jint state_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_OFF");
+    jint state_turning_off = CALEGetConstantsValue(env, CLASSPATH_BT_ADAPTER, "STATE_TURNING_OFF");
+
+    if (state_on == status) // STATE_ON:12
     {
         CANetworkStatus_t newStatus = CA_INTERFACE_UP;
         CALEClientCreateDeviceList();
@@ -239,7 +240,13 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
 
         gCALEDeviceStateChangedCallback(newStatus);
     }
-    else if (BT_STATE_OFF == status) // STATE_OFF:10
+    else if (state_turning_off == status) // BT_STATE_TURNING_OFF:13
+    {
+        // gatt Device list will be removed.
+        // so it is need to create list again when adapter is enabled.
+        CAStopLEGattClient();
+    }
+    else if (state_off == status) // STATE_OFF:10
     {
         CALEClientStopMulticastServer();
 
@@ -250,19 +257,13 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
             OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
         }
 
-        res = CALEClientRemoveAllScanDevices(env);
-        if (CA_STATUS_OK != res)
-        {
-            OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
-        }
-
         res = CALEClientRemoveAllDeviceState();
         if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
         }
 
-        // remove obej for server
+        // remove obj for server
         res = CALEServerRemoveAllDevices(env);
         if (CA_STATUS_OK != res)
         {
@@ -285,8 +286,17 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback(JNIEnv *en
     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
     VERIFY_NON_NULL_VOID(addr, TAG, "addr is null");
 
+    // geneally 'addr' parameter will be not ble address, if you didn't bond for BLE.
+    // below logics will be needed when ble pairing is set.
+
+    CAResult_t res = CALEClientDisconnectforAddress(env, addr);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientDisconnectforAddress has failed");
+    }
+
     // remove obj for client
-    CAResult_t res = CALEClientRemoveGattObjForAddr(env, addr);
+    res = CALEClientRemoveGattObjForAddr(env, addr);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "CANativeRemoveGattObjForAddr has failed");
index 5a04a02..7ebd68a 100644 (file)
@@ -2158,38 +2158,13 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCall
     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
     VERIFY_NON_NULL_VOID(device, TAG, "device");
 
-    jclass jni_cid_bluetoothProfile = (*env)->FindClass(env, "android/bluetooth/BluetoothProfile");
-    if (!jni_cid_bluetoothProfile)
-    {
-        OIC_LOG(ERROR, TAG, "jni_cid_bluetoothProfile is null");
-        return;
-    }
-
-    jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
-                                                                "STATE_CONNECTED", "I");
-    if(!jni_fid_state_connected)
-    {
-        OIC_LOG(ERROR, TAG, "jni_fid_state_connected is null");
-        return;
-    }
-
-    jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
-                                                                   "STATE_DISCONNECTED", "I");
-    if(!jni_fid_state_disconnected)
-    {
-        OIC_LOG(ERROR, TAG, "jni_fid_state_disconnected is null");
-        return;
-    }
-
     // STATE_CONNECTED
-    jint jni_int_state_connected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
-                                                             jni_fid_state_connected);
+    jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
 
     // STATE_DISCONNECTED
-    jint jni_int_state_disconnected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
-                                                                jni_fid_state_disconnected);
+    jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
 
-    if (newState == jni_int_state_connected)
+    if (newState == state_connected)
     {
 
         OIC_LOG(DEBUG, TAG, "LE CONNECTED");
@@ -2215,7 +2190,7 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCall
         }
         (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
     }
-    else if (newState == jni_int_state_disconnected)
+    else if (newState == state_disconnected)
     {
         OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
 
@@ -2331,7 +2306,8 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(
     OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
               status);
 
-    if (GATT_SUCCESS != status) // error case
+    jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
+    if (gatt_success != status) // error case
     {
         OIC_LOG(ERROR, TAG, "it will be sent again.");
 
index 3edf551..7c7bcdf 100644 (file)
 
 #include "caleutils.h"
 #include "logger.h"
-#include "oic_malloc.h"
 #include "cathreadpool.h"
 #include "uarraylist.h"
 #include "caadapterutils.h"
 
 #define TAG PCF("OIC_CA_LE_UTILS")
 
-#define METHODID_OBJECTNONPARAM   "()Landroid/bluetooth/BluetoothAdapter;"
-#define METHODID_STRINGNONPARAM   "()Ljava/lang/String;"
-#define CLASSPATH_BT_ADPATER "android/bluetooth/BluetoothAdapter"
-
 jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
 {
     VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
@@ -146,7 +141,7 @@ jobjectArray CALEGetBondedDevices(JNIEnv *env)
 {
     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
 
-    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_cid_BTAdapter is null");
@@ -213,7 +208,7 @@ jint CALEGetBTStateOnInfo(JNIEnv *env)
 {
     VERIFY_NON_NULL_RET(env, TAG, "env is null", -1);
 
-    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getBTStateOnInfo: jni_cid_BTAdapter is null");
@@ -300,7 +295,7 @@ jboolean CALEIsEnableBTAdapter(JNIEnv *env)
 {
     VERIFY_NON_NULL_RET(env, TAG, "env is null", JNI_FALSE);
 
-    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
@@ -368,3 +363,29 @@ jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
 
     return jni_address;
 }
+
+jint CALEGetConstantsValue(JNIEnv *env, const char* classType, const char* name)
+{
+    OIC_LOG(DEBUG, TAG, "CALEGetConstantsValue");
+
+    VERIFY_NON_NULL_RET(env, TAG, "env", -1);
+    VERIFY_NON_NULL_RET(classType, TAG, "classType", -1);
+    VERIFY_NON_NULL_RET(name, TAG, "name", -1);
+
+    jclass jni_cid = (*env)->FindClass(env, classType);
+    if (!jni_cid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid is null");
+        return -1;
+    }
+
+    jfieldID jni_fieldID = (*env)->GetStaticFieldID(env, jni_cid,
+                                                    name, "I");
+    if (!jni_fieldID)
+    {
+        OIC_LOG(ERROR, TAG, "jni_fieldID is null");
+        return -1;
+    }
+
+    return (*env)->GetStaticIntField(env, jni_cid, jni_fieldID);
+}
index 520c80a..371e748 100644 (file)
@@ -42,6 +42,17 @@ static const char OIC_GATT_CHARACTERISTIC_REQUEST_UUID[] = CA_GATT_REQUEST_CHRC_
 static const char OIC_GATT_CHARACTERISTIC_RESPONSE_UUID[] = CA_GATT_RESPONSE_CHRC_UUID;
 static const char OIC_GATT_CHARACTERISTIC_CONFIG_UUID[] = "00002902-0000-1000-8000-00805f9b34fb";
 
+static const char CLASSPATH_BT_PROFILE[] = "android/bluetooth/BluetoothProfile";
+static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
+static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
+static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice";
+static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
+
+
+static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
+static const char METHODID_BT_DEVICE[] = "()Landroid/bluetooth/BluetoothDevice;";
+static const char METHODID_BT_REMOTE_DEVICE[] = "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;";
+
 static const jint GATT_SUCCESS = 0;
 
 static const jint BOND_BONDED = 12;
@@ -123,6 +134,14 @@ jboolean CALEIsEnableBTAdapter(JNIEnv *env);
  */
 jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
 
+/**
+ * get value from selected constants.
+ * @param[in]   env              JNI interface pointer.
+ * @param[in]   classType        class type
+ * @param[in]   name             constants name to get.
+ * @return  remote address.
+ */
+jint CALEGetConstantsValue(JNIEnv *env, const char* classType, const char* name);
 #ifdef __cplusplus
 } /* extern "C" */
 #endif