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

debugging sd_ble_gatts_hvx

Hi

I am trying to get to the bottom of a problem I am having with sending a buffer of data on connection and indication enable. Here's what I do: I have a process running, which is capturing sensor data every 10 seconds, and keeping it in a circular buffer. When a master connects, I want to send the circular buffer to the master app. I am doing that by triggering on the event that the CCCD is written to enable indications (I am using indication because I want to make sure that the values end up in the app). When this CCCD write is happening, I send the first item in my circular buffer, and then use the BLE_GATTS_EVT_HVC event to see if I have gotten a confirmation, just as in the health thermometer example.

I am running into a number of problems

  • when I trigger on the CCCD write and immediately do a sd_ble_gatts_hvx, I get an error 8 (illegal state); if I start a timer and do the same after 10 ms, then it is ok
  • I sometimes also have a BLE_ERROR_GATTS_SYS_ATTR_MISSING error, how can I avoid that? when should I normally do a sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0) (i do not use bonding)

I have the impression that timing issues or race conditions are causing my problems, can anyone give me hint on how to solve this?

  • This all sounds like you are triggering your call to sd_ble_gatts_hvx() too early in some cases. Are you 100% sure that you're calling it when a write to the specific CCCD is written? you might have multiple CCCDs and the peer might be writing to another one. Another possible issue is a race condition between your call to sys_attr_set(NULL) and the writing of the CCCD. if you write too late you might overwrite the value written by the peer, so I recommend you call sys_attr_set() directly in your handling of BLE_GAP_EVT_CONNECTED

  • I am using MCP, so I do all the steps manually. And I first connect, and then discover services on MCP, and then do the write on the appropriate CCCD. My sys_attr_set is on connection. I will try to remove it from the error handler for the BLE_GATTS_EVT_SYS_ATTR_MISSING event.

  • So maybe I describe in short again what I got: I changed my code such that on a BLE_GAP_EVT_CONNECTED event I do a sd_ble_gatts_sys_attr_set.

    When I then wait on a write with value 2 to the CCCD of the characteristic I want to send indications from to the master. In the event handler of that write event, I immediately do a first sd_ble_gatts_hvx, hoping that I will get a BLE_GATTS_EVT_HVC when that indication was finished, such that on that event I can do a next sd_ble_gatts_hvx call, and so on, until my sample buffer I want to transmit is empty. However, when doing the first sd_ble_gatts_hvx I get a return value of NRF_ERROR_INVALID_STATE, and I never receive the confirmation of my indication. What can be the cause of the invalidi state? So I am connected, and the CCCD is written with the right value. Please help...

  • I think you should pull the HVC events before attempting to send new indications, but your problem here occurs at the first hvx, so it is not this that stops you. Could you please add a print/breakpoint when you're about to send an HVI and print out a) the handle that was written to, and b) the handle you are about to indicate? I still have a feeling that you are trying to indicate the wrong characteristic.

Related