BLE service not showing on connection

Posted on
  • I'm trying to create and advertise a BLE service that I can read and write binary data to, but I can't seem to get the service to actually present itself to a connected device, it does advertise however...

    This is the code I've been trying to get working without any success...

    var test = "No data";
    NRF.setServices({
      "78290001-d52e-473f-a9f4-f03da7c67dd1": {
        "78290002-d52e-473f-a9f4-f03da7c67dd1": {
          value : [0, 0, 0, 0, 0, 0, 0, 0,],
          maxLen: 8,
          readable : true,
          writable : true,
          notify: true,
          indicate: true,
          onWrite : function(evt) {
            test = evt;
          }
        }
      }
    }, { uart : false, advertise: ["78290002-d52e-473f-a9f4-f03da7c67dd1"] });
    
    setWatch(function() {
      NRF.setServices({ }, { uart : true });
    }, BTN, { repeat: false, edge:"rising", debounce:50 });
    

    My end goal is to have a service that I can write to and then respond back to the device writing the data, I think I could do this by updating the value in the onWrite callback?

    I've been testing with the NRC Connect app and I have the newest firmware on the puck

  • What you're doing there looks spot on.

    Are you using an iPhone out of interest? iPhones 'cache' the services on a device as they're not expecting them to change - so the services may well have changes, just your phone isn't reporting them.

    Could you try turning Bluetooth off and then on again on your phone, then try again?

  • I tried the script on my Bangle:

    • uploaded the script to the Bangle using WebIDE
    • disconnected the Bangle from the WebIDE
    • Using NrfConnect on iPhone reveals the Bangle, connected to it, and it shows the advertised services. Writing to 78290002..... works OK.
    • To make sure I disconnected the Bangle from NrfConnect, and reconnected. The data I had written was displayed as I sent it. I GUESS this means that the data is written to the Bangle succesfully.

    Maybe this helps?

  • BTW I had to reboot the Bangle when I wanted to reconnect it to WebIDE. Without rebooting is did not show up in the WebBluetooth devices of the WebIde.

    And I mad sure it was not still connected to NrfConnect :-)

  • Without rebooting is did not show up in the WebBluetooth devices of the WebIde

    Yeah, it's because the UART was turned off with NRF.setServices - so there was no way for the IDE to communicate

  • Are you using an iPhone out of interest? iPhones 'cache' the services on a device as they're not expecting them to change - so the services may well have changes, just your phone isn't reporting them.

    There is actually 'Service Changed' characteristics that should be used for that and indicate changes. Some details e.g. in this issue https://github.com/espressif/esp-idf/issues/1777

    Don't have any Espruino around now but I guess this is not used now?
    Described also here https://devzone.nordicsemi.com/f/nordic-q-a/19073/nordic_hrm-generic-attribute-service-change-0x2a05-0x2902-add
    Don't see that line ble_enable_params.gatts_enable_params.service_changed = 1;
    somewhere before https://github.com/espruino/Espruino/blob/master/targets/nrf5x/bluetooth.c#L2246

    Also discussed here https://punchthrough.com/attribute-caching-in-ble-advantages-and-pitfalls/

  • There is actually 'Service Changed' characteristics that should be used for that and indicate changes.

    I know, but as far as I know it's no use.

    The Service Changed characteristic is designed to enable a GATT server to change its structure during a BLE connection while maintaining synchronicity with the client.

    Basically in order to remove a service, you have to reboot the softdevice, which means being disconnected. And if you're disconnected, nothing is going to be listening to get the notification that the service changed :(

    About the only thing I can think is to have the flag, then if something has changed wait until the connection has initialised and then set service changed?

  • You were right, my phone was caching the services, I turned off bluetooth and back on again and it showed up as expected...

  • Basically in order to remove a service, you have to reboot the softdevice, which means being disconnected. And if you're disconnected, nothing is going to be listening to get the notification that the service changed :(

    Interesting. I've seen this 'service changed' characteristics working in the buttonless DFU as done in SDK11 - on F07/F10/DK08 watches. Stock firmware has some services including buttonless DFU, then when you click DFU button and start uploading zip in nrfconnect it reboots into bootloader after sending init packet, then upload continues and then after update it reboots back and it still uses same mac address. However I am not sure if services are removed during this. I was thinking yes (since you cannot use the fitness stuff or read battery while in bootloader and updating the firmware) but now I am not sure. Softdevice is not restarted when entering bootloader and possibly even connection is kept open if I understand it correctly. When switching back the connection is closed and SD is restarted. And it seem to work as expected when updating between different versions of original firmware. And true that when I flash espruino via this buttonless DFU I do have issues connecting to espruino nordic uart. Will check in more details. I just know this characterisitics is there and also saw some code related to that in SDK11 bootloader - method static uint32_t service_change_indicate() in SDK11/components/libraries/bootloader_dfu/dfu_transport_ble.c. It calls sd_ble_gatts_service_changed(m_conn_handle, DFU_SERVICE_HANDLE, BLE_HANDLE_MAX).

    About the only thing I can think is to have the flag, then if something has changed wait until the connection has initialised and then set service changed?

    Well, yes, that could be solution. Always add this characteristics and signal change on every connection. Either always or when change is detected. Or add method for it so that people could trigger the change after connection themselves(?). But the initial state after waking BT on startup the characteristics should be there so that device would not cache the state without having it (?).

    The practical caching experience with IOS and Android is described in that last link I posted. They mention iOS even does not cache if the 'service changed' is there (?).

  • @DanTheMan827 I'm glad you got this sorted out, I meant to ping you that I got it working with this code though I'm sure it's a bit of a mess... :)

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

BLE service not showing on connection

Posted by Avatar for DanTheMan827 @DanTheMan827

Actions