Device state incorrect after RECONNECTING_LONG_TERM using DefaultDeviceReconnectFilter



  • Hello,

    We are in the process of upgrading to SweetBlue v3 but there seems to be a problem with the device state after the DefaultDeviceReconnectFilter triggers RECONNECTING_LONG_TERM.

    Our test case is as follows:

    1. Connect to device
    2. Pull battery from device so connection is lost
    3. Observe state change CONNECTED=true, RECONNECTING_SHORT_TERM=true
    4. Observe state change CONNECTED=false, DISCONNECTED=true, RECONNECTING_LONG_TERM=true
    5. Turn device back on
    6. SweetBlue correctly connects to the device, our BleTransaction.Init is ran (and it calls succeed) to set up notification subscriptions and at this point we can read/write data from the device and receive notifications

    Yet after all this, the device state seems to be stuck on:

    AUTHENTICATED
    BLE_CONNECTED
    CONNECTING_OVERALL
    DISCONNECTED
    DISCOVERED
    INITIALIZING
    RECONNECTING_LONG_TERM
    SERVICES_DISCOVERED
    UNBONDED
    

    We would expect the device state to go back to CONNECTED at this point, and for RECONNECTING_LONG_TERM to go away but it does not.



  • Thanks for the report, we'll look into it, most likely next week, as we have a holiday this week.



  • Okay, this is super weird.

    The issue persisted all day on our test device. Eventually we suspected it might be related to having a BleTransaction.Init, so we removed ours and instead put that logic in our DeviceStateListener when didEnter CONNECTED. This seemed to resolve the problem!

    However, we later reverted this change to test some more things with the transaction, and the problem hasn't resurfaced since.

    So it seems that for some reason, for a while, SweetBlue wouldn't enter CONNECTED after the transaction succeeded.

    But now we can't replicate the issue with the same code base, so it seems somewhat sporadic.

    Just in case, here's an anonymized version of our BleTransaction.Init:

    public class MyInitTx extends BleTransaction.Init {
        private final UUID SERVICE = UUID.fromString("...");
        private final UUID CHAR = UUID.fromString("...");
    
        @Override
        protected void start() {
    	BleNotify bleNotify = new BleNotify(SERVICE, CHAR);
    	bleNotify.setNotificationListener(new NotificationListener() {
    	    @Override
    	    public void onEvent(NotificationEvent notificationEvent) {
    	        if(notificationEvent.type() != Type.ENABLING_NOTIFICATION) {
    	            return;
    	        }
    
    	        if(notificationEvent.wasSuccess()) {
    	            succeed();
    	        }else{
    	            fail();
    	        }
    	    }
    	});
    
    	ReadWriteListener.ReadWriteEvent notify = enableNotify(bleNotify);
    	if(!notify.isNull()) {
    	    enableNotify(bleNotify);
    	    fail();
    	}
        }
    }
    

    Is this the correct way of writing a transaction?

    We'll continue testing on various devices.



  • Only thing that looks weird to me is within the check of (!notify.isNull()). Looks like you try enabling it again, then immediately fail the transaction. I would just fail in that case. This will close the current session, forcing you to re-connect again. If enabling a notification fails in the field, it's most likely due to something out of your hands, usually bad signal strength. Typically if you get one failure when connected on Bluetooth, the stack doesn't handle it well, and you have to reconnect anyway.



  • Good point regarding the failure, that was a mistake and I've adjusted our code.

    However I don't think that this is relevant to the weirdness we ran into. We stepped through the code with a debugger and that line actually never ran. Instead we wound up within the onEvent callback where wasSuccess() was true, so succeed() did get called.



  • Ok, good to know. Not saying there is no bug, just trying to gather as much info as I can when we have the time to fully test it out and dig deep into the problem.



  • The problem resurfaced this morning on the same device (OnePlus 6, Android Pie 9). It's unclear why, and it went away after clearing the system-wide Bluetooth cache.

    It seems to be related to having an BleTransaction.Init, so for now we've gone back to emulating its behavior after connection.



  • Is that the only phone you're seeing this problem on?



  • Hi Ryan,

    We've just tested on a Galaxy S8 (Android 8.0.0) and a LG Nexus 5X (Android 8.1.0) and got the same problem there.

    However, after a re-read of the javadoc we discovered BleDeviceConfig.autoEnableNotifiesOnReconnect. This defaults to true, and the docs tell us Basically, if you enable notifications in an BleTransaction.Init transaction, then set this to false, as the transaction will run on reconnection.

    Setting this to false seems to help. We'll continue testing, but so far it's looking good.



  • Excellent, please let me know if you still see the problem.