MTU Size, 3 bytes are lost somehow

Hi,

I have used one of the sample and was playing around a write characteristic. I changed the MTU size to 65 bytes and then tried to send same data from the app to the board/firmware. 

The total number of bytes i received on the firmware is 62 (3 bytes less). I then tried same thing with default MTU.

On the serial output, I can the following line printed when the BLE connection is established:

Updated MTU: TX: 23 RX: 23 bytes

But the max data I can send it 20 bytes. If I try to send 23 bytes, again, the 3 bytes are lost. 

Same with 65 bytes:

Updated MTU: TX: 65 RX: 65 bytes

If I send 65 bytes, I only see 63 on the serial output.


My write handler on the firmware looks something like this. I have highlighted the len param. 

static ssize_t write_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset,
uint8_t flags)
I do not understand why cant I send the max number of bytes, same as the size of currently set MTU? 
Parents
  • Hello,

    The attribute protocol needs 3 bytes for the opcode (write command) and the attribute handle (which attribute to write to) to be able to write your payload. Thus, the max. payload size for your write command will always be ATT_MTU - 3.  You can read more about this in vol.3, part F, section 3.4.5 of the Blueooth core specification.

    Best regards,

    Vidar

  • Hi,

    Thanks for the detailed reply. It creates an issue for our apps if they need to do this adjustment after setting up the MTU size. This is something we would like to avoid as we already have some other chips/devices where this step is not required and it would mean change of logic in quite a few apps (that are in production). 

    Is there anyway I could adjust this in firmware/configs so it report backs to the app/central after deducting 3 bytes? For example, instead of reporting 65 bytes during MTU negotiation, can it say 62? It would reduce the code change on lots of our other apps. 

    Thanks! 

Reply
  • Hi,

    Thanks for the detailed reply. It creates an issue for our apps if they need to do this adjustment after setting up the MTU size. This is something we would like to avoid as we already have some other chips/devices where this step is not required and it would mean change of logic in quite a few apps (that are in production). 

    Is there anyway I could adjust this in firmware/configs so it report backs to the app/central after deducting 3 bytes? For example, instead of reporting 65 bytes during MTU negotiation, can it say 62? It would reduce the code change on lots of our other apps. 

    Thanks! 

Children
  • Hi,

    No problem, but I am not sure I understand how the MTU size affects your application logic and how it can be different on other (BLE?) devices. The MTU negotiation and sizes are all defined by the Bluetooth specification, and is not something that can be changed.

    Best regards,

    Vidar

  • Hi,


    It was an NXP chip, but like you said, it shouldn't really make any difference as the BLE protocol should act the same way. Unfortunately the firmware done for those devices was done by other team so I can't see exactly how they managed it there.

    But, when working with those devices, if we set MTU to, let's just say, 100 (from our mobile apps), we for sure can then send 100 bytes of our raw data, without having to compensate for the 3 bytes for opcode and we would like to avoid patching all production apps now when we add NRF52940/Zephyr in our stack. 

    I should dig up the docs as you suggested. 

    And again, thanks for taking time to answer here, really appreciate that.

  • Hi,

    You could use a BLE sniffer to view the MTU exchange on air and see what the MTU ends up being set to. If it is indeed 100 bytes and you are able to send 100 bytes of raw data, then the phone must be doing what's known a queued write/long write (vol.3, part F, section 3..4.6.1). This operation allows you to write an attribute value larger than ATT_MTU-3, but slower as it requires the write to be split across multiple ATT packets.

Related