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

Switch between applications (multiple services.h) - nRF8001

Hello,

I am working on a product, which uses the nRF8001 as basis for the Bluetooth communication. The application offers two interfaces, a custom interface and a HID interface. There are two generated services.h, one for each application.

The plan was, that the device is able to switch between these service definitions via a hard reset and a new setup phase. Dynamic bonding data gets stored separately for both applications. This is working in general but I was running into a problem because it seems, that the device holds a unique Bluetooth Address which an Android device uses as identifier. (If I think about it, it is not a surprise.) So, if I reset the bond device the Android device will not show a second independent Bluetooth device ready to bond; It will just replace the name and stay in a unknown state.

Does someone have a few ideas how I could solve my problem or is their at least a more specific documentation about the dynamic data so that I know how to extract the bonding information. (So I somehow can, at least, keep this information between both application modes.)

Would the nRF8001/nRF51822 be able to change this Bluetooth Address? Unfortunately the hardware is already locked, but I would be interested if the nRF51822 would be able to do that.

Thanks, bledev.

  • I see a few issues in your implementation.

    1. Changing between Services needs to take care of the cache in the phone for the apps. See info for Android below.
    2. In addition you should also send the Service Changed Indication from your firmware.
    • See the Service Changed Characteristic in your nRFgo Studio settings , in GAP-> Advanced GATT Settings -> Add Service Changed Characteristic

    Send the Service Changed Indicaton with the data as "0xuuuu – Start of Affected Attribute Handle Range, 0xuuuu – End of Affected Attribute Handle Range", or use the entire handle range as the affected handle range i.e. (0x0001 to 0xFFFF) , remember that this has to be sent with little end first.

    I would actually recommend that you merge the Services so that you do not need to do this swapping of Services, do you have a reason to do this, since the custom GATT Characteristic can actually be mapped to a HID over GATT Report. It is possible for the custom Service and the HID over GATT to co-exist and point to the identical Characteristic.

    Android has a few things you need to do to get the change of Services correctly. /*

    • We would like to avoid using the hack with refreshing the device (refresh method is not in the public API). The refresh method clears the cached services and causes a
    • service discovery afterwards (when connected). Android, however, does it itself when receive the Service Changed indication when bonded.
    • In case of unpaired device we may either refresh the services manually (using the hack), or include the Service Changed characteristic.
    • According to Bluetooth Core 4.0 (and 4.1) specification:
    • [Vol. 3, Part G, 2.5.2 - Attribute Caching]
    • Note: Clients without a trusted relationship must perform service discovery on each connection if the server supports the Services Changed characteristic.
    • However, as up to Android 5 the system does NOT respect this requirement and servers are cached for every device, even if Service Changed is enabled -> Android BUG?
    • For bonded devices Android performs service re-discovery when SC indication is received. */

    refreshDeviceCache(gatt, !hasServiceChanged);

    // Close the device close(gatt);

    =

    You need to do the above to get the Service changed implementation correctly or merge the Services so there is a single Serivce.

  • Hello David,

    thanks for all the information. I will definitely take a look at the Service Changed Indication. The reason why it is split up, is the special behavior on Android for HID devices. If the HID device is known by the Android device, like a keyboard for example, the Android device automatically connects to the device after the bonding and uses it as a system input device. So I want the device to connect automatically in HID service mode and keep manual control for an application in custom service mode. I thought this might be only possible if I do this complete device restart and swapping. Do you know if Android will try to connect to an HID device after an Service Changed Indication? Respectively, does it disconnect if the Service Changed Indication removes the HID device services?

Related