Skip to content

ble_hci: fill in the handle and error code of an ATT Error Response - #11145

Open
annejan wants to merge 1 commit into
adafruit:mainfrom
annejan:fix/att-error-response
Open

ble_hci: fill in the handle and error code of an ATT Error Response#11145
annejan wants to merge 1 commit into
adafruit:mainfrom
annejan:fix/att-error-response

Conversation

@annejan

@annejan annejan commented Jul 29, 2026

Copy link
Copy Markdown

send_error() in the HCI _bleio ATT server takes a handle and an error code and then ignores both. The initialiser only sets the two opcodes:

} rsp = { {
              .code = BT_ATT_OP_ERROR_RSP,
          }, {
              .request = opcode,
          }};

So every ATT Error Response the device sends carries handle 0x0000 and error code 0x00.

0x00 is not a valid ATT error code, and a client may reasonably treat the response as malformed. BlueZ does. During service discovery it issues a Read By Type Request for Server Supported Features (0x2B3A); no attribute matches, so the server correctly wants to answer Attribute Not Found, but the malformed error goes out instead. BlueZ abandons the ATT bearer and completes discovery with an empty database.

The visible symptom is a peripheral that appears to have no services at all, even though its Read By Group Type Responses are byte-for-byte correct. ServicesResolved becomes true and UUIDs is empty.

How this was found

On an nRF52840 running the HCI _bleio host against an on-chip controller, by capturing the ATT exchange over SWD. The request and the reply we sent:

request:  08 01 00 FF FF 3A 2B      Read By Type, 0x0001-0xFFFF, type 0x2B3A
response: 01 08 00 00 00            Error Response, request 0x08, handle 0x0000, error 0x00

With the fields filled in, the same read is answered with Attribute Not Found, discovery proceeds, and a client sees every service and characteristic. Verified with bleak and bluetoothctl: service count goes from 0 to 3, and characteristic writes then work end to end.

send_error() takes a handle and an error code and then ignored both: the
initialiser only set the two opcodes, so every Error Response the device sent
carried handle 0x0000 and error code 0x00.

0x00 is not a valid ATT error code, and a client may treat such a response as
malformed. BlueZ does. During service discovery it reads Server Supported
Features (0x2B3A), no attribute matches, the malformed error comes back, and
it abandons the ATT bearer and finishes with an empty database. The peripheral
then appears to have no services at all, even though its Read By Group Type
Responses were correct.

Found on an nRF52840 talking to BlueZ, by reading the ATT exchange over SWD.
With the fields filled in, that read is answered with Attribute Not Found,
discovery proceeds, and the client sees every service and characteristic.
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