Android 14 Enforcing MTU Size 517 Causes OTA Issues with BLE 5.0 Device Firmware

Hello,

I am encountering an issue with my Android OTA app after upgrading to Android 14. The OS seems to enforce the MTU size to 517 by default, but my device firmware (Bluetooth LE version 5.0) does not support this value. As a result, the OTA update fails when running on Android 14. The same OTA process works perfectly on Android 13 and lower, where the MTU size is negotiated properly between the device and the phone.

In addition, I have noticed the same issue when using the nRF Connect app on Android 14.

Here are a few details about the issue:

  • Device firmware BLE version: 5.0.
  • Device firmware MTU support: My device supports a lower MTU size than 517.
  • Issue: Android 14 forces the MTU value to 517, causing communication issues with the device during the OTA process.
  • Behavior: The OTA update fails when the device tries to handle packets larger than its supported MTU size.
  • Expected behavior: The MTU should be negotiated between the phone and the device, similar to the behavior in Android 13 and lower versions.

Has anyone else faced this issue or found a workaround to control or negotiate the MTU size on Android 14? Any suggestions on how to handle this problem would be greatly appreciated!


Logs of nrf connects

nRF Connect, 2024-10-10

Fan Dimmer (84:FC:E6:0C:03:3A)

V 11:38:08.447 Connecting to 84:FC:E6:0C:03:3A...

D 11:38:08.447 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)

D 11:38:08.793 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2)

I 11:38:08.793 Connected to 84:FC:E6:0C:03:3A

V 11:38:08.815 Discovering services...

D 11:38:08.815 gatt.discoverServices()

D 11:38:08.872 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED

I 11:38:09.259 Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)

D 11:38:09.440 [Callback] Services discovered with status: 0

I 11:38:09.440 Services discovered

V 11:38:09.445 Generic Attribute (0x1801)

- Service Changed [I] (0x2A05)

   Client Characteristic Configuration (0x2902)

Generic Access (0x1800)

- Device Name [R] (0x2A00)

- Appearance [R] (0x2A01)

- Central Address Resolution [R] (0x2AA6)

Unknown Service (0000abf0-0000-1000-8000-00805f9b34fb)

- Unknown Characteristic [R WNR] (0000abf1-0000-1000-8000-00805f9b34fb)

- Unknown Characteristic [N R] (0000abf2-0000-1000-8000-00805f9b34fb)

   Client Characteristic Configuration (0x2902)

- Unknown Characteristic [R WNR] (0000abf3-0000-1000-8000-00805f9b34fb)

- Unknown Characteristic [N R] (0000abf4-0000-1000-8000-00805f9b34fb)

   Client Characteristic Configuration (0x2902)

D 11:38:09.445 gatt.setCharacteristicNotification(00002a05-0000-1000-8000-00805f9b34fb, true)

D 11:38:09.448 gatt.setCharacteristicNotification(0000abf2-0000-1000-8000-00805f9b34fb, true)

D 11:38:09.451 gatt.setCharacteristicNotification(0000abf4-0000-1000-8000-00805f9b34fb, true)

I 11:38:09.562 Connection parameters updated (interval: 45.0ms, latency: 0, timeout: 5000ms)

V 11:38:28.676 Requesting new MTU...

D 11:38:28.676 gatt.requestMtu(460)

W 11:38:28.774 Requested MTU not supported. MTU changed to: 517

Parents
  • Hi Noman, 
    It's quite strange that the ATTMTU cause the FOTA process to break. I agree that the MTU Exchange should be the negotiation between the phone and the device where they select the max that each side can support. 
    Could you show the log after the MTU update failed ? 


    Could you capture a sniffer trace in both case, Android 13 and Android 14. If you are not familiar with the sniffer please take a look here

  • This is the packet capture of MTU negotiation between our device and nrf connect running on android 14 device. Our device is running ble 5.0 and supports ble MTU negotiation. I set the MTU of 460bytes (not 517) from the nrf connect app but as seen in packet capture it requested an MTU of 517 bytes. This happens only on android 14.

  • Hi Noman, 
    Please send the whole sniffer trace. 
    It's quite often that the app can't control what the system would do regarding BLE configuration. 
    But you should have full control on the nRF52 side. If you don't allow above 460 bytes in the MTU ATT then the result of the negotiation will match with what you set to the MTU. 

  • Hi Hung, here is the complete picture. Our device is based on esp32c3 module from espressif, running bluedroid ble stack. I am using nrf android BLE library in my app and using nrf connect app to debug this issue. I have created 3 scenarios with different android versions:

    1. Nrf connect app on android version <=13
      Any value within 23-517 for MTU can be set from the app without any issues. Wireshark capture file and screenshot are attached.

      Wireshark capture:
      MTU_negotiation_android_8.pcapng
    2. Nrf connect app on android version 14
      Unable to set desired MTU value. When MTU of 460B is set from nrf connect app, it somehow requests 517B instead of 460, can be seen in the screenshot below:
      MTU_negotiation_android_14
      Wireshark capture:
      MTU_negotiation_android_14.pcapng
    3. Nrf connect app on android 14 and MTU 300 set on device
      Interestingly, when i explicitly set an MTU of 300B through a function call in my device firmware, it sets the MTU of 300 against any value(larger or smaller) requested from the nrf app.

      When MTU of 460B is requested from app:


      When MTU of 256B is requested from the app:

      Wireshark capture:
      MTU_negotiation_android_14_mtu_300_set_on_device_mtu_256_set_from_app.pcapng
Reply
  • Hi Hung, here is the complete picture. Our device is based on esp32c3 module from espressif, running bluedroid ble stack. I am using nrf android BLE library in my app and using nrf connect app to debug this issue. I have created 3 scenarios with different android versions:

    1. Nrf connect app on android version <=13
      Any value within 23-517 for MTU can be set from the app without any issues. Wireshark capture file and screenshot are attached.

      Wireshark capture:
      MTU_negotiation_android_8.pcapng
    2. Nrf connect app on android version 14
      Unable to set desired MTU value. When MTU of 460B is set from nrf connect app, it somehow requests 517B instead of 460, can be seen in the screenshot below:
      MTU_negotiation_android_14
      Wireshark capture:
      MTU_negotiation_android_14.pcapng
    3. Nrf connect app on android 14 and MTU 300 set on device
      Interestingly, when i explicitly set an MTU of 300B through a function call in my device firmware, it sets the MTU of 300 against any value(larger or smaller) requested from the nrf app.

      When MTU of 460B is requested from app:


      When MTU of 256B is requested from the app:

      Wireshark capture:
      MTU_negotiation_android_14_mtu_300_set_on_device_mtu_256_set_from_app.pcapng
Children
Related