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

I give up; how do I do a service changed?

The documentation is VERY difficult to search. A search only goes over the chapter. I get different results depending upon which one I am in .... aarrg! And there are SOOO many.

So I want to do something very basic; 

On my peripheral I want to expose the service changed characteristic. That appears to be done by default because I see it on my central. But now I try to enable indications from the central and it fails. Well of course it does! I need to handle the BLE_GATTS_EVT_WRITE event!

So I do and come across a MAJOR difficulty. I need to have the handle of the Service Changed Characteristic. But there is no way to get it; or at least I cannot find a way to get it.

So how can I get the handle of the service changed characteristic so I can deal with it in the BLE_GATTS_EVT_WRITE event?

  • The 'get' function gives me a value of 0xD.

    So I tried both 0 and the value provided by the table from the 'get()' method.. Both gave me the same error 0x3003

    'INVALID ATTRIBUTE HANDLE'

    There must be something more missing. For example, the restoration of the of the 'system attributes' from the previous connection. However that doesn't happen because I never get a 

    BLE_GATTS_EVT_SYS_ATTR_MISSING

    event. So maybe that's the problem.

  • Could you try follow our code in gscm_service_changed_ind_send () in gatts_cache_manager ? 


    do
        {
            err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle);
            if (err_code == BLE_ERROR_INVALID_ATTR_HANDLE)
            {
                start_handle += 1;
            }
        } while (err_code == BLE_ERROR_INVALID_ATTR_HANDLE);

    I'm not 100% sure why we need to do the "trial and error" method like this, may need to check with the developer. But you don't need to do this all the time, if you find the value you can hardcode it I believe. 

  • Then I better start from 0 and not what I get from the 'get' method. I am still suspicious that it has something to do with the fact I cannot restore the system attributes because I do not get signaled the ..._SYS_ATTR_MISSING event

    Since my \examples\connectivity\ble_connectivity does not have the code you reference above, I am kind of stuck with trial and error from zero ... if it even works. 

    I definitely will not hard code, as I am implementing a peripheral, running it, disconnecting, and then implementing another, one after the other. So far it all works except for the service changed and the BLE_GATTS_EVT_SYS_ATTR_MISSING event. However, my central always re-enables indications and notifications because of the misbehaving devices that do not do bonding correctly.

    Doing the 'cycle' starting with 0 I no longer get the invalid handle, instead I get 

    BLE_ERROR_GATTS_SYS_ATTR_MISSING

  • Have you enabled indication from the central side ? Please use nRFConnect to test first, before using Android. 

  • Yes I have (I did use Android and it works with other devices). If I knew the handle value of the service changed characteristic I should be able to catch it in my peripheral code ... unless Nordic doesn't pass that one up to the application (like it does other notification/indication attempts).

    I trapped all attempts by collector to enable characteristics and I see this 

    Client Enabling CCCD of characeteristic handle 13 with value 2 at time 1953

    However, on a reconnect when I attempt to do a service changed indication I get this:

    Started advertising at time 0
    Connected at time 234, connection handle 0x0001
    Failed invoking service changed indication. Invalid handle 0
    Failed invoking service changed indication. Invalid handle 1
    Failed invoking service changed indication. Invalid handle 2
    Failed invoking service changed indication. Invalid handle 3
    Failed invoking service changed indication. Invalid handle 4
    Failed invoking service changed indication. Invalid handle 5
    Failed invoking service changed indication. Invalid handle 6
    Failed invoking service changed indication. Invalid handle 7
    Failed invoking service changed indication. Invalid handle 8
    Failed invoking service changed indication. Invalid handle 9
    Failed invoking service changed indication. Invalid handle 10
    Failed invoking service changed indication. Invalid handle 11
    Failed invoking service changed indication. Invalid handle 12
    Failed invoking service changed indication. Invalid handle 13
    Failed invoking service changed indication. Service attributes missing
    Result of sending encryption params 0
    Security settings reported at time 843:
    security level: 2
    security mode: 1
    key length: 16
    Disconnected at time 1078

    Of course the Android central is going to fail now as it will try to write to handles based upon the old service tables as it never re-did service discovery to find out that there is no DIS anymore and the HeartRate service values have changed.

Related