Merge pull request #649 from openweave/bug/improve_ble_endpoint_close

Improve woble connection close
diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp
index cb437dc..783f0fe 100644
--- a/src/ble/BLEEndPoint.cpp
+++ b/src/ble/BLEEndPoint.cpp
@@ -407,6 +407,7 @@
             StopAckReceivedTimer();
             StopSendAckTimer();
 
+            WeaveLogProgress(Ble, "BLEEndPoint::FinalizeClose will call UnsubscribeCharacteristic");
             // Indicate close of WeaveConnection to peripheral via GATT unsubscribe. Keep end point allocated until
             // unsubscribe completes or times out, so platform doesn't close underlying BLE connection before
             // we're really sure the unsubscribe request has been sent.
@@ -419,17 +420,8 @@
             }
             else if (mConnObj != BLE_CONNECTION_UNINITIALIZED)
             {
-                // Unsubscribe request was sent successfully, and a confirmation wasn't spontaneously generated or
-                // received in the downcall to UnsubscribeCharacteristic, so set timer for the unsubscribe to complete.
-                err = StartUnsubscribeTimer();
-
-                if (err != BLE_NO_ERROR)
-                {
-                    Free();
-                }
-
-                // Mark unsubscribe GATT operation in progress.
-                SetFlag(mConnStateFlags, kConnState_GattOperationInFlight, true);
+                //Force to free endpoint's BLE connection
+                Free();
             }
         }
         else // mRole == kBleRole_Peripheral, OR GetFlag(mTimerStateFlags, kConnState_DidBeginSubscribe) == false...
diff --git a/src/device-manager/WeaveDeviceManager.h b/src/device-manager/WeaveDeviceManager.h
index 95d97e4..99c23cc 100644
--- a/src/device-manager/WeaveDeviceManager.h
+++ b/src/device-manager/WeaveDeviceManager.h
@@ -136,11 +136,11 @@
     WEAVE_ERROR PassiveRendezvousDevice(const uint8_t *accessToken, uint32_t accessTokenLen, void *appReqState, CompleteFunct onComplete, ErrorFunct onError);
 #if CONFIG_NETWORK_LAYER_BLE
     WEAVE_ERROR ConnectBle(BLE_CONNECTION_OBJECT connObj,
-        void *appReqState, CompleteFunct onComplete, ErrorFunct onError, bool autoClose = true);
+        void *appReqState, CompleteFunct onComplete, ErrorFunct onError, bool autoClose = false);
     WEAVE_ERROR ConnectBle(BLE_CONNECTION_OBJECT connObj, const char *pairingCode,
-        void *appReqState, CompleteFunct onComplete, ErrorFunct onError, bool autoClose = true);
+        void *appReqState, CompleteFunct onComplete, ErrorFunct onError, bool autoClose = false);
     WEAVE_ERROR ConnectBle(BLE_CONNECTION_OBJECT connObj, const uint8_t *accessToken, uint32_t accessTokenLen,
-        void *appReqState, CompleteFunct onComplete, ErrorFunct onError, bool autoClose = true);
+        void *appReqState, CompleteFunct onComplete, ErrorFunct onError, bool autoClose = false);
 #endif // CONFIG_NETWORK_LAYER_BLE
 
     // ----- Remote Passive Rendezvous -----
diff --git a/src/device-manager/cocoa/NLWeaveBleDelegate.mm b/src/device-manager/cocoa/NLWeaveBleDelegate.mm
index 8acb5d2..56e8a37 100644
--- a/src/device-manager/cocoa/NLWeaveBleDelegate.mm
+++ b/src/device-manager/cocoa/NLWeaveBleDelegate.mm
@@ -145,6 +145,7 @@
             characteristic = [CBUUID UUIDWithData:[NSData dataWithBytes:charId->bytes length:sizeof(charId->bytes)]];
         }
 
+        WDM_LOG_DEBUG(@"Calling BleDelegateTrampoline::UnsubscribeCharacteristic\n");
         result = [mBleDelegate UnsubscribeCharacteristic:(__bridge id) connObj serivce:service characteristic:characteristic];
 
     exit:
@@ -488,6 +489,7 @@
 {
     WDM_LOG_METHOD_SIG();
 
+    WDM_LOG_DEBUG(@"forceBleDisconnect_Sync is called");
     // force BleLayer to forget about this connObj
     _mBleLayer->HandleConnectionError((__bridge void *) peripheral, BLE_ERROR_REMOTE_DEVICE_DISCONNECTED);
 }
diff --git a/src/device-manager/cocoa/NLWeaveDeviceManager.mm b/src/device-manager/cocoa/NLWeaveDeviceManager.mm
index bec3ece..6f1d3ac 100644
--- a/src/device-manager/cocoa/NLWeaveDeviceManager.mm
+++ b/src/device-manager/cocoa/NLWeaveDeviceManager.mm
@@ -248,15 +248,21 @@
     if (_mWeaveCppDM) {
         WDM_LOG_ERROR(@"Shutdown C++ Weave Device Manager");
 
-        if (_blePeripheral) {
-            // this is a hack to avoid further callback from BleLayer after closign
-            [[[NLWeaveStack sharedStack] BleDelegate] forceBleDisconnect_Sync:_blePeripheral];
-        }
-
         _mWeaveCppDM->Shutdown();
 
         delete _mWeaveCppDM;
         _mWeaveCppDM = NULL;
+
+        if (_blePeripheral)
+        {
+            // autoclose is disabled when running weave connect ble, close ble after woble stack is
+            // destroyed
+            // release reference to the CBPeripheral
+            // since device manager is the only one who holds a strong reference to this peripheral,
+            // releasing it here cause immediate destruction and hence disconnection
+            [[[NLWeaveStack sharedStack] BleDelegate] forceBleDisconnect_Sync:_blePeripheral];
+            _blePeripheral = nil;
+        }
     }
 
     [self DispatchAsyncCompletionBlock:nil];
@@ -299,21 +305,22 @@
         }
 
         if (IsOKay) {
-            if (_blePeripheral) {
-                // this is a hack to avoid further callback from BleLayer after closign
-                [[[NLWeaveStack sharedStack] BleDelegate] forceBleDisconnect_Sync:_blePeripheral];
+            // Note that we're already in Weave work queue, which means all callbacks for the previous or current request
+            // has either happened/completed or would be canceled by this call to Close. Therefore, it should be safe
+            // to wipe out request context variables like _mRequestName and _mCompletionHandler.
 
+            _mWeaveCppDM->Close();
+
+            if (_blePeripheral) {
+                [[[NLWeaveStack sharedStack] BleDelegate] forceBleDisconnect_Sync:_blePeripheral];
+                // autoclose is disabled when running weave connect ble, close ble after woble stack is
+                // destroyed
                 // release reference to the CBPeripheral
                 // since device manager is the only one who holds a strong reference to this peripheral,
                 // releasing it here cause immediate destruction and hence disconnection
                 _blePeripheral = nil;
             }
 
-            // Note that we're already in Weave work queue, which means all callbacks for the previous or current request
-            // has either happened/completed or would be canceled by this call to Close. Therefore, it should be safe
-            // to wipe out request context variables like _mRequestName and _mCompletionHandler.
-            _mWeaveCppDM->Close();
-
             _mRequestName = taskName;
             _mCompletionHandler = completionHandler;
             [self DispatchAsyncCompletionBlock:nil];