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?

Parents
  • Hi Brian, 

    We have two examples in the SDK : ble_app_gatts_c and ble_app_gatts. Have you tried to test them ? 

    They are not exactly the same as you wanted (server on peripheral and client on central) however, you can use them as the referral. 

    Basically, on the server, you need to enable service changed, and send the indication. This is already handled by gatt_cache_manager.c and you just need to call pm_local_database_has_changed() to send the indication. ( it's inside bsp_event_handler() in ble_app_gatts)

    On the client, you need to do service discovery and write to the CCCD to enable indication. This is already handled by nrf_ble_gatts.c and the ble_db_discovery.c modules. Please have a look in gatts_evt_handler in main.c in ble_app_gatts_c. 

  • Thanks for the response. I understand that a client can support services; its just in practice (out in the field) I have never seen it ... except perhaps for a CTS.

    In any case, I am using the pc-ble-driver so I must use sd_* calls myself. Even so, it looks like it should be easy. Basically, as far as I can tell the GATT service is already set up and the service changed characteristic exists. Now I have an Android application that will attempt to enable indications on the service changed characteristic if it finds one. It works fine for peripheral devices out in the field.

    I also have no sd_* APIs in the pc-ble-driver that allow me to get the handle of the GATT services, characteristics, or descriptors. Looked for answers on that, too. I did see some post which suggests the handle is 0x0B but that may even be another platform, so I don't know if that is even right. Found no documentation on it though.

    So that's where I am at. What config step am I missing? Where can I find documentation on how to do this?

    UPDATE: It appears the handle I am using 0x0B for the Service Changed characteristic is wrong.

    The sd_ble_gatts_service_changed() method returns the error incorrect handle. But I cannot get the handle.

  • Hi Brian, 

    I'm sorry for the bad user experience. You can click on the Reply button right under the question. 

    The service_changed_send_in_evt() you can find in gatt_cache_manager.c. The file is used in the ble_app_gatts. 
    From what you described, it seems to be correct to me. Not sure why the function still complaining. 

    But I strongly suggest to try testing the ble_app_gatts and ble_app_gatts_c and then compare to the behavior of your application. Try comparing the difference in the code on the working examples with yours. I think you are pretty close. 

  • UI experience: The problem is the reply button doesnt' EXIST! I have to go through loops an hoops to get it to appear (refreshes and reloads). When it finally appears, all is rosy.

    That aside, I do not have the tools to build the HEX files needed to test the example in the NRF SDK. The other problem is that I could not find the file you referenced in the SDK (at least in my copy). So I can't even look at it. I found something similar in another file and that is why I did the 'loop' over ever-increasing handles.

    That 'loop-guess' part still stinks even if it DID work; not knowing what the handle of the service changed characteristic is, providing no means to get it, yet requiring it in the call to invoke the service changed indication.

    Clearly there needs to be an sd_* call that gets the handle needed in the sd_ call that invokes the service changed. Doesn't that make sense? Otherwise DONT demand the handle and have the soft device find it. It clearly knows it!

    In the end the problem is that softdevice thinks it doesn't have the system attributes. What that error means is still unclear to me because a get clearly shows they are there!

    If it was TRULY the case that Android had not enabled indications I would expect the error

    NRF_ERROR_INVALID_STATE 

    not 

    BLE_ERROR_GATTS_SYS_ATTR_MISSING

    At least that's what the documentation says.

  • Hi,

    Hung is out-of-office and I am having a look at this while he is away.

    The file gatt_cache_manager.c is found in the SDK at <sdk root folder>/components/ble/peer_manager/gatt_cache_manager.c

    Regards,
    Terje

  • this is the pc-ble-driver.

    Following those examples does not solve the problem

  • Hi,

    As pc-ble-driver is serialization of the same SoftDevice that is used by the nRF5 SDK, all code from the nRF5 SDK using the SoftDevice can be used for referencing how to use the SoftDevice API.

    Regards,
    Terje

Reply Children
No Data
Related