Subscribing to Notifications/Indications

  • You may want to look at this page . It explains how states have changed slightly. Now you just look for the CONNECTED state (that is essentially the old INITIALIZED state). The INITIALIZED state is still there, but it's filtered out from the state events (Filtering was applied to cut down on the amount of posting to the main thread). You can of course change this behavior, by setting the option BleDeviceConfig.defaultDeviceStates (it's an array of BleDeviceState).

    I've always handled notifications/indications the same way. By turning them on in an Init transaction. This way, if the device has to reconnect because android dropped the session for whatever reason, I know the notifications will be re-enabled (plus any other operations that need to be done upon establishing a connection).

    BleManagerConfig config = new BleManagerConfig();
    config.defaultInitFactory = () -> new BleTransaction.Init()
                protected void start()
                    BleNotify notify = new BleNotify(myServiceUuid, myCharUuid)
                            .setNotificationListener((notifyEvent) -> 
                               if (notifyEvent.wasSuccess())
                                   BleRead read = new BleRead(mNameRead);
                                   read.setReadWriteListener((readEvent) ->
                                       if (readEvent.wasSuccess())

  • Okay, that's a neat way of handling it. Presumably we could set a defaultInitFactory for a device config instead of a manager config if we want different default behaviour between different types of device?

    And a ConnectionEvent success should be the same as being in the state CONNECTED then?

    Interestingly though, I seem to get the same behaviour in the v3 toolbox as I do in our app - the device with one indication successfully enables it but gets no data; the other device can't enable indications at all, but can (for some reason) enable the Notify.

  • The key with transactions is to remember to call either succeed() or fail(). Otherwise it will perpetually be in the transaction forever, and nothing will seem to work. You are correct in your assumption about using BleDeviceConfig if you want different behavior from device to device.

    Yes the when the DeviceConnectListener reports a successful connection, the device will be in the CONNECTED state. These changes were made in an effort to make things more intuitive.

    Is there any way you could send us the 2 devices? It will be MUCH easier for us to figure out the problem if we could reproduce it here, and step through code between v2 and v3 to find where they are diverging from one another.

  • Potentially, although I'd like to try a couple of other things first.

    One is using another tablet to act as a peripheral, just to check if it's working.

    The other is using a development board or one of our devices as a simplified test device - something like a single indication which updates every couple of seconds with known data.

    Both of those should be easier to test than our actual devices which expect a timestamp and/or a one-time-key authentication before sending any data.

  • Ok, let me know how it goes. I know that in general, notifications do work, as we've been running V3 in our commercial app for a few months now (granted, we don't have a production case for indications working, but it's really the same process).

  • Okay, I might have something.

    I used the nrfConnect app from Nordic Semiconductor to clone our devices and act as an advertiser and GATT server. These indications work fine as far as I can tell. Still not sure why that's different.

    Going back to our devices, I had another look at the one where subscribing works but no data comes through. I noticed that in the V2 app it writes 0200 to the CCCD to enable indications, but in the V3 app it writes 0100.

    I think that (allowing for different byte order) that corresponds to enabling an indication (0x0002) or a notification (0x0001). So in the simpler one-indication device, I think we receive the value and possibly even start sending data, but android ignores it because we're sending via indicate instead of notify, and it's enabled notify. Or it doesn't match the value we're expecting so we don't start sending data, I'm not 100% sure. Then in the other device with multiple indications we're using a different radio chip, which I suspect rejects the notify enable completely and we get the GATT_NO_RESOURCES error.

    So if I can set the CCCD value for sweetblue to write, it should all work, I think.

  • Just to confirm, when I connect the V2 app to nrfConnect and enable an notifications on an indication I get an '"Indications enabled" received' message on the logger, but when I do the same for the V3 app, I get a '"Notifications enabled" received' message. However in both cases the nrfConnect app can then send an indication through to the sweetblue apps.

    So presumably for whatever reason our "real" devices behave differently and expect an "Indications enabled" instead of a "Notifications enabled" even though other than the value of 1 or 2 the messages are effectively the same.

  • Ok I'll look into it. Someone else mentioned the 1 versus 2 being sent for indications. It's strange as the logic to decide which one to send hasn't changed, but there must be a glitch in there somewhere. Thanks for digging in for more info.

  • So I found the issue. Well, the issue where the library is sending the wrong value when enabling indications. I'm prepping to release a hotfix version (3.0.1) to fix this issue. It should be release within the next 2 days.

  • Excellent news, thank you!