This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

service_changed oddity

Forgive me if there is an obvious answer to this; thanks for your patience.

I'm a long time developer but new to the area of BT in general. After a day or so starting with the examples within the 10.0 SDK, and using SD 110 V8 cleanly unzipped, I've run into a bit of a challenge.

To cut to the chase, the problem seems to be related to "handle confusion" that occurs when the service_changed flag is enabled in the gatts_enable_params.

I've reduced this to a repro outside my app. Start with a cleanly-building cleanly working "uart" example app from the SDK, and verify that it works with nRF Toolbox's UART module. (In my case I'm monitoring the serial port I/O of a RedBear Nano.) Great.

Then, at the top of main.c in the uart example, change IS_SRVC_CHANGED_CHARACT_PRESENT to 1, and rebuild. The UART app will no longer function. No serial output.

(Interestingly, though, when I use the nRF MCP, I can see the UART TX attribute changing! Just no serial output.)

After far too much debugging, it appears that there is some confusion about handles, and which characteristic is thought to be firing the ble event:

  • When operating cleanly, the value_handles for RX==11 and TX==14. When ble_evt_dispatch comes in upon data ready to be written to the UART, the evt_write->handle is 14, which is perfect.

  • When compiled with service_changed enabled, though, the value_handles assigned are RX==14 and TX==17. (I assume this is likely explained by the hidden characteristics automatically added for service_changed events.) However, when ble_evt_dispatch comes in upon data ready to be written to the UART, the evt_write->handle is 14 - which is of course wrong. It should be 17. Where the heck it got 14 is a mystery.

I've looked at the source code all the way down to the softdevice encoder, and I can't find the source of the issue; it looks as though handle values are assigned within the softdevice or elsewhere that I can't determine.

Chances are that this issue is most likely mine, but I don't see it. Guidance? Thanks

  • (Oh, and yes, in case it matters, I bumped DM_GATT_CCCD_COUNT to 10 just to see if I was overflowing something. It didn't make any difference.)

  • are you bonded? has the client cached all the handles?

  • The problem was mine. Indeed it was a bonding issue. All I did was to clear the bonding info on the other device, and it worked again. If I understand properly this is an issue because when I changed to using service_changed, it switched the handle mappings and thus the other device's cached mappings were no longer valid. Thanks for pointing me in the right direction.

  • Yes - when the initial bond was made to a service with no service changed characteristic that makes an explicit promise that the service will never change (as long as the device continues to identify as the same device). So the client is allowed to cache handles forever. Once you've added the service changed characteristic and started over with a new bond, then you can update the service changed characteristic (which has to stay in the same place) to tell the client to re-read them.

    Having seen the logs of how some clients seem to deal with the service changed characteristic (OSX I'm looking at you here), I wonder how well-used it really is and whether it always works.

Related