Cap GATT write chunks at 512 bytes to fix crash on Android 13+#227
Open
obook wants to merge 1 commit into
Open
Cap GATT write chunks at 512 bytes to fix crash on Android 13+#227obook wants to merge 1 commit into
obook wants to merge 1 commit into
Conversation
…d 13+ The default MTU-based splitter chunks writes at MTU - 3 bytes. When the system negotiates the maximum MTU of 517 (e.g. on a Pixel 8), chunks reach 514 bytes, which BluetoothGatt.writeCharacteristic rejects since Android 13 (max attribute length is 512), throwing IllegalArgumentException and crashing the app a few seconds after connecting to the watch. Use a custom DataSplitter capped at 512 bytes regardless of the negotiated MTU.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On recent Android versions the app stays open for a few seconds and then closes
when connecting to the watch. This pull request fixes that crash. It was
reproduced on a Pixel 8 (Android 14/15) and matches the reports in #217 and
#203.
Root cause
AsteroidBleManager.send()writes characteristics with the default.split()splitter (added in #195), which chunks data at
MTU - 3bytes. When the systemnegotiates the maximum MTU of 517, as the Pixel 8 does, each chunk is 514 bytes.
Since Android 13,
BluetoothGatt.writeCharacteristic()rejects any value longerthan 512 bytes (the maximum GATT attribute length) and throws
IllegalArgumentException, so the app crashes on the first notification whosepayload exceeds 512 bytes, a few seconds after connecting to the watch.
The existing
requestMtu(256)call does not help, because the connection hasalready negotiated an MTU of 517 by the time it runs:
Fix
Use a custom
DataSplitterthat caps each chunk at 512 bytes regardless of thenegotiated MTU. The watch reassembles the message from the chunks, so a smaller
chunk size only changes the number of writes, not the result.
Testing
Built and installed on a Pixel 8 (Android 14/15). The app no longer closes after
a few seconds, and notifications reach the watch, including ones larger than 512
bytes that previously triggered the crash.
Fixes #217.
Thanks for AsteroidOS and for maintaining this app. Best regards from France.