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

Queued write response fails

iOS is using queued writes to send data to my nRF52832 application. For some reason, on the third queued write reply (in nrf_ble_qwr.c) sd_ble_gatts_rw_authorize_reply returns NRF_ERROR_INVALID_STATE.

I modified nrf_ble_qwr.c to log every time it calls sd_ble_gatts_rw_authorize_reply anywhere. I am sure that my code is not calling it, as I also log everywhere I call it too. The log output looks like this:

<debug> nrf_sdh_ble: BLE event: 0x1.
<debug> nrf_sdh_ble: BLE event: 0x51.
<info> app: prepare reply
<debug> nrf_sdh_ble: BLE event: 0x51.
<info> app: prepare reply
<debug> nrf_sdh_ble: BLE event: 0x51.
<info> app: prepare reply
<error> KFPAL: ERROR 8 [NRF_ERROR_INVALID_STATE] at ...KFPAL_Nordic_bluetooth.c:446
PC at: 0x000268F1
<error> KFPAL: End of error report

this occurs in the sd_ble_gatts_rw_authorize_reply call in on_prepare_write in nrf_ble_qwr.c. Unless sd_ble_gatts_rw_authorize_reply is being called by another nrf library, it is only being called from nrf_ble_qwr.c. I'm really struggling to understand why INVALID_STATE is being returned.

  • Hi Nick, 


    I think I might find the root cause. In our queued write example we set the MEM_BUFF_SIZE to 512. This is the user memory provided to the softdevice to receive the queued writes (I assume you also use stack handled queued write, not app handled).

    It's not the same as the rcvd_data[NRF_BLE_QWRS_MAX_RCV_SIZE]; which is handled by the qwrs module. 

    If it's the case please try to test increase the User mem buffer to for example 1024.

    In my test here if I leave the MEM_BUFF_SIZE =512  (thus m_buffer size array of 512 bytes) I got INVALID_STATE after 400+ bytes transmitted (there are lots of overhead in queued writes) it fixed after I increase the user mem. 

    Please note that, queued write usually used when you want to update multiple characteristics at once. If you want to do a normal write, you can simply use normal write (with or without authorization). 

  • Ok thanks. So for receiving 512 bytes of data via queued write, what should MEM_BUFF_SIZE be? iOS uses queued writes for large data size, so I don't really have control over it. Thanks

  • It depends on the overhead of queued writes you have. There are 5 bytes of overhead per Prepare Write Request:

    So you need to know roughly the size of the data you going to receive. And the ATT MTU size to calculate the number of Prepare Write Request. 

    Again, the queued write is designed so that you can write multiple characteristic at the same time. If you plan to write only one characteristic, or if you don't have the requirement of updating multiple of them at the same time, you can just use normal write. 

Related