Repository navigation
Conversation
3 of 6 tasks
A request was always split into 200 byte packets. When the connection negotiated a smaller MTU, each packet became a long write, which the device can reject with ATT error 0x0e. Size the packets to a single write at the MTU of each connection instead, read from the characteristic's max_write_without_response_size, and keep 200 bytes when the characteristic is not resolved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bleak reports the 20 bytes of the minimum MTU when BlueZ does not publish the MTU. Besides BlueZ before 5.62, that is the case for a bonded device whose GATT objects are cached from an earlier connection, since BlueZ only signals the MTU on the connection that created them. Every bonded unit on a local adapter then got 20 byte packets regardless of the real MTU. Treat 20 bytes as unknown and keep the 200 byte packets that worked so far. Only a published MTU above the minimum shrinks the packets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nailik
force-pushed
the
fix/mtu-sized-packets
branch
from
October 17, 2026 21:26
7f5cc40 to
8f26300
Compare
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
Requests were always split into 200 byte packets. When a connection negotiates a smaller ATT MTU, each of those packets is sent as a long write, which the device can reject with ATT error 0x0E (
UNLIKELY_ERROR). This sizes packets to fit a single write at each connection's negotiated MTU._packet_size(client)readsmax_write_without_response_sizeof the Blanco characteristic, capped at the 200 byte protocol target. For a write with response that is the same limit (ATT MTU − 3). On BlueZ bleak takes it from theMTUproperty BlueZ publishes (5.62+); on an ESPHome proxy from the MTU the proxy reports. No private bleak API is used.validate_pinwithout a protocol (config flow, random-MAC scan) does the same.MIN_WRITE_SIZE). Besides BlueZ before 5.62, that is the case for every bonded device whose GATT objects BlueZ cached on an earlier connection: BlueZ only signals the MTU on the connection that created them (att_exchangeinsrc/gatt-client.c), and the reporter log in Fix BLE connection leaks and pair during setup #24 shows noMTUproperty at all. Shrinking to 20 bytes there would change the framing on setups that work today, without knowing the real MTU.manifest.json: version0.0.15-mtu-sized-packagesfor the test prerelease (valid SemVer for Home Assistant, sorts between 0.0.14 and 0.0.15).Behaviour change to verify
Packets only shrink when a connection publishes an MTU above the 23 byte minimum, for example an ESPHome proxy or a local adapter on a fresh (not cached) connection. A request then takes more, smaller writes. Each is a plain write, and the busy-write retry from #25 covers them on BlueZ. Where the MTU is unknown, the 200 byte long writes from before stay. No log so far shows the device rejecting those with 0x0E, so this mainly matters once one does.
Test plan
pytest testson the rebased branch (HA 2026.6, Python 3.14): 391 passed, 68 snapshots passedvalidate_pinwrites MTU-sized packets, pairing sizes the session protocol0.0.15-mtu-sized-packagestested by reporters🤖 Generated with Claude Code