Search code examples
androidbluetoothbluetooth-lowenergygattbluetooth-gatt

How to send BLE characteristic notification if value len > MTU size?


I have an Android GATT server with the following code:

// Data length = 24 bytes
void onNewData(GattServerDelegate gattServer, byte[] data) { // data = 24 bytes
    characteristic.setValue(data);

    // MTU = 23
    gattServer.notifyCharacteristicChanged(mNotifyDevice, characteristic, false);
}

Because the data is longer than the MTU size, the client only receives part of the message. Could I:

  • Request a new MTU from the server side? or,
  • Split the data in two packets?

Solution

  • The answer is yes to both questions, with a small detail.

    MTU can be requested only from a GATT client and not from a GATT server. A GATT server can only respond with its MTU when a MTU exchange is initated by the client.

    However, a device can have both the GATT server role and the GATT client role at the same time to the same device. The same MTU is used for both. So simply open a client connection and call https://developer.android.com/reference/android/bluetooth/BluetoothGatt#requestMtu(int). Or just make sure the remote device initiates MTU exchange before you send a notification.

    You can also split the data and send multiple notifications. When doing that, make sure you wait for this callback https://developer.android.com/reference/android/bluetooth/BluetoothGattServerCallback#onNotificationSent(android.bluetooth.BluetoothDevice,%20int) before sending the next notification.

    Also, note that maximum notification size is MTU - 3, since the ATT header must fit as well.