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

Allocating memory for queued writes

Hi

I am trying to implement long writes on the gatt server side. My implementation is stack handled, so I am going for the "GATTS Queued Writes: Stack handled, one or more attributes require authorization" sequence. So far everything has been working fine, whenever I get BLE_EVT_USER_MEM_REQUEST I reply with a large memory block, and long writes from the client side has worked without an issue.

My query is regarding memory optimisation, as I would like to only allocate enough memory for a write to one attribute in the gatt server. In other words, for an attribute of length 20 bytes, I'll need to allocate only 20+X bytes of memory for a queued write to be successful. Our app supports variable length attributes, so the amount of memory given to sd_ble_user_mem_reply() will vary. So my question is, how do I calculate how much memory is needed to perform a long write on one attribute?

We're using softdevice S132 v3.0.0 on nRF52.

Thanks

Parents
  • Hi Youssif,

    As you can see in the sequence chart you quoted, we receive BLE_EVT_USER_MEM_REQUEST before the peer finished with its write request. Meaning we don't know how many bytes will be written when we receive the event. Our suggestion is to use the maximum size of the characteristic when you declare it.

    Note that if you have more than one characteristic, you may need to allocate enough memory for all of them, but it's should be avoildable from the master side (don't write to more than one characteristic at the same time ).

  • Hi Youssif,

    Sorry I forgot about the overhead. Yes there are header need to be counted. So it would be possible to send only 18 bytes payload when it comes to queued write (2 bytes for HandleID, 2 byte for offset, 2 byte for length). In this page you will find how the user memory should be parsed.

    The table is for one single packet, if you have more than one packet for the queued write, the next packet will come right after. In short if you need to send 20 bytes, the first packet requires 2 (handle) + 2 (offset) + 2 (length) + 18 (payload) = 24 bytes. The next one require 6 (headers as first packet) + 2 (2 bytes payload left) = 8.

    In total it's 32 bytes. But as you already figured out we need 34. This is because the last command "Execute write request" needs 2 bytes (one opcode one value). So you need to count 2 extra byte in.

    In shot, minimum the size of the buffer is 6xnumber of packet + payload size + 2.

    There is an exception for the case that only one packet needed, I found the buffer size need to be more than 21 bytes.

Reply
  • Hi Youssif,

    Sorry I forgot about the overhead. Yes there are header need to be counted. So it would be possible to send only 18 bytes payload when it comes to queued write (2 bytes for HandleID, 2 byte for offset, 2 byte for length). In this page you will find how the user memory should be parsed.

    The table is for one single packet, if you have more than one packet for the queued write, the next packet will come right after. In short if you need to send 20 bytes, the first packet requires 2 (handle) + 2 (offset) + 2 (length) + 18 (payload) = 24 bytes. The next one require 6 (headers as first packet) + 2 (2 bytes payload left) = 8.

    In total it's 32 bytes. But as you already figured out we need 34. This is because the last command "Execute write request" needs 2 bytes (one opcode one value). So you need to count 2 extra byte in.

    In shot, minimum the size of the buffer is 6xnumber of packet + payload size + 2.

    There is an exception for the case that only one packet needed, I found the buffer size need to be more than 21 bytes.

Children
No Data
Related