Omer Omer - 1 month ago 9
Android Question

BluetoothGatt: negotiating new MTU succeeds but new size cannot be used (3 bytes difference)

I'm working on an app that exchange data between devices using BLE.

In order to get better performance, after connecting two devices I'm negotiating to increase the MTU in order to exchange bigger data packages over BLE.

Once the BluetoothDevice is connected and all services and characteristics are read, I request to increase the MTU using:

private void requestMtu() {
//gatt is a BluetoothGatt instance and MAX_MTU is 512
this.gatt.requestMtu(MAX_MTU);
}


After that, on the
BluetoothGattCallback
implementation I get the MTU request succeeded and the new MTU matches the one I requested:

@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);

if (status == BluetoothGatt.GATT_SUCCESS) {
this.supportedMTU = mtu;
}
}


The problem is, when I try to send a data package of 512 bytes, on the other side (
onCharacteristicWriteRequest:
) I get 509 bytes.

Any ideas?

Answer Source

The MTU size represents maximum amount of bytes which can be utilized in an ATT payload. An ATT write request payload (which is being send for a characteristic write) looks like the following:

1 byte Attribute Opcode 2 byte Attribute Handle N Byte Attribute Value

Since the MTU size is 512 bytes, the maximum size N can be is 512 - 3 = 509 bytes