Skip to content

espressif: report GATT ATT errors as specific exceptions - #11550

Open
dhalbert wants to merge 2 commits into
adafruit:mainfrom
dhalbert:espressif-gatt-att-errors
Open

dhalbert wants to merge 2 commits into
adafruit:mainfrom
dhalbert:espressif-gatt-att-errors

Conversation

@dhalbert

Copy link
Copy Markdown
Collaborator

Code by Claude, reviewed by @dhalbert.

Problems

  • GATT client reads and writes reported ATT errors from the peer as "Unknown system firmware error: 261" and the like, instead of SecurityError or another specific exception.
  • check_nimble_error() called unknown NimBLE return codes "system firmware" errors.
  • Unknown error codes were printed in decimal, so they could not be looked up in NimBLE's documentation.

Changes

  • bleio_gattc_read() and bleio_gattc_write() pass ATT error statuses to check_ble_error(), which now maps the common ones:
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: 0x01xx (nordic's existing message)
  • Unknown errors from check_nimble_error() and check_ble_error() both print "Unknown BLE error: 0x%04x". NimBLE's return-code documentation lists codes in that form, e.g. 0x0213 for HCI error 0x13.

Testing

Metro ESP32-S3 as central, Feather nRF52840 on nordic 11.0.0-alpha.1 as peripheral:

Operation Result
Read a NO_ACCESS characteristic BluetoothError: read not permitted
Write a NO_ACCESS characteristic BluetoothError: write not permitted
Read an ENCRYPT_NO_MITM characteristic without pairing SecurityError: Insufficient authentication
Write 8 bytes to a 4-byte fixed_length characteristic ValueError: Invalid length
Ordinary read and write unchanged

0x08, 0x0C and other ATT errors could not be produced with a CircuitPython peripheral.

Not changed

  • connect() to an absent device usually returns a Connection that is not connected instead of raising. That will be a separate PR.

GATT client reads and writes reported ATT errors from the peer as
"Unknown system firmware error: 261" and the like. They now go through
`check_ble_error()`, which maps the common ones:

- 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: 0x01xx"

`check_nimble_error()` only sees NimBLE return codes, so its fallback now
says "Unknown BLE error" instead of "Unknown system firmware error". Both
fallbacks print the code as `0x%04x`, the form NimBLE's return-code
documentation uses (e.g. 0x0213 for HCI error 0x13).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dhalbert
dhalbert requested a review from mikeysklar October 12, 2026 00:43
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.

1 participant