Fixed a session problem related to BT off/on for Android BLE.
authorjihwan.seo <jihwan.seo@samsung.com>
Wed, 16 Sep 2015 08:23:21 +0000 (17:23 +0900)
committerPatrick Lankswert <patrick.lankswert@intel.com>
Thu, 17 Sep 2015 16:13:26 +0000 (16:13 +0000)
when BT turn off/on while device is connected,
BLE is not connected again.
so i have modified something like in below

- when BLE Disconnect event is called
  server have to start advertising again.
- the dataList of server/client have to destroy, when BT turn off.
- client have to start device scan again, when BT turn on.

Change-Id: I97b75d349a0e3205e221e1347d3f24ca23f4e139
Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2579
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.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/caleserver.h

index 6742cd1..bb622ed 100644 (file)
@@ -82,6 +82,8 @@ static ca_mutex g_deviceListMutex = NULL;
 static ca_mutex g_gattObjectMutex = NULL;
 static ca_mutex g_deviceStateListMutex = NULL;
 
+static ca_mutex g_scanMutex = NULL;
+
 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
 
 //getting jvm
@@ -329,7 +331,7 @@ void CALEClientTerminate()
     }
 
     g_isStartedMulticastServer = false;
-    g_isStartedScan = false;
+    CALEClientSetScanFlag(false);
     CALEClientSetSendFinishFlag(false);
 
     CALEClientTerminateGattMutexVariables();
@@ -1077,7 +1079,7 @@ CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
     else
     {
         OIC_LOG(DEBUG, TAG, "startLeScan is started");
-        g_isStartedScan = true;
+        CALEClientSetScanFlag(true);
     }
 
     return CA_STATUS_OK;
@@ -1142,7 +1144,7 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobj
     else
     {
         OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
-        g_isStartedScan = true;
+        CALEClientSetScanFlag(true);
     }
 
     return CA_STATUS_OK;
@@ -1218,7 +1220,7 @@ CAResult_t CALEClientStopScan()
     }
     else
     {
-        g_isStartedScan = false;
+        CALEClientSetScanFlag(false);
     }
 
     if (isAttached)
@@ -1229,6 +1231,13 @@ CAResult_t CALEClientStopScan()
     return ret;
 }
 
+void CALEClientSetScanFlag(bool flag)
+{
+    ca_mutex_lock(g_scanMutex);
+    g_isStartedScan = flag;
+    ca_mutex_unlock(g_scanMutex);
+}
+
 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
 {
     OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
@@ -3038,6 +3047,16 @@ CAResult_t CALEClientInitGattMutexVaraibles()
         }
     }
 
+    if (NULL == g_scanMutex)
+    {
+        g_scanMutex = ca_mutex_new();
+        if (NULL == g_scanMutex)
+        {
+            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -3064,6 +3083,9 @@ void CALEClientTerminateGattMutexVariables()
     ca_mutex_free(g_SendFinishMutex);
     g_SendFinishMutex = NULL;
 
+    ca_mutex_free(g_scanMutex);
+    g_scanMutex = NULL;
+
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -3294,70 +3316,47 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J
             goto error_exit;
         }
     }
-    else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
+    else // le disconnected
     {
         CAResult_t res = CALEClientStartScan();
         if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+            goto error_exit;
         }
 
         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)
         {
-            res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
-                                              STATE_CHARACTER_NO_CHANGE,
-                                              STATE_SEND_NONE);
+            res = CALEClientRemoveDeviceState(address);
             if (CA_STATUS_OK != res)
             {
-                OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+                OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
+                goto error_exit;
             }
-            (*env)->ReleaseStringUTFChars(env, jni_address, address);
-        }
-
-        res = CALEClientGattClose(env, gatt);
-        if (CA_STATUS_OK != res)
-        {
-            OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
-        }
-    }
-    else // error
-    {
-        // update state
-        jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
-        if (!jni_address)
-        {
-            OIC_LOG(ERROR, TAG, "jni_address is null");
-            goto error_exit;
 
-        }
-
-        const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
-        if (address)
-        {
-            CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
-                                                         STATE_CHARACTER_NO_CHANGE,
-                                                         STATE_SEND_FAILED);
+            res = CALEClientRemoveGattObjForAddr(env, jni_address);
             if (CA_STATUS_OK != res)
             {
-                OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+                OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
+                goto error_exit;
             }
+
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
         }
-        (*env)->ReleaseStringUTFChars(env, jni_address, address);
 
-        CAResult_t res = CALEClientGattClose(env, gatt);
+        res = CALEClientGattClose(env, gatt);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
         }
-
-        goto error_exit;
     }
     return;
 
index 708a1c5..df53c3d 100644 (file)
@@ -244,6 +244,12 @@ jobject CALEClientGetUUIDObject(JNIEnv *env, const char *uuid);
 CAResult_t CALEClientStopScan();
 
 /**
+ * set ble scanning flag.
+ * @param[in]   flag        scan flag.
+ */
+void CALEClientSetScanFlag(bool flag);
+
+/**
  * stop scan (implement).
  * @param[in]   env                   JNI interface pointer.
  * @param[in]   callback              callback to receive device object by scanning.
index ac074d1..c9c6a9b 100644 (file)
@@ -226,6 +226,21 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
     if (BT_STATE_ON == status) // STATE_ON:12
     {
         CANetworkStatus_t newStatus = CA_INTERFACE_UP;
+        CALEClientCreateDeviceList();
+        CALEServerCreateCachedDeviceList();
+
+        CAResult_t res = CALEClientStartScan();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        }
+
+        res = CALEStartAdvertise();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEStartAdvertise has failed");
+        }
+
         gCALEDeviceStateChangedCallback(newStatus);
     }
     else if (BT_STATE_OFF == status) // STATE_OFF:10
@@ -243,6 +258,12 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
             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
         res = CALEServerRemoveAllDevices(env);
         if (CA_STATUS_OK != res)
@@ -250,6 +271,8 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
             OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
         }
 
+        CALEClientSetScanFlag(false);
+
         CANetworkStatus_t newStatus = CA_INTERFACE_DOWN;
         gCALEDeviceStateChangedCallback(newStatus);
     }
index 8f8ec34..916b94f 100644 (file)
@@ -345,6 +345,44 @@ CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, j
     return CA_STATUS_OK;
 }
 
+CAResult_t CALEStartAdvertise()
+{
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    bool isAttached = false;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
+        }
+        isAttached = true;
+    }
+
+    // start advertise
+    CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+    return ret;
+}
+
 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
 {
     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
@@ -1459,7 +1497,13 @@ void CALEServerTerminate()
         isAttached = true;
     }
 
-    CAResult_t ret = CALEServerStopMulticastServer(0);
+    CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
+    }
+
+    ret = CALEServerStopMulticastServer(0);
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
@@ -2136,10 +2180,19 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCall
     else if (newState == jni_int_state_disconnected)
     {
         OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
-        CAResult_t res = CALEServerGattClose(env, g_bluetoothGattServer);
-        if (CA_STATUS_OK != res)
+
+        jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
+        CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
+        }
+
+        // start advertise
+        ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
+        if (CA_STATUS_OK != ret)
         {
-            OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
+            OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
         }
     }
     else
@@ -2261,8 +2314,7 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEn
     VERIFY_NON_NULL_VOID(env, TAG, "env");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
 
-    OIC_LOG_V(ERROR, TAG, "LE Advertise Start Failure Callback(%d)",
-              errorCode);
+    OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
 }
 
 /**
index 48484b5..46d6b51 100644 (file)
@@ -129,6 +129,11 @@ CAResult_t CALEServerCreateJniInterfaceObject();
 
 /**
  * start advertise in gatt server.
+ */
+CAResult_t CALEStartAdvertise();
+
+/**
+ * start advertise in gatt server.
  * @param[in]   env                JNI interface pointer.
  * @param[in]   advertiseCallback  callback to be notified on reception of
  *                                 advertisement result.