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

Why don't I get a BLE_GATTS_EVT_SYS_ATTR_MISSING event?

This discussion got mixed up with a discussion about what Nordic means by a 'system attribute' (which is still not clear). In any case, in that discussion I was trying to save pairing/bonding information so I could restore it on a reconnect. The pairing keys worked. I grabbed the keys on the pairing complete event, saved them to a file, read them from that file, and gave them to the peer when asked on a reconnect in the BLE_GAP_EVT_SEC_INFO_REQUEST event.

But the CCCD information doesn't work that way. I can't restore the CCCD state using the same approach, because I cannot initialize the CCCD myself from the application (even prior to a connection). Instead I was told I need to get the 'system attributes' by calling this method sd_ble_gatts_sys_attr_get(), save them to a file, and restore them by calling this method sd_ble_gatts_sys_attr_set() when I get a BLE_GATTS_EVT_SYS_ATTR_MISSING event.

Fantastic! Sounds easy enough. However, I never get a BLE_GATTS_EVT_SYS_ATTR_MISSING event. I get this event BLE_GAP_EVT_SEC_INFO_REQUEST to restore the keys, so that works. What is missing?

Parents
  • Hi,

    You will get the BLE_GATTS_EVT_SYS_ATTR_MISSING event if the peer requests a read on any of the system attributes.

    In the case where you send indications or notifications before the peer requests such a read, for instance you want to perform a sd_ble_gatts_service_changed(), you need to do the sd_ble_gatts_sys_attr_set() first.

    In our SDK, this is done for instance inside service_changed_send_in_evt() in gatt_cache_manager.c (part of Peer Manager), where the function local_db_apply_in_evt() calls gscm_local_db_cache_apply() in gatts_cache_manager.c, which eventually calls sd_ble_gatts_sys_attr_set().

    Regards,
    Terje

  • There are two independent issues happening here. First, I am using the pc-ble-driver. I make direct sd_* calls. I acutally find that easier in most cases than trying to figure out what the SDK is doing and porting it to the pc-ble-driver.

    In any case

    • issue #1 has to do with restoring the state of the CCCDs that were set by the collector in a previous connection. I was told to use the sd_ble_gatts_sys_attr_set() function in the BLE_GATTS_EVT_SYS_ATTR_MISSING. I saved the state from a sd_ble_gatts_sys_attr_get() function in the previous connection, and then on a reconnection waited for the BLE_GATTS_EVT_SYS_ATTR_MISSING event to restore it. It never happened. So what I have done instead is to ignore those instructions and just restore it in the connection event.

    • issue #2 is trying to do a service changed indication on a reconnect. No matter what I do for prep, the sd_ble_gatts_service_changed() fails, and it always fails in the same way. From start handles 0-13 I get invalid handle, and for every handle value above that I get a BLE_ERROR_SYS_ATTRS_MISSING error. This happens regardless of the number of get and set calls I do prior to making the service changed attempt. I see from the table returned from the 'get' call that there is only one entry and that handle is 13.
  • Hi,

    Issue #1:
    The call to sd_ble_gatts_sys_attr_set() should normally be done on the BLE_GATTS_EVT_SYS_ATTR_MISSING event, which indicates that the attributes are needed, but it can be done at any time after connection so your solution there should be fine.

    Issue #2:
    Upon getting the BLE_ERROR_SYS_ATTRS_MISSING return code you should run sd_ble_gatts_sys_attr_set() first and then retry the operation.

    If you are still experiencing issues with this, can you provide the code for reproducing the behavior? Then I can have a look here at might be the issue.

    Regards,
    Terje

Reply
  • Hi,

    Issue #1:
    The call to sd_ble_gatts_sys_attr_set() should normally be done on the BLE_GATTS_EVT_SYS_ATTR_MISSING event, which indicates that the attributes are needed, but it can be done at any time after connection so your solution there should be fine.

    Issue #2:
    Upon getting the BLE_ERROR_SYS_ATTRS_MISSING return code you should run sd_ble_gatts_sys_attr_set() first and then retry the operation.

    If you are still experiencing issues with this, can you provide the code for reproducing the behavior? Then I can have a look here at might be the issue.

    Regards,
    Terje

Children
  • I certainly can provide the code. I will provide the entire VS project. Because I still am getting that error. How do I do that?

    I restore the saved CCCDs with a 'set' in the connection event. Then I try and invoke the service changed. I redo the get and set before that call and cycle through tries of the handle since I do not know what the handle is. It turns out to be '13' as I have only one entry in the CCCD table but there is no way to (generically) know what attribute that table belongs to. Since there is only one is has to be the service changed since there are no others.

    I do not use that approach because that will not work in all cases. A new API is clearly needed to get the the handle of the service-changed attribute or to get the UUID of the attribute referenced in the CCCD table. Neither exists yet the service changed API requires that handle.

  • Hi,

    Sorry for the delay, I thought you were going to provide the project, but now I realize you asked how to do so.

    If you do not want to attach it here in this public thread, you can create a private ticket, attach it there, and refer to this thread from the private ticket.

    Regards,
    Terje

  • I do not SEE a way to attach the project or anything else.

  • Hi,

    You can attach files to a reply here in this thread. From the "Insert" menu you can "Insert image/video/file", which lets you attach any type of file.

    You can also attach files to the opening post of a new thread, both for public and private threads.

    Regards,
    Terje

  • I was in Amsterdam last week at an HL7 FHIR Dev Days meeting and did not have access to this project. Sorry about the delay.

    I will try to attach the project.

    I have set up the code to do the following in 3 stages

    Stage 1:

    Starts advertising as a heart rate monitor; supports a DIS, and requires pairing before one can enable notifications on the measurement characteristic.

    Once connected, the usual spin-up. Pairing will happen when the client tries to enable notifications

    It sends a few measurements then disconnects

    Stage 2:

    Re-run the same setup.

    Start advertising again. 

    Once connected It sends the measurements (the client re-enables notifications but that is so because there are too many devices in the field which do not support bonding correctly).

    Disconnects.

    Stage 3

    Reconfigures the device to have no DIS and changes some of the fields in the HR characteristic

    Configures the device to invoke service changed on connection event.

    start advertising

    once connected, service changed  fails.

    HERE IS THE LOG of that sequence:

    Serial port used: COM5
    Baud rate used: 1000000
    Info: Successfully opened COM5. Baud rate: 1000000. Flow control: none. Parity: none.
    Status: 6, message: Target Reset performed
    Status: 7, message: Connection active
    Advertising data set
    Service initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Service initiated
    Characteristic initiated
    Characteristic initiated
    Started advertising at time 0
    Connected at time 641, connection handle 0x0001
    Result of sending encryption params 0
    Security settings reported at time 1282:
    security level: 2
    security mode: 1
    key length: 16
    Read write authorized request signaled
    Read authorized request at time 1422 for characteristic 2A23
    Read update reply response 0
    Read write authorized request signaled
    Read authorized request at time 1625 for characteristic 2A26
    Read update reply response 0
    Read write authorized request signaled
    Read authorized request at time 1813 for characteristic 2A28
    Read update reply response 0
    Read write authorized request signaled
    Read authorized request at time 2016 for characteristic 2A27
    Read update reply response 0
    Read write authorized request signaled
    Read authorized request at time 2203 for characteristic 2A29
    Read update reply response 0
    Read write authorized request signaled
    Read authorized request at time 2407 for characteristic 2A25
    Read update reply response 0
    Client Enabling CCCD of characeteristic handle 13 with value 2 at time 2500
    Read write authorized request signaled
    Read authorized request at time 2594 for characteristic 2A24
    Read update reply response 0
    Read write authorized request signaled
    Read authorized request at time 2688 for characteristic 2A2A
    Read update reply response 0
    Read write authorized request signaled
    Read authorized request at time 2797 for characteristic 2A2A
    Read update reply response 0
    Enabling CCCD with 1 at time 2891
    Send mesurement 40
    Successfully transmitted a heart rate reading.
    Send mesurement 43
    Successfully transmitted a heart rate reading.
    Send mesurement 46
    Successfully transmitted a heart rate reading.
    Send mesurement 49
    Successfully transmitted a heart rate reading.
    Disconnected at time 6985
    Info: serial port COM5 closed.
    Saving data to file at time 7922
    Closed at time 7938

    Serial port used: COM5
    Baud rate used: 1000000
    Info: Successfully opened COM5. Baud rate: 1000000. Flow control: none. Parity: none.
    Status: 6, message: Target Reset performed
    Status: 7, message: Connection active
    Advertising data set
    Service initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Characteristic initiated
    Service initiated
    Characteristic initiated
    Characteristic initiated
    Started advertising at time 0
    Connected at time 563, connection handle 0x0001
    Result of sending encryption params 0
    Security settings reported at time 1094:
    security level: 2
    security mode: 1
    key length: 16
    Enabling CCCD with 1 at time 1235
    Send mesurement 40
    Successfully transmitted a heart rate reading.
    Client Enabling CCCD of characeteristic handle 13 with value 2 at time 1875
    Send mesurement 43
    Successfully transmitted a heart rate reading.
    Send mesurement 46
    Successfully transmitted a heart rate reading.
    Send mesurement 49
    Successfully transmitted a heart rate reading.
    Disconnected at time 5328
    Info: serial port COM5 closed.
    Saving data to file at time 6282
    Closed at time 6282

    Serial port used: COM5
    Baud rate used: 1000000
    Info: Successfully opened COM5. Baud rate: 1000000. Flow control: none. Parity: none.
    Status: 6, message: Target Reset performed
    Status: 7, message: Connection active
    Advertising data set
    Service initiated
    Characteristic initiated
    Characteristic initiated
    Started advertising at time 0
    Connected at time 281, 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 984:
    security level: 2
    security mode: 1
    key length: 16
    Disconnected at time 1281
    Info: serial port COM5 closed.
    Saving data to file at time 1297
    Closed at time 1297

    Attached is the Visual Studio 2019 community edition project.

    Using nRF52840 dongle

    The client application is a production Android Personal Health Gateway used in the field for health devices (HDP, SPP, and BTLE)in remote patient monitoring scenarios (Health@Home PHG on Android Playstore - free). I may need to give you an APK that is preconfigured with a fake patient.. That is needed to run the application. You can configure it yourself but that can be confusing.

    If you have a client app that supports the above that should work as well. Looks like the attachment worked!


    BleHeartRateMonitor.zip

Related