Search code examples
gattandroid-blemtu

Android 14 default MTU and related considerations


Has the default MTU changed to 517 bytes in Android 14? If so, this would warrant questions pertaining to hardware, the Bluetooth stack, MTU capabilities and proper usage of the function requestMtu().

~I now understand that the default MTU value (23) has not changed under Android 14. Thank you to all who provided feedback and trust that others will find utility in the commentary.


Solution

  • As you describe in your question, BluetoothGatt offers a requestMtu method since API 21. However, this is not possible in Android 14 and beyond:

    MTU is set to 517 for the first GATT client requesting an MTU

    Starting from Android 14, the Android Bluetooth stack more strictly adheres to Version 5.2 of the Bluetooth Core Specification and requests the BLE ATT MTU to 517 bytes when the first GATT client requests an MTU using the BluetoothGatt#requestMtu(int) API, and disregards all subsequent MTU requests on that ACL connection.

    The workarounds include changing your firmware:

    Your peripheral device should respond to the Android device's MTU request with a reasonable value that can be accommodated by the peripheral. The final negotiated value will be a minimum of the Android requested value and the remote provided value (i.e. min(517, remoteMtu))

    ...or manually sending appropriately-sized packets:

    • Alternatively, limit your GATT characteristic writes based on the minimum between the known supported value of your peripheral and the received MTU change
      • A reminder that you should reduce 5 bytes from the supported size for the headers
      • For example: arrayMaxLength = min(SUPPORTED_MTU, GATT_MAX_ATTR_LEN(517)) - 5