This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to use sd_ble_gatts_service_changed?

In our product we have both a DFU profile and an application profile which is confusing Mac OS X 10.9 "Mavericks" since it caches device services unless it receives a service changed indication.

The sd_ble_gatts_service_changed requires a start and end service handle, is there a way to determine what the max used service handle is? Passing 0xFF as max causes the routine to return an error.

Parents
  • Hi Pål,

    Thanks for the clear explanation! I tried this out, and it seems to work for some test cases. If we just try connecting to the device from an iPhone (with the free LightBlue app), sd_ble_gatts_service_changed() returns NRF_SUCCESS now that the code calls sd_ble_gatts_sys_attr_set()/get() correctly before that. However, the iPhone seemed to correctly clear its caches of services and characteristics anyway when re-connecting, so the service_changed() wasn’t really needed.

    The problem we’re running into is with OS X 10.9. (10.8 worked OK.) Our device can either be in a firmware update mode or in our normal “application” mode. These modes have different services and characteristics. We’re basically using the sample DFU code in the nRF SDK, so our DFU service UUID is 0x1530 (plus our vendor UUID prefix, of course). Our application service UUID is, say, 0xBEEF.

    Here’s the scenario that I’m trying to get working, and what’s going on right now:

    1. boot device into application mode, so the device has 0xBEEF service.
    2. OS X connects to device, then does some stuff with 0xBEEF.
    3. OS X disconnects from device.
    4. after disconnection, device calls sd_ble_gatts_sys_attr_get() and saves CCCDs out to persistent storage successfully.
    5. reboot device into firmware update mode, so device has 0x1530 service (and no 0xBEEF).
    6. OS X reconnects to device.
    7. device calls sd_ble_gatts_sys_attr_set() upon connection, which is successful.
    8. device calls sd_ble_gatts_service_changed(), which now returns NRF_ERROR_INVALID_STATE. 9. OS X still thinks device has 0xBEEF service.

    So the sd_ble_gatts_service_changed() call in step 8 fails. Presumably this is because the device saved a different set of CCCDs with sys_attr_get() than is now active, but that’s just a guess.

    Keep in mind that this is for a non-bonded connection. As you’ve hinted at, I believe that both iOS and OS X have different service/characteristic caching behaviour for bonded devices, so I’m tempted to just add characteristic authorisation to the device to force iOS/OS X to bond. I’m puzzled since the non-bonded behaviour should be the simpler one to get working.

    It’s entirely possible that perhaps we’re doing the right thing for a non-bonded device and these are all bugs in the Core Bluetooth framework on iOS/OS X, but I feel like I’m missing something in the application code on our device.

    Any hints would be greatly appreciated. Your help so far has been invaluable already, thank you very much!

    Andre.

  • Hm, as you have said, the Mac might cache the data, and this is something it should not have done if it hasn't bonded. Because if it does not bond, then it should rediscover the peer database every time it connects.

    But what you have done looks correct, and the reason why step #8 fails is possibly because Mac isn't enabling service changed in your database. And this is probably a bit different behavior from the iOS behavior.

    I think this is something that you can report on the bluetooth-dev [at] lists.apple.com.

Reply
  • Hm, as you have said, the Mac might cache the data, and this is something it should not have done if it hasn't bonded. Because if it does not bond, then it should rediscover the peer database every time it connects.

    But what you have done looks correct, and the reason why step #8 fails is possibly because Mac isn't enabling service changed in your database. And this is probably a bit different behavior from the iOS behavior.

    I think this is something that you can report on the bluetooth-dev [at] lists.apple.com.

Children
No Data
Related