Skip to content

zephyr-cp: Improve BLE error reporting: raise GATT ATT errors as specific exceptions - #11556

Open
dhalbert wants to merge 1 commit into
adafruit:mainfrom
dhalbert:zephyr-gatt-att-errors
Open

dhalbert wants to merge 1 commit into
adafruit:mainfrom
dhalbert:zephyr-gatt-att-errors

Conversation

@dhalbert

Copy link
Copy Markdown
Collaborator

Diagnosis and code by Claude, reviewed by @dhalbert.

Error reporting

ATT error Exception
0x02 Read Not Permitted BluetoothError: read not permitted
0x03 Write Not Permitted BluetoothError: write not permitted
0x05 Insufficient Authentication SecurityError: Insufficient authentication
0x08 Insufficient Authorization SecurityError: Insufficient authorization
0x0C Insufficient Encryption Key Size, 0x0F Insufficient Encryption SecurityError: Insufficient encryption
0x0D Invalid Attribute Value Length ValueError: Invalid length
any other BluetoothError: Unknown gatt error: 0x00xx
  • Also, Zephyr reports a disconnect during the request, and other local failures, as BT_ATT_ERR_UNLIKELY (0x0E). So check_gattc_status() checks the connection first and raises ConnectionError if it dropped.
    • Each request holds a reference on the bt_conn until that check, so it is safe after a disconnect.

Testing

nRF54LM20 DK with this PR as central, Feather nRF52840 on nordic with #11553 as peripheral:

Test Result
read/write NO_ACCESS, unpaired read of ENCRYPT_NO_MITM, over-length write to fixed_length read not permitted, write not permitted, Insufficient authentication, Invalid length
Ordinary read and write unchanged
Disconnect during a read/write loop, then reconnect and disconnect again ConnectionError, then no problems
ble_uart_echo_client.py from the BLE library examples echoes received, no errors
pytest tests/bsim -k nrf5340 61 passed

GATT client reads and writes passed ATT error codes from the peer to
`raise_zephyr_error()`, which expects a negative errno, so they came out as
`OSError` with a negative number. They now go through a new
`check_gattc_status()`, which maps the same ATT errors as espressif and
nordic:

- 0x02, 0x03: `BluetoothError("read not permitted")` / `"write not permitted"`
- 0x05: `SecurityError("Insufficient authentication")`
- 0x08: `SecurityError("Insufficient authorization")`
- 0x0C, 0x0F: `SecurityError("Insufficient encryption")`
- 0x0D: `ValueError("Invalid length")`
- other ATT errors: "Unknown gatt error: 0x00xx"

Zephyr reports a disconnect during the request, and other local failures,
as `BT_ATT_ERR_UNLIKELY`. So the connection state is checked first, and a
dropped connection raises `ConnectionError`. Each request holds a reference
on the `bt_conn` so the check is safe after a disconnect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dhalbert
dhalbert requested a review from mikeysklar October 12, 2026 00:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants