Explicit disconnect triggers automatic reconnect?



  • Hi, we’ve setup a DefaultDeviceReconnectFilter object to deal with some scenarios but it is sometimes still triggered when we don’t want it to (please note that an explicit disconnect is called and the attemptShortTermReconnect triggers a reconnect.

      1. Shouldn’t the reconnect only be attempted on implicit/soft disconnections?
      1. What triggers a SOFTLY_CANCELLED? It seems to be product of us calling either unbond() or undiscover()

    0_1539881276015_94ba8b21-5edd-4a79-a6ec-3996920d74dc-image.png

    (We’re disconnecting, then scanning and connecting the same device with another UUID.

    1. Would you recomment to rather use the native discover services function?)

    Thanks, all the best!



  • P.S. I’ve tried to set this up before disconnecting and scanning to stop the automatic reconnect but it’s not helping:

            bleManager?.setListener_DeviceReconnect(object: DefaultDeviceReconnectFilter() {
                override fun onConnectionLost(connectionLostEvent: ConnectionLostEvent?): ConnectionLostPlease {
                    return ConnectionLostPlease.stopRetrying()
                }
    
                override fun onConnectFailed(connectionFailEvent: ConnectFailEvent?): ConnectFailPlease {
                    return ConnectFailPlease.doNotRetry()
                }
            })


  • Are you explicitly unbonding? The tryBondingWhileDisconnected flag affects this...if that option is true (which it is by default), then SweetBlue will disconnect to do the unbond. I think there is some weirdness here. So because the library initiated the disconnect, it labels it as being implicit (because, well, it is). So the library then thinks it should reconnect. I think we'll have to add some logic there to take care of this case.

    Could you explain what you mean by "connecting the same device with another UUID"? Is the device's gatt database changing somehow? Do you really need to disconnect?



  • This post is deleted!


  • Yes, I was not sure if calling disconnect() would also unbond() but on the source code on v2 it seemed that the later would end up calling the first one.

    So what is the correct way to disconnect with unbond, without reconnecting and also make the app forget that this device was ever connected?

    Our use case might seem a bit weird, but we're following Cypress' standard process for a firmware-over-the-air update: The hardware peripheral needs to reboot and start its FOTA mode with a special service, thus it will be disconnected and we need to rediscover it with its new service UUID that is now available but was not there before.

    Alternatively I try to skip the disconnect step, since the hardware device reboots it will get disconnected anyway. But if the app is still trying to reconnect, we're pretty much back to the same situation described on this post.

    Any ideas?



  • What we do right now is to call undiscover() (even when the docs state that there's no obvious use case for this function, I think ours is pretty valid), then disconnect() and then only if the device is() is on BOND state, we call unbond().

    The whole process seems utterly complicated for me since we also are reacting to other connection/disconnection issues and this is on top of that. But I've been building this on top of itself as the behavior proved to need more rework.



  • @ryanbis hi, any comments about the issue? Thanks again!



  • Removing all the calls to unbond() from our side does not mitigate the automatic reconnection.



  • I was able to make it work by always keeping the last updated connection state manually:

    I have a BehaviourSubject (or BehaviourRelay) where I track the latest connection state
    I have a boolean flag inside the ReconnectFilter which I switch off and then it returns stopRetrying(), etc before I ask for a disconnect.
    I set a NoReconnectFilter() before asking for a disconnect.
    I call disconnect_remote() and undiscover() when I ask for a disconnect
    I explicitly trigger a STATE_DISCONNECTED on my BehaviourSubject after this, so the rest of the app continues and we get no more notification from sweetblue after this. Firmware update works normally and we recover from this.


  • @caeduk that's a good solution is similar to what we do:

    1. Before switching the device to be in firmware update OTA/DFU mode, we keep track of which device will be put into that mode.
    2. Undiscover the device after the disconnection.
    3. Set the setListener_DeviceReconnect to null.
    4. We only trigger a connection in the DefaultDeviceReconnectFilter if we know that the device is not transitioning into its firmware update mode.


  • @AlejandroHCruz I haven't really been able to unbound without triggering RECONNECTING_SHORT_TERM on the library as a side effect.

    @ryanbis any ideas?



  • @caeduk what is your situation? Are you trying to unbond while connected?



  • Just some info here. SweetBlue initiates an implicit disconnect when you try to unbond when connected. This is to fix a bug which happens on Android where the bond state gets out of sync. The unbond will work, but the reported bond state no longer matches reality. SO, SweetBlue disconnects before unbonding to ensure bond state is as reliable as possible.

    With that said, we need to make the library a little more flexible here. I think we should be able to whip something up for more OTA friendliness.



  • @ryanbis will undiscover() also unbound and disconnect?

    Yes I was trying to unbound() before disconnecting.



  • Undiscover will disconnect, but will not explicitly unbond.