Fix ios ble close issue

 we see iOS app forces ble connection close before weave close  so that
 ios app would not send woble unsubscribe request to close woble
 connection in device.
 In order to fix this issue, we move ble disconnection after woble
 shutdown/close so that unsubcribe can be sent out and further disable
 autoclose when connecting ble so that woble shutdown/close would
 not close ble connection, and app/device manager can close ble
 connection explicitly after close.
diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp
index ff470d3..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.
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];