This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2652RB: Increasing GATT_MAX_NUM_PREPARE_WRITES

Part Number: CC2652RB
Other Parts Discussed in Thread: CC2541

There's a define in gatt.h:

#define GATT_MAX_NUM_PREPARE_WRITES      5 //!< GATT Maximum number of attributes that Attribute Server can prepare for writing per Attribute Client

From what I can tell, this comment is misleading at best, as this seems to limit the number of packets that can be prepared, even for a single attribute.

We have a writable characteristic in our peripheral device that is 258 bytes long, and we were having trouble writing the entire thing.  Our central is an Android/iOS phone, and we have to be able to support a wide range of models, so we can't necessarily guarantee that we will have access to Bluetooth 4.2 DLE features.  So with a variable MTU that can be as low as 23, Write Requests and Write Commands aren't going to cut it, as they do not provide a means of including an offset in the header of any layer.  The file would have to be chopped up at the application level and offsets generated at runtime in the mobile app based on the MTU available at the time on each individual device.

So instead we've been using Prepare/Execute Write.  I'm aware they come with their own inefficiencies, but I'm not sure there's a better way to send a large chunk of data without putting the burden of figuring out how to partition it on the central device.  The problem is that we were only able to send 90 bytes without increasing the MTU.  With the default 4.0 MTU of 23, we lose 1 byte to the Prepare Write opcode, 2 bytes to the attribute handle, and another 2 bytes to the offset, leaving 18 bytes for data.  90 bytes is exactly 5 packets, leading me to believe my statement above concerning GATT_MAX_NUM_PREPARE_WRITES.

Assuming that is indeed the limiting factor, what are the repercussions of changing this value?  I was not able to find hardly anything in the way of documentation concerning this setting.  That is the only place it appears in the code, so it's not clear what it does.  Does it mean a larger buffer would be needed somewhere to hold more packets?  Would I need to increase the task stack size?  Is there a limit to how high this should be set?  For the case of a phone with the default 4.0 MTU, we'd need 15 packets to be able to write a 258-byte characteristic.  But if we raise the MTU in our device to 251 (based on MAX_PDU_SIZE, which maxes out at 255 for some reason, even though the Bluetooth spec allows an MTU up to 512. Side question: why does TI limit this?), then 15 packets' worth of Prepare Write data would be 3690 bytes.  Hopefully that's not what the buffer would need to be; we care about accommodating the total characteristic size regardless of MTU, not some arbitrary number of packets.

I also found that define and comment existed exactly as they are today in TI's Bluetooth code from 6+ years ago when we used it in our previous product based on the CC2541, so it predates the Bluetooth 4.2 specification for Data Length Extensions.  Now that higher MTUs are possible, what are the consequences of changing GATT_MAX_NUM_PREPARE_WRITES, and how should we handle this?

  • Hi Chris,

    The only place this define is used is as the argument in gattServApp_SetNumPrepareWrites, it defines the size of the write queue. Let us get back to you on whether this is a packet queue.

  • Hi Chris, 

    I will look into this and get back to you next week. 

    Thanks, 
    Elin

  • Hi Chris, 

    Thanks for your patience. 

    I have submitted a ticket to R&D for them to look into and clarify the comment for GATT_MAX_NUM_PREPARE_WRITES.

    Thanks, 
    Elin

  • Great, but could someone clarify it for me in the meantime?  How is this resolved?  My end goal here isn't just to make sure TI's documentation is complete; it's to be able to finish a project for our customer so we can buy a bunch of these parts from you and go into manufacturing.  We can't afford to wait for an indefinite number of "next week"s.  I know the comment in the code is unclear; can someone answer the rest of the question?

  • I should have clarified.  "We can't afford to wait for an indefinite number of 'next week's" meant "we can't afford to wait weeks for answer," not "we can wait at least another month, just stop telling us every week that you're going to answer us next week."

  • Hi Chris,

    Apologies for the delay here. Hope you are well. 

    The maximum number of Prepare Writes (GATT_MAX_NUM_PREPARE_WRITES ) on the GATT Server is set to 5 by default. And, each Prepare Write Request can carry up to 18 bytes of attribute data.

    However, this max can be changed by setting GATT_MAX_NUM_PREPARE_WRITES to a higher value in the project.

    As Marie mentioned, it's utilized by gattServApp_SetNumPrepareWrites. This will allocate RAM for the prepare write queues per connection. This will cause your device to use more of the available heap at a rate of the number of prepare writes * the number of connections you support. 

    I do not see any other reason why more than 5 would be a limit in our stack and this should enable you to move forward with your design. 

    We can update our documentation to clarify this in the future, thank you for your feedback Chris. As always, it's greatly appreciated in helping us make a better product and make them easier to use. I will not click TI Thinks Resolved unless you approve of this response or have any follow up questions we can address.